Samba 4 AD on ZFS


This Wiki page covers installing and configuring Samba 4 as an Active Directory server on a ZFS system. It was developed based on FreeBSD 11 (amd64) installed mid July 2017.

This install was an upgrade of an older FreeBSD system running Samba 3.6 using the 'classicupgrade' script using BIND for DNS and the Samba 4.5 port.

The example domain is '' - change to match your network.


The following is still not done


   1 cd /usr/ports/net/samba45
   2 sudo make install
   3 # Select BIND911 during the samba45 config phase
   4 # Select GSSAPI_HEIMDAL during the bind911 config phase


Enable NFSv4 ACLs in your ZFS volume

   1 sudo zfs set aclmode=passthrough zroot
   2 sudo zfs set aclinherit=passthrough zroot

Setup UFS system volume

Samba's upgrade script is not smart enough (yet) to enable zfsacl automatically so it's simpler to have a POSIX ACL enabled UFS file system as sysvol.

   1 sudo zfs create -V 2G zroot/samba4sysvol
   2 sudo newfs /dev/zvol/zroot/samba4sysvol
   4 # Add to /etc/fstab
   5 sudo sh -c 'cat >>/etc/fstab' <<EOF
   6 /dev/zvol/zroot/samba4sysvol /var/db/samba4/sysvol ufs       rw,acls 0       2
   7 EOF
   9 sudo mkdir -p /var/db/samba4/sysvol
  10 sudo mount /var/db/samba4/sysvol

Copy old data

   1 sudo -i
   2 mkdir -p /usr/local/samba.PDC/dbdir
   3 cd /usr/local/samba.PDC
   4 scp root@oldserver:/usr/local/etc/smb.conf smb.PDC.conf
   5 scp root@oldserver:/usr/local/etc/samba/smbpasswd dbdir
   6 scp root@oldserver:/usr/local/etc/samba/secrets.tdb dbdir/
   7 scp root@oldserver:/usr/local/etc/samba/schannel_store.tdb dbdir/
   8 scp root@oldserver:/usr/local/etc/samba/passdb.tdb dbdir/
   9 scp root@oldserver:/var/spool/samba/locks/gencache_notrans.tdb dbdir/
  10 scp root@oldserver:/var/spool/samba/locks/group_mapping.tdb dbdir/
  11 scp root@oldserver:/var/spool/samba/locks/account_policy.tdb dbdir/

Run upgrade script

This was done iteratively - I ran the upgrade script and removed entries from the old smbpasswd file that it objected to.

   1 vi dbdir/smbpasswd
   2 # Remove all cruft (old entries, conflicts, etc that the upgrade script complains about)
   3 sudo samba-tool domain classicupgrade --dbdir=/usr/local/samba.PDC/dbdir/ --dns-backend=BIND9_DLZ /usr/local/samba.PDC/smb.PDC.conf

Configure BIND

Generate an RNDC key by running..

rndc-confgen -a -k rndc-key -c tmp

Note the contents of "tmp" and combine with /usr/local/etc/named.conf as below..

options {
        // All file and path names are relative to the chroot directory,
        // if any, and should be fully qualified.
        directory       "/usr/local/etc/namedb/working";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";

// These zones are already covered by the empty zones listed below.
// If you remove the related empty zones below, comment these lines out.
        disable-empty-zone "";
        disable-empty-zone "";
        disable-empty-zone "";

        forwarders {

        empty-zones-enable yes;
        disable-empty-zone "";
        disable-empty-zone "";

        tkey-gssapi-keytab "/var/db/samba4/private/dns.keytab";

zone "." {
        type slave;
        file "/usr/local/etc/namedb/slave/named.root";
        masters {
      ;           //
                2620:0:2d0:202::132;    //
      ;           //
                2620:0:2830:202::132;   //
        notify no;

// IPv4 ARPA
zone "arpa" {
        type slave;
        file "/usr/local/etc/namedb/slave/arpa.root";
        masters {
      ;           //
                2620:0:2d0:202::132;    //
      ;           //
                2620:0:2830:202::132;   //
        notify no;

// IPv6 ARPA
zone "" {
        type slave;
        file "/usr/local/etc/namedb/slave/";
        masters {
      ;           //
                2620:0:2d0:202::132;    //
      ;           //
                2620:0:2830:202::132;   //
        notify no;

// RFCs 1912, 5735 and 6303 (and BCP 32 for localhost)
zone "localhost"        { type master; file "/usr/local/etc/namedb/master/localhost-forward.db"; };
zone "" { type master; file "/usr/local/etc/namedb/master/localhost-reverse.db"; };

key "rndc-key" {
        algorithm hmac-md5;
        secret "XXXXXX";

controls {
        inet port 953
                allow {; } keys { "rndc-key"; };
include "/var/db/samba4/private/named.conf";

Where "XXXXXX" is the key material. Also update the non-empty zones to match your domain and IP range.

Create "/usr/local/etc/namedb/rndc.conf"

key "rndc-key" {
        algorithm hmac-md5;
        secret "XXXXXX";

options {
        default-key "rndc-key";
        default-port 953;

Where "XXXXXX" is the key material.

This file should be owned root:wheel with permissions 0640.

Check "/var/db/samba4/private/named.conf" and make sure only the "" line is uncommented.

Configure Samba

The following configuration will create a 'users' share and a 'public' share.

# Global parameters
        log level = all:2
        netbios name = EXAMPLEHOST
        realm = EXAMPLE.ORG
        workgroup = EXAMPLE
        server role = active directory domain controller
        server services = -dns
        idmap_ldb:use rfc2307 = yes

        path = /var/db/samba4/sysvol/
        read only = No

        path = /var/db/samba4/sysvol
        read only = No

        comment = User home directories
        path = /usr/home
        read only = no
        vfs objects = zfsacl

        comment = Public
        path = /public
        read only = no
        public = yes
        vfs objects = zfsacl

Note that AD mode is incompatible with the home directories feature, the 'users' share above is the canonical (Windows) way to do this.

Configure Kerberos

Copy the Kerberos configuration and key tab created by the classicupgrade script

sudo cp -p /var/db/samba4/private/krb5.conf /etc/
sudo cp -p /var/db/samba4/private/secrets.keytab /etc/krb5.keytab

Modify "/etc/krb5.conf" so it looks like so

        default_realm = EXAMPLE.ORG
        dns_lookup_realm = false
        dns_lookup_kdc = true
        default_ccache_name = /tmp/krb5cc_%{uid}

[domain_realm] = EXAMPLE.ORG

Configure NSS

Modify "/etc/nsswitch.conf" to comment out group, group_compat, passed and passwd_compat and replace with

group: files winbind
passwd: files winbind

Configure /etc/hosts

Add an entry to "/etc/hosts" which matches the hostname to to the IP, e.g.  examplehost example

Configure rc.conf

Add this to /etc/rc.conf to start bind & Samba at boot


Start daemons

Reboot or run the following to start BIND and Samba

sudo service samba_server start
sudo service named start


You should now be able to use "getent" to query Samba, eg..

[examplehost 14:38] ~ >getent group Domain\ Users
EXAMPLE\domain users:x:20
[examplehost 14:38] ~ >getent group Domain\ Admins
EXAMPLE\domain admins:x:0


In order for Windows to be able to manage permissions someone has to be given the right to change permissions. This can be done like so

sudo setfacl -m g:Domain\ Admins:cC:fd:allow /public /usr/home

Useful Commands


As Samba is now managing DNS you need to get it to add/remove records. This can be done with the Windows management tools or using samba-tool, e.g.

# Get a Kerberos ticket as an admin user

# List all zones
samba-tool dns zonelist examplehost -k yes

# List all forward records
samba-tool dns query examplehost -k yes @ ALL

# Create reverse zone (not done by default)
samba-tool dns zonecreate examplehost -k yes

# Add A record for testpc ->
samba-tool dns add examplehost -k yes testpc A
samba-tool dns add examplehost -k yes 10 CNAME

# Delete above records
samba-tool dns delete examplehost -k yes testpc A
samba-tool dns delete examplehost -k yes 10 CNAME

Set permissions

Grant group "Domain Users" all permissions on /somedir and contents

sudo find /somedir -type f -print0 | sudo xargs -0 setfacl -m g:Domain\ Users:full_set::allow
sudo find /somedir -type d -print0 | sudo xargs -0 setfacl -m g:Domain\ Users:full_set:fd:allow

Or for everybody (probably not wise, since it's like chmod 777/666)

sudo find /somedir -type f -print0 | sudo xargs -0 setfacl -m @everybody:full_set::allow
sudo find /somedir -type d -print0 | sudo xargs -0 setfacl -m @everybody:full_set:fd:allow

Limited privilege users

Create a "dhcpuser" who is a member of "DnsAdmins" which could be used to from a DHCP server to updated DNS

samba-tool user create dhcpduser --description="Unprivileged user for TSIG-GSSAPI DNS updates via ISC DHCP server" --random-password
samba-tool user setexpiry dhcpduser --noexpiry
samba-tool group addmembers DnsAdmins dhcpduser
samba-tool domain exportkeytab dhcpduser.keytab
sudo cp dhcpduser.keytab /usr/local/etc/dhcpduser.keytab

Note that I have only done limited testing here. This is based on an ArchLinux Wiki page and the package

Edit user profile information

sudo ldbedit -H /var/db/samba4/private/sam.ldb 'sAMAccountName=testuser'

Time synchronisation

When a Windows PC is joined to a domain the 'Internet Time' tab will disappear and it will instead only synchronise to the DC. For this to work NTPd needs to be configured to sign messages (with Samba's help).

Edit /etc/ntp.conf and add/modify the following..

ntpsigndsocket /var/run/samba4/ntp_signd/
restrict -4 default kod notrap nomodify nopeer noquery mssntp
restrict -6 default kod notrap nomodify nopeer noquery mssntp

And restart NTPd (eg sudo service ntpd restart)

Time synchronisation on a client Windows PC can be checked by running the following..

w32tm /stripchart / /dataonly

Which will give output like so

C:\Users\darius>w32tm /stripchart / /dataonly
Tracking [].
The current time is 10/01/2018 9:49:52 AM.
09:49:52, +00.0064586s
09:49:55, -00.0050746s
09:49:57, -00.0034439s
09:49:59, -00.0038588s
09:50:01, +00.1017965s
09:50:04, -00.0029371s
09:50:06, -00.0055241s
09:50:08, -00.0004811s
09:50:10, -00.0039628s

CategoryHowTo CategoryZfs

Samba4ZFS (last edited 2019-06-12T21:36:24+0000 by DanielOConnor)