Skip to content

Your first gated share

This tutorial teaches the core trick the whole hospital layer is built on: gating an SMB share by Active Directory group membership. You will add a brand-new group, give it a share, add one user, and watch a non-member get denied. It assumes you have already done Stand up the lab.

A gated share is enforced at two layers, and both have to pass:

  1. The connection gate is the valid users = @AD\<Group> line in smb.conf. It decides who can even mount the share.
  2. The write gate is Unix ownership on the backing folder: the directory is owned by the group’s winbind GID at mode 2770 with the setgid bit, so only group members can write, and new files inherit the group.

When both agree, a member connects and writes; everyone else is stopped, most of them at the connection gate with NT_STATUS_ACCESS_DENIED.

Open a shell on the DC and create a Radiology-Techs group with one member:

Terminal window
make shell
samba-tool group add Radiology-Techs
samba-tool group addmembers Radiology-Techs gabriel.lawrence

Create the on-disk folder under the shares root and hand it to the group:

Terminal window
install -d /srv/shares/rad-techs
gid=$(getent group "AD\\Radiology-Techs" | cut -d: -f3)
chgrp "$gid" /srv/shares/rad-techs
chmod 2770 /srv/shares/rad-techs # setgid + group rwx, no "other"

The 2770 mode is the write gate: the leading 2 is setgid (new files inherit the folder’s group), 770 gives the owner and group full access and everyone else nothing.

Append the share definition to smb.conf and reload:

Terminal window
cat >> /etc/samba/smb.conf <<'EOF'
[rad-techs]
comment = Radiology techs scratch
path = /srv/shares/rad-techs
valid users = @AD\Radiology-Techs
read only = No
create mask = 0660
directory mask = 2770
EOF
smbcontrol all reload-config

The valid users = @AD\Radiology-Techs line is the connection gate.

Still inside the DC, try the share as the member and as a non-member:

Terminal window
# gabriel.lawrence IS in the group: expect a successful put
smbclient //localhost/rad-techs -U 'AD\gabriel.lawrence%Welcome@2026' \
-c 'put /etc/hostname proof.txt; ls'
# john.carter is NOT in the group: expect tree connect denied
smbclient //localhost/rad-techs -U 'AD\john.carter%Welcome@2026' \
-c 'ls'

The member’s put succeeds; the non-member is rejected with tree connect failed: NT_STATUS_ACCESS_DENIED. gate proven

Terminal window
exit

You built, by hand, exactly what make groups and make clinics automate at scale. The hospital’s 19 clinic shares, the all-staff share, and the clinicians-only phi share are all this same pattern, plus group nesting to build meta-groups like Clinicians. That nesting is what lets one membership edge act as the HIPAA boundary, explained in HIPAA nesting.

To do this the repeatable way instead of by hand, see Build the clinics and the editable tables in scripts/setup-clinics.sh.