KB
File Services

Samba File Server: Shares, Permissions and Access Control

7 min read1427 words27 code blocks

At a glance#

  • Purpose: Build and administer a standalone Samba file server providing Windows-compatible shared folders to Linux and Windows clients.
  • Applies to: Samba 4.x on RHEL-family and Ubuntu/Debian, in standalone (non-domain) mode.
  • Risk: Medium — misconfigured permissions can expose confidential data to everyone on the network.
  • Time: 1–2 hours for a first build; 15 minutes per additional share.

Overview#

Samba implements the SMB/CIFS protocol, letting Linux serve shared folders that Windows machines mount as network drives. This article covers standalone mode, where Samba keeps its own user database rather than joining a directory service.

The thing that catches people out is that two independent permission layers apply, and access is granted only where both agree:

text
Client → Share-level permissions (smb.conf) → Filesystem permissions (POSIX/ACL) → File

A share marked writeable in smb.conf still fails if the underlying directory is read-only to that user. Most "Samba permissions" tickets are actually filesystem permission problems.

Before you start#

  • Root or sudo access.
  • A decision on where share data will live — a dedicated filesystem or LVM volume is strongly preferred over /home or /.
  • A list of groups and who belongs to them.
  • TCP 445 reachable from clients.
Warning: Never expose Samba to the internet. SMB has a long history of serious vulnerabilities and is a primary ransomware propagation path. Restrict TCP 445 to internal networks at the firewall.

Installation#

bash
# RHEL / Rocky / AlmaLinux
sudo dnf install -y samba samba-client samba-common

# Ubuntu / Debian
sudo apt update && sudo apt install -y samba smbclient
bash
sudo systemctl enable --now smb nmb        # RHEL
sudo systemctl enable --now smbd nmbd      # Ubuntu

Preparing storage and groups#

1. Create the share directory#

bash
sudo mkdir -p /srv/shares/finance
sudo mkdir -p /srv/shares/public

2. Create groups that mirror access requirements#

bash
sudo groupadd finance
sudo groupadd staff

3. Set filesystem ownership and permissions#

This is the layer that actually enforces access:

bash
# finance: only the finance group, nothing for others
sudo chown root:finance /srv/shares/finance
sudo chmod 2770 /srv/shares/finance

# public: all staff can read and write
sudo chown root:staff /srv/shares/public
sudo chmod 2775 /srv/shares/public

The leading 2 sets setgid, so every file created inside inherits the directory's group. Without it, files belong to the creator's primary group and colleagues cannot open them — the single most common cause of "I can see the folder but not the file".

Full detail in Linux File Permissions, Ownership and ACLs.

Creating Samba users#

Samba keeps its own password database. A Linux account must exist first, then be added to Samba:

bash
# Linux account with no shell login - file access only
sudo useradd -M -s /sbin/nologin jsmith
sudo usermod -aG finance,staff jsmith

# add to the Samba password database
sudo smbpasswd -a jsmith
bash
# list Samba users
sudo pdbedit -L -v

# disable / enable
sudo smbpasswd -d jsmith
sudo smbpasswd -e jsmith

# remove
sudo smbpasswd -x jsmith
Note: -M -s /sbin/nologin creates an account that can access shares but cannot log into the server itself. File-server users should never get a shell.

Configuring shares#

bash
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak-$(date +%F)
sudo nano /etc/samba/smb.conf
ini
[global]
   workgroup = WORKGROUP
   server string = Samba File Server
   netbios name = FILESRV
   security = user
   map to guest = never

   # restrict to the internal network
   hosts allow = 192.168.10.0/24 127.0.0.1
   hosts deny = 0.0.0.0/0
   interfaces = lo eth0
   bind interfaces only = yes

   # require modern, encrypted SMB only
   server min protocol = SMB2_10
   client min protocol = SMB2_10
   smb encrypt = desired

   log file = /var/log/samba/log.%m
   max log size = 5000
   logging = file

[finance]
   comment = Finance department
   path = /srv/shares/finance
   browseable = no
   writable = yes
   valid users = @finance
   create mask = 0660
   directory mask = 2770
   force group = finance

[public]
   comment = Shared staff area
   path = /srv/shares/public
   browseable = yes
   writable = yes
   valid users = @staff
   create mask = 0664
   directory mask = 2775
   force group = staff

Key directives:

DirectivePurpose
valid users = @groupOnly members of that group may connect. @ denotes a group.
browseable = noHides the share from network browsing. It is still reachable by exact path — obscurity, not security.
create mask / directory maskMaximum permissions on newly created files and folders.
force groupFiles are created owned by this group regardless of the user's primary group.
map to guest = neverRefuses anonymous access outright.
server min protocol = SMB2_10Disables SMB1, which is obsolete and dangerous.
Warning: Never enable SMB1 (NT1). It is the protocol WannaCry spread over. If an old device "needs" SMB1, replace the device.

Applying and testing configuration#

Always validate before restarting:

bash
sudo testparm

testparm reports syntax errors and prints the effective configuration with defaults filled in.

bash
sudo systemctl restart smb nmb        # RHEL
sudo systemctl restart smbd nmbd      # Ubuntu

Firewall and SELinux#

bash
# firewalld
sudo firewall-cmd --permanent --add-service=samba
sudo firewall-cmd --reload

# ufw - restrict to the LAN
sudo ufw allow from 192.168.10.0/24 to any port 445 proto tcp

On RHEL-family systems SELinux blocks Samba from serving arbitrary paths until the context is set:

bash
sudo setsebool -P samba_export_all_rw on
sudo semanage fcontext -a -t samba_share_t "/srv/shares(/.*)?"
sudo restorecon -Rv /srv/shares
Note: If a share is visible but every file access is denied on RHEL, check SELinux before anything else. sudo ausearch -m avc -ts recent will show the denials.

Connecting from clients#

Windows — File Explorer address bar:

text
\\192.168.10.50\finance

Map as a drive: This PC → Map network drive, tick Connect using different credentials.

Linux — one-off mount:

bash
sudo mkdir -p /mnt/finance
sudo mount -t cifs //192.168.10.50/finance /mnt/finance \
  -o username=jsmith,uid=$(id -u),gid=$(id -g),vers=3.0

Persistent mount with credentials kept out of fstab:

bash
sudo nano /etc/samba/credentials-finance
text
username=jsmith
password=REPLACE_ME
bash
sudo chmod 600 /etc/samba/credentials-finance
text
# /etc/fstab
//192.168.10.50/finance  /mnt/finance  cifs  credentials=/etc/samba/credentials-finance,uid=1000,gid=1000,vers=3.0,_netdev,nofail  0  0
bash
sudo mount -a
Warning: nofail matters. Without it, a server that cannot reach the file share will hang during boot waiting for the mount.

Verification#

bash
# config valid
sudo testparm -s

# services running
sudo systemctl status smb nmb

# listening on 445
sudo ss -tulpn | grep 445

# list shares as a user - the real test
smbclient -L //localhost -U jsmith

# connect and write
smbclient //localhost/finance -U jsmith

Inside smbclient, confirm both directions work:

text
smb: \> ls
smb: \> put /etc/hostname test.txt
smb: \> del test.txt
smb: \> quit

Then verify access control actually holds by testing with a user who should not have access:

bash
smbclient //localhost/finance -U someoneelse

That must fail. A share that everyone can reach is worse than no share.

Finally, confirm the setgid inheritance works:

bash
sudo -u jsmith touch /srv/shares/finance/inherit-test
ls -l /srv/shares/finance/inherit-test    # group should be 'finance'
sudo rm /srv/shares/finance/inherit-test

Rollback#

bash
sudo cp /etc/samba/smb.conf.bak-YYYY-MM-DD /etc/samba/smb.conf
sudo testparm
sudo systemctl restart smb nmb

If a permission change broke access, filesystem permissions can be reset with:

bash
sudo chown -R root:finance /srv/shares/finance
sudo find /srv/shares/finance -type d -exec chmod 2770 {} \;
sudo find /srv/shares/finance -type f -exec chmod 660 {} \;

Troubleshooting#

SymptomCause and fix
NT_STATUS_LOGON_FAILURESamba password not set. Run sudo smbpasswd -a user. A Linux password is not enough.
NT_STATUS_ACCESS_DENIED on a share the user should reachFilesystem permissions, not Samba. Test with sudo -u user ls /srv/shares/x.
Share visible, all files denied (RHEL)SELinux context missing. Run the semanage/restorecon steps.
Files created but colleagues cannot open themsetgid missing on the directory. chmod 2770.
NT_STATUS_BAD_NETWORK_NAMEShare name typo, or the path does not exist.
Windows will not connect at allClient has SMB1 disabled and the server offers only SMB1, or vice versa. Confirm server min protocol.
Windows caches old credentialscmdkey /list, then cmdkey /delete:192.168.10.50.
Cannot see the server when browsing the networkNormal on modern Windows — browsing is unreliable. Use the full \\ip\share path.
Very slow transfersCheck smb encrypt overhead, duplex mismatch, and disk I/O on the server.
Boot hangs after adding an fstab entryMissing _netdev,nofail. Add both.