- Linux
- Samba
Setting up a File Server using Samba
I wanted to migrate my existing Windows File Server to an open alternative, and being Samba the industry standard I decided to give it a go.
In this article I will share what I learnt in the process, but first…
Get your gears right
The system I used is a Fedora 41, you should be able to use any current RHEL derivative and chances are things will work very similarly.
The filesystem I used to host the directories shared by Samba is EXT4 for which no special mount option or configuration is needed; check the Samba documentation if you use a different filesystem.
The version of the software packages I used are:
– samba: 4.21.4-1
– winbind: 4.21.4-1
– realmd: 0.17.1-13
– krb5-workstation: 1.21.3-4
All of this software is the current version at the time of writing (early 2025); when a configuration option is not specified it means I accept the default of this version; if you use older software the default can differ substantially and you may encounter issues or create security vulnerabilities.
The first steps of Samba
Samba is a complex software; instead of going full “ClickOps” it is beneficial to understand how the underlying infrastructure works.
Winbind
Unless you want to delight yourself with endless hours of troubleshooting, to use Samba you must join the system to Active Directory by using Winbind (which is part of the Samba suite). Again, you could theoretically do away with it and just have Samba use the system keytab if you only want to use Kerberos to access SMB shares, but because of SMB little skeletons in the closet (NTLM, NETBIOS,…) you are better of by taking the road most often taken.
If your organization policy states that systems must be joined via SSSD because you don’t want to allow NTLM in your network, you can still use Winbind and disable NTLM support.
Winbind provides different services:
– Name resolution for the Name Service Switch library for the following capabilities:
+ passwd
+ group
– Backend authentication services for the pam_winbind PAM library; both the NSS and PAM capabilities work against local (to Winbind itself) and Active Directory objects (users and groups).
– ID Mapping:
Windows and SMB use SIDs to unequivocally determine the identity of a group or a user, whereas UNIX uses UID and GID numbers. To maintain a mapping between SIDs and UIDs/GIDs, Winbind can use different techniques.
I recommend using the tdb
backend for local identities (that’s Winbind default) and rid
for Active Directory; for these reasons:
+ You must use tdb
(Trivial DataBase, that’s the format winbind
uses for storing data in different files) for local identities; unless you use local security groups you don’t have to backup that database.
+ The rid
idmap backend does generate deterministic mapping of SIDs to UIDs and GIDs. A RID is the last part of a SID and cannot be assigned to two different objects in the same AD domain. The only thing you should be careful about is not to overlap with any existing UID/GID pool used on the system and don’t overlap them for different domains.
In this way, you don’t have to backup anything except for the configuration of Samba and the filesystem with the shares to restore a working system.
Samba
Samba is implemented as a single user-mode process that listens on port 445/tcp (SMB) and 139/tcp (NETBIOS Session Service, basically SMB over NETBIOS over TCP; another skeleton in the closet of SMB).
Whenever a new user initiates a connection to the smbd
daemon, Samba forks itself and the new instance runs as the user identity. This has implications for accessing the filesystem hosting the shares.

The glue that keeps it together (spoiler: there’s a lot of it)
Samba emulates the permission model of a foreign filesystem onto the UNIX filesystem model. Certain things that SMB expects to be there are completely missing (for better or worse) or have different implementations.
Things like:
+ Permission inheritance (that does not exist on a UNIX system)
+ NTFS ACLs (well, ACLs do exists but they are not the same!)
+ File Locking (does not exist)
+ DOS Attributes
Permissions
In a UNIX system there is no concept of permission inheritance; in the classic model every file and directory gets created with default permissions depending on the creating user umask
, the creating user then becomes the owner and it’s primary group the file/directory group owner.
In Windows every file and folder inherits it’s permission from the parent folder. Also, there’s the concept of “blocking inheritance”, so you can set a different set of permissions on an object and it’s descendants that’s unrelated to the permission of it’s ancestor.
There are provisions in Samba to emulate all these behaviors (many parts of the following text are direct quotes from smb.conf man
page):
– map acl inherit = yes (defaults to no)
This parameter controls whether smbd
will attempt to map the ‘protected’ (don’t inherit) flags of the
Windows ACLs into an extended attribute called user.SAMBA_PAI (POSIX draft ACL Inheritance). This parameter requires support for extended attributes on the filesystem and allows the Windows ACL editor to store (non-)inheritance information while NT ACLs are mapped best-effort to the POSIX draft ACLs that the OS and filesystem implements.
We can actually see this through the command getfattrib:

It takes a little imagination as it’s encoded but if you look at the first two paths the attribute value is the same; on the third one is different, and that’s because that one has it’s inheritance blocked at Windows side.

– inherit permissions = yes (defaults to no)
New directories inherit the mode of the parent directory, including bits such as setgid.
New files inherit their read/write bits from the parent directory. Their execute bits continue to be determined by map archive, map hidden and map system as usual.
This one refers to how the permissions for new files and directories are determined on the UNIX side. We are basically telling Samba to create them on the local filesystem as Windows would (this last sentence is a poetic license, but you get the idea).
Don’t pay attention to the execute bits part because these are going to be stored in extended filesystem attributes, not as execute bits!.
– inherit owner = windows and unix (defaults to no)
The ownership of new files and directories is normally governed by effective uid of the connected user. This option allows the Samba administrator to specify that the ownership for new files and directories should be controlled by the ownership of the parent directory.
windows and unix = The Windows (SID) owner and the UNIX (uid) owner of new files and directories are set to the respective owner of the parent directory.
This is what you usually want on a Windows file share, and it’s what happens by default on a Windows box.
– acl group control = yes (defaults to no)
In a POSIX filesystem, only the owner of a file or directory and the superuser can modify the permissions and ACLs on a file. If this parameter is set, then Samba overrides this restriction, and also allows the primary group owner of a file or directory to modify the permissions and ACLs on that file.
On a Windows server, groups may be the owner of a file or directory – thus allowing anyone in that group to modify the permissions on it. This allows the delegation of security controls on a point in the filesystem to the group owner of a directory and anything below it also owned by that group. This means there are multiple people with permissions to
modify ACLs on a file or directory, easing manageability.
This parameter allows Samba to also permit delegation of the control over a point in the exported directory hierarchy in much the same way as Windows. This allows all members of a UNIX group to control the permissions on a file or directory they have group ownership on.
This parameter is best used with the inherit owner option and also on a share containing directories with the UNIX setgid bit set on them, which causes new files and directories created within it to inherit the group ownership from the containing directory.
This parameter was deprecated in Samba 3.0.23, but re-activated in Samba 3.0.31 and above, as it now only controls permission changes if the user is in the owning primary group.
NTFS ACLs
– vfs objects = acl_xattr
Samba has provisions for modules called Virtual File Systems; they are overlays on top of your real filesystem that alter how Samba exported shares behave.
The vfs_acl_xattr
VFS module stores NTFS Access Control Lists (ACLs) in Extended Attributes (EAs). This enables the full mapping of Windows ACLs on Samba servers even if the ACL implementation of the underlying filesystem is not capable of doing so.
The attribute is visible via standard tools in it’s encoded form and by using samba-tools
we can decode it:

This is how permissions are enforced on the Windows side:

File Locking
File locks are tracked in various tdb
databases:

DOS Attributes
– store dos attributes = yes (defaults to yes)
If this parameter is set Samba attempts to first read DOS attributes (SYSTEM, HIDDEN, ARCHIVE or READ-ONLY) from a filesystem extended attribute, before mapping DOS attributes to UNIX permission bits (such as occurs with map hidden and map readonly). When set, DOS attributes will be stored onto an extended attribute in the UNIX filesystem, associated with the file or directory. When this parameter is set it will override the parameters map hidden, map system, map archive and map readonly and they will behave as if they were set to off. This parameter writes the DOS attributes as a string into the extended attribute named “user.DOSATTRIB”.
This attribute from Samba 3.5.0 will also store the create time for a file.
Here it is, visible in it’s encoded form:

Joining the system to Active Directory
Now that we have an understanding of what’s involved in making a Samba share, let’s get to it:
Install the required software:
The following packages are needed to have a working system:
realmd oddjob oddjob-mkhomedir samba-winbind-clients samba-winbind samba-common-tools samba-winbind-krb5-locator krb5-workstation
Optional packages, but useful for troubleshooting:
samba-tools tdb-tools
Join the machine to the AD DS domain by using Winbind:
I prefer to edit the realmd.conf
file beforehand so that the servers all go to a specific Organization Unit and also have valid OperatingSystem and OperatingSystemVersion attributes. I use Ansible and Jinja2 templates to achieve that, but you do you.
realm join --membership-software=samba --client-software=winbind
Modify the system Kerberos library configuration:
This is needed so you can use Kerberos to local application as the system Kerberos library without this Samba-specific library can’t correctly map AD identities to Kerberos tickets otherwise.
Add the following to the /etc/krb5.conf
file:
[plugins]
localauth = {
module = winbind:/usr/lib64/samba/krb5/winbind_krb5_localauth.so
enable_only = winbind
}
Modify the Winbind PAM module configuration:
It’s entirely up to you, but please note that the system Kerberos library will search for a ticket cache in sssd-kcm
whereas realmd
configures the pam_winbind
module to store the ticket cache in a file.
The result is that upon logon, you don’t have a ticket cache available. I felt that this is a minor misconfiguration of realmd
and opened a bug into Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2354031. Let’s see where it goes.
Edit the /etc/security/pam_winbind.conf
file::
krb5_ccache_type = KCM
Now your system should be joined to the AD DS domain successfully.
You can now make your site local customization (like adding sudoers, trusted CAs, and so on..).
Note: if you try to query the NSS for group membership (eg: getent group CORP\\Domain\ Admins
) you’ll see no members. It’s expected. In a recent version of Winbind group enumeration was turned off because it’s an expensive and unreliable operation. You can manually turn it on again by modifying it’s configuration:
winbind enum groups = yes
winbind enum users = yes
winbind expand groups = number_of_nested_groups
Configuring Samba
Now that we have discussed the workings of Samba, the configuration it’s quite easy: just merge these lines into /etc/samba/smb.conf
.
It will configure Samba with sensible security defaults and create a share that everyone can read by only one can write.
valid users
and write list
directives are unrelated to SMB/NTFS permissions of the share, it’s just a paranoid check. Adjust at will.
vfs objects = acl_xattr
map acl inherit = yes
store dos attributes = yes
disable netbios = yes
kerberos encryption types = strong
server signing = mandatory
inherit owner = windows and unix
inherit permissions = yes
acl group control = yes
[software]
comment = Software Repository
path = /data/shares/software
read only = no
guest ok = no
valid users = +"NT AUTHORITY\Authenticated Users"
write list = +"CORP\Domain Admins", +"CORP\luca.cavana"
You then prepare the filesystem location to host the share:
A few notes:
– The setgid on the the group owner is needed so acl group control
can work on all the way deep.
– Be a man and use SELinux.
sudo mkdir -p /data/shares/software
sudo chown -R root:"CORP\\Domain Admins" /data/shares/software
sudo chmod -R u=rwx,g=rwxs,o=--- /data/shares/software
sudo semanage fcontext -a -t samba_share_t "/data(/.*)?"
sudo restorecon -R -v /data
Lastly, you fix the permissions from the Windows side.
Adjust at will.


In the images here you can see the POSIX ACL that is written to the filesystem as a result of manipulating permissions on Windows.