Active Directory Service with Samba
Setting up Samba and Active Directory
We're building an Active Directory server from Samba running on FreeBSD, free server software on a free operating system. We have already set up the needed DNS infrastructure on an existing BIND master (or primary) DNS server, installed FreeBSD on a Raspberry Pi, and set that up as a BIND slave DNS server for those same zones. Now we're ready to do the Samba work! Jump back to the start for an overview of the project.
Recall that Active Directory is simply Microsoft's bundle of DNS, LDAP (more or less), and Kerberos (kind of). I had thought that Active Directory meant an enormously complicated collection of Microsoft-specific services, all of which communicate through arcane Microsoft-specific protocols. Not really.
Samba setup
In an earlier step we
installed Samba
on our FreeBSD system.
Now it's time to configure it.
But first, let's see if any Samba processes are running,
or if any old database files are
lying around to cause confusion.
The egrep
process may notice itself,
as here.
That doesn't matter, just make sure there aren't any
of the ones we're looking for:
Cleaning up
# ps axuww | egrep 'PID|samba|smbd|nmbd|winbindd' USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 755 0.0 0.5 6424 2280 0 S+ 16:30 0:00.08 egrep PID|samba|smbd|nmbd|winbind # smbd -b | grep / Built using: /nxb-bin/usr/bin/cc SRCDIR: /wrkdirs/usr/ports/net/samba43/work/samba-4.3.13/source3 BUILDDIR: /wrkdirs/usr/ports/net/samba43/work/samba-4.3.13/source3 SBINDIR: /usr/local/sbin BINDIR: /usr/local/bin CONFIGFILE: /usr/local/etc/smb4.conf LOGFILEBASE: /var/log/samba4 LMHOSTSFILE: /usr/local/etc/lmhosts LIBDIR: /usr/local/lib MODULESDIR: /usr/local/lib/shared-modules LOCKDIR: /var/db/samba4 STATEDIR: /var/db/samba4 CACHEDIR: /var/db/samba4 PIDDIR: /var/run/samba4 SMB_PASSWD_FILE: /var/db/samba4/private/smbpasswd PRIVATE_DIR: /var/db/samba4/private
You may need to clean up some things:
# pkill samba smbd nmbd winbindd # rm -rf /usr/local/etc/smb4.conf \ /usr/local/etc/lmhosts \ /var/db/samba4/*
Provisioning a domain
Make sure that you are certain about the DNS domain and Kerberos realm name, as you cannot change those. You would have to delete the definitions and start over with the correct names.
Here is one way to do the provisioning.
You can also do it interactively, passing only the
--use-rfc2307
option.
Include
RFC 2307
support,
as this allows you to store Unix attributes like UID,
home directory, etc., in Active Directory.
Be patient, as this takes several minutes to run,
especially on a single-CPU Raspberry Pi.
# samba-tool domain provision --use-rfc2307 \ --realm=CORP.EXAMPLE.COM --domain=CORP \ --server-role=dc --dns-backend=BIND9_DLZ Looking up IPv4 addresses Looking up IPv6 addresses Setting up share.ldb Setting up secrets.ldb Setting up the registry Setting up the privileges database Setting up idmap db Setting up SAM db Setting up sam.ldb partitions and settings Setting up sam.ldb rootDSE Pre-loading the Samba 4 and AD schema Adding DomainDN: DC=corp,DC=example,DC=com Adding configuration container Setting up sam.ldb schema Setting up sam.ldb configuration data Setting up display specifiers Modifying display specifiers Adding users container Modifying users container Adding computers container Modifying computers container Setting up sam.ldb data Setting up well known security principals Setting up sam.ldb users and groups Setting up self join Adding DNS accounts Creating CN=MicrosoftDNS,CN=System,DC=corp,DC=example,DC=com Creating DomainDnsZones and ForestDnsZones partitions Populating DomainDnsZones and ForestDnsZones partitions See /var/db/samba4/private/named.conf for an example configuration include file for BIND and /var/db/samba4/private/named.txt for further documentation required for secure DNS updates Setting up sam.ldb rootDSE marking as synchronized Fixing provision GUIDs A Kerberos configuration suitable for Samba 4 has been generated at /var/db/samba4/private/krb5.conf Setting up fake yp server settings Once the above files are installed, your Samba4 server will be ready to use Admin password: +Dyg<oqzjG~H$p%NI Server Role: active directory domain controller Hostname: freebsd NetBIOS Domain: CORP DNS Domain: corp.example.com DOMAIN SID: S-1-5-21-1556128061-1363490377-3170584331
Record the automatically generated administrator password and the domain SID.
You probably want to change the password expiration. Otherwise you will be suddenly inconvenienced in 42 days.
# samba-tool user setexpiry --noexpiry Administrator Expiry for user 'Administrator' disabled.
You may want to reset the password. If you do this without waiting for a day, change the minimum password age to zero:
# samba-tool domain passwordsettings show
Password informations for domain 'DC=corp,DC=example,DC=com'
Password complexity: on
Store plaintext passwords: off
Password history length: 24
Minimum password length: 7
Minimum password age (days): 1
Maximum password age (days): 42
Account lockout duration (mins): 30
Account lockout threshold (attempts): 0
Reset account lockout after (mins): 30
# samba-tool domain passwordsettings set --min-pwd-age 0
Minimum password age changed!
All changes applied successfully!
# samba-tool user password --user=administrator
Password for [CORP\administrator]:+Dyg<oqzjG~H$p%NI
New Password:new-password-here
Retype Password:new-password-here
Changed password OK
Remaining manual steps
Verify that
/var/db/samba4/private/named.conf
was automatically configured by uncommenting the
appropriate dlz_bind9_*.so
shared library.
Then, if it hasn't already been done automatically,
add a line at the end of
/usr/local/etc/namedb/named.conf
:
include "/var/db/samba4/private/named.conf";
I need to make a symbolic link to the new Kerberos configuration file:
# ln -s /var/db/samba4/private/krb5.conf /etc/krb5.conf
Now let's see if Samba starts cleanly:
# /usr/local/etc/rc.d/samba_server onestart
Performing sanity check on Samba configuration: OK
Starting samba.
[2017/02/18 11:55:02.721769, 0] ../lib/util/debug.c:947(reopen_logs_internal)
Unable to open new log file '/var/log/samba4/log.samba': No such file or directory
[2017/02/18 11:55:02.758508, 0] ../source4/smbd/server.c:371(binary_smbd_main)
samba version 4.3.13 started.
Copyright Andrew Tridgell and the Samba Team 1992-2015
# /usr/local/etc/rc.d/samba_server onestop
Stopping samba.
Waiting for PIDS: 1063
It fails because /var/log
is
mounted on RAM on the Raspberry Pi.
Logs disappear at every boot,
along with the expected subdirectory.
I have configured syslog to start, but then
to send everything over the network to a log collector
instead of saving it to disk.
Samba, however, wants to save a copy locally.
So, I added one line to the end of the
[global]
stanza in
/usr/local/etc/smb4.conf
.
I also removed the dnsupdate
from the end
of the list of server services.
[global]
workgroup = CORP
realm = CORP.EXAMPLE.COM
netbios name = FREEBSD
server role = active directory domain controller
server services = s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbindd, ntp_signd, kcc
idmap_ldb:use rfc2307 = yes
log file = /var/log/samba.%m
[netlogon]
path = /var/db/samba4/sysvol/corp.example.com/scripts
read only = No
[sysvol]
path = /var/db/samba4/sysvol
read only = No
Now let's try it again:
# /usr/local/etc/rc.d/samba_server onestart Performing sanity check on Samba configuration: OK Starting samba. [... wait a minute for everything to come up ...] # /usr/local/etc/rc.d/samba_server onestatus samba is running as pid 564. # pstree -+= 00001 root /sbin/init -- |--= 00347 root /sbin/devd |--= 00493 root /usr/sbin/syslogd -s |--= 00505 bind /usr/local/sbin/named -u bind -c /usr/local/etc/namedb/named.conf |--= 00553 root /usr/sbin/ntpd -g -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift |-+= 00564 root /usr/local/sbin/samba --daemon --configfile=/usr/local/etc/smb4.conf | |-+- 00690 root samba: task[s3fs_parent] (samba) | | \-+= 00692 root /usr/local/sbin/smbd -D --option=server role check:inhibit=yes --foreground | | |--- 00707 root /usr/local/sbin/smbd -D --option=server role check:inhibit=yes --foreground | | |--- 00710 root /usr/local/sbin/smbd -D --option=server role check:inhibit=yes --foreground | | \--- 01642 root /usr/local/sbin/smbd -D --option=server role check:inhibit=yes --foreground | |--- 00691 root samba: task[dcesrv] (samba) | |--- 00693 root samba: task[nbtd] (samba) | |--- 00694 root samba: task wrepl server_id[694] (samba) | |--- 00695 root samba: task[ldapsrv] (samba) | |--- 00696 root samba: task[cldapd] (samba) | |--- 00697 root samba: task[kdc] (samba) | |--- 00698 root samba: task[dreplsrv] (samba) | |-+- 00699 root samba: task[winbindd_parent] (samba) | | \-+= 00703 root /usr/local/sbin/winbindd -D --option=server role check:inhibit=yes --foreground | | |--- 00709 root /usr/local/sbin/winbindd -D --option=server role check:inhibit=yes --foreground | | |--- 01164 root /usr/local/sbin/winbindd -D --option=server role check:inhibit=yes --foreground | | \--- 01165 root /usr/local/sbin/winbindd -D --option=server role check:inhibit=yes --foreground | |--- 00700 root samba: task[ntp_signd] (samba) | |--- 00701 root samba: task[kccsrv] (samba) | \--- 00702 root samba: task[dnsupdate] (samba) |-+= 00634 root /usr/sbin/sshd | \-+= 01647 root sshd: cromwell [priv] (sshd) | \-+- 01649 cromwell sshd: cromwell@pts/0 (sshd) | \-+= 01650 cromwell -tcsh (tcsh) | \-+= 01688 cromwell pstree | \--- 01689 cromwell ps -axwwo user,pid,ppid,pgid,command |--= 00689 root /usr/libexec/getty 3wire.115200 ttyu0 |--= 00685 root /usr/libexec/getty Pc ttyv0 |--= 00686 root /usr/libexec/getty Pc ttyv1 |--= 00687 root /usr/libexec/getty Pc ttyv2 \--= 00688 root /usr/libexec/getty Pc ttyv3
I also looked in the syslog output on the log collector,
there were no new error messages about missing log directories.
Locally I have multiple Samba log files, all of them
ephemeral ones on the RAM-based /var/log
file system.
But all the content is going to the log collector
and being saved there.
# ls -l /var/log/log* /var/log/samba* total 20 drwxrwxr-x 2 root operator 512 Feb 18 11:42 .snap -rw-r--r-- 1 root wheel 266 Feb 18 12:27 log.wb-CORP -rw-r--r-- 1 root wheel 133 Feb 18 12:27 log.winbindd-idmap -rw-r--r-- 1 root wheel 3639 Feb 18 12:27 samba.%m -rw-r--r-- 1 root wheel 154 Feb 18 12:27 samba.smbd -rw-r--r-- 1 root wheel 342 Feb 18 12:27 samba.winbindd
All this seems good,
so I added this line to /etc/rc.conf
:
samba_server_enable="YES"
Now let's reboot and make sure that everything comes up.
Checking the network services
DNS
This is good, it's listening on IPv4 and IPv6 on all interfaces.
# lsof -i tcp:53 -o -i udp:53 COMMAND PID USER FD TYPE DEVICE OFFSET NODE NAME named 508 bind 21u IPv6 0xc321f650 0t0 TCP localhost:domain (LISTEN) named 508 bind 22u IPv4 0xc321f328 0t0 TCP localhost:domain (LISTEN) named 508 bind 23u IPv4 0xc321f000 0t0 TCP freebsd.example.com:domain (LISTEN) named 508 bind 24u IPv6 0xc321eca0 0t0 TCP [fe80:2::ba27:ebff:fe41:b9ae]:domain (LISTEN) named 508 bind 25u IPv6 0xc321e978 0t0 TCP freebsd.example.com:domain (LISTEN) named 508 bind 512u IPv6 0xc31373e8 0t0 UDP localhost:domain named 508 bind 513u IPv4 0xc31373d4 0t0 UDP localhost:domain named 508 bind 514u IPv4 0xc31373c0 0t0 UDP freebsd.example.com:domain named 508 bind 515u IPv6 0xc31373ac 0t0 UDP [fe80:2::ba27:ebff:fe41:b9ae]:domain named 508 bind 516u IPv6 0xc3137398 0t0 UDP freebsd.example.com:domain
Microsoft SMB/CIFS services
Three samba
processes are providing five
network services.
Check /etc/services
to figure out which
is which.
# egrep -w '135|136|137|138|139|445' /etc/services loc-srv 135/tcp epmap #Location Service loc-srv 135/udp epmap #Location Service profile 136/tcp #PROFILE Naming System profile 136/udp #PROFILE Naming System netbios-ns 137/tcp #NETBIOS Name Service netbios-ns 137/udp #NETBIOS Name Service netbios-dgm 138/tcp #NETBIOS Datagram Service netbios-dgm 138/udp #NETBIOS Datagram Service netbios-ssn 139/tcp #NETBIOS Session Service netbios-ssn 139/udp #NETBIOS Session Service microsoft-ds 445/tcp microsoft-ds 445/udp # lsof -i tcp:135-139 -o -i udp:135-139 -o -i tcp:445 -o -i udp:445 COMMAND PID USER FD TYPE DEVICE OFFSET NODE NAME samba 691 root 41u IPv6 0xc321d328 0t0 TCP *:loc-srv (LISTEN) samba 691 root 42u IPv4 0xc321d000 0t0 TCP *:loc-srv (LISTEN) smbd 692 root 44u IPv6 0xc321f978 0t0 TCP *:microsoft-ds (LISTEN) smbd 692 root 45u IPv6 0xc3480978 0t0 TCP *:netbios-ssn (LISTEN) smbd 692 root 46u IPv4 0xc3480650 0t0 TCP *:microsoft-ds (LISTEN) smbd 692 root 47u IPv4 0xc3480328 0t0 TCP *:netbios-ssn (LISTEN) samba 693 root 24u IPv4 0xc31372e4 0t0 UDP *:netbios-ns samba 693 root 27u IPv4 0xc31372d0 0t0 UDP *:netbios-dgm samba 693 root 29u IPv4 0xc31372bc 0t0 UDP 10.1.1.255:netbios-ns samba 693 root 30u IPv4 0xc31372a8 0t0 UDP freebsd.corp.example.com:netbios-ns samba 693 root 31u IPv4 0xc3137294 0t0 UDP 10.1.1.255:netbios-dgm samba 693 root 32u IPv4 0xc3137280 0t0 UDP freebsd.corp.example.com:netbios-dg
LDAP, LDAP/S
LDAP is needed for the directory service. We need both LDAP and Kerberos for Windows clients to move beyond old-style NetBIOS/LANMAN operation.
# lsof -i tcp:389 -o -i udp:389 -o -i tcp:636 -o -i udp:636 COMMAND PID USER FD TYPE DEVICE OFFSET NODE NAME samba 695 root 24u IPv6 0xc3381328 0t0 TCP *:ldap (LISTEN) samba 695 root 29u IPv6 0xc3381000 0t0 TCP *:ldaps (LISTEN) samba 695 root 33u IPv4 0xc3380650 0t0 TCP *:ldap (LISTEN) samba 695 root 34u IPv4 0xc3380328 0t0 TCP *:ldaps (LISTEN) samba 696 root 24u IPv6 0xc313726c 0t0 UDP *:ldap samba 696 root 30u IPv4 0xc3137258 0t0 UDP *:ldap samba 696 root 32u IPv6 0xc3137244 0t0 UDP freebsd.corp.example.com:ldap samba 696 root 33u IPv4 0xc3137230 0t0 UDP freebsd.corp.example.com:ldap
Kerberos
Finally, Kerberos authenticates users and issues service tickets.
# lsof -i tcp:88 -o -i udp:88 -o -i tcp:464 -o -i udp:464 COMMAND PID USER FD TYPE DEVICE OFFSET NODE NAME samba 697 root 24u IPv6 0xc3382000 0t0 TCP *:kerberos-sec (LISTEN) samba 697 root 31u IPv6 0xc313721c 0t0 UDP *:kerberos-sec samba 697 root 33u IPv6 0xc3381ca0 0t0 TCP *:kpasswd5 (LISTEN) samba 697 root 34u IPv6 0xc3137208 0t0 UDP *:kpasswd5 samba 697 root 35u IPv4 0xc3381978 0t0 TCP *:kerberos-sec (LISTEN) samba 697 root 36u IPv4 0xc31371f4 0t0 UDP *:kerberos-sec samba 697 root 37u IPv4 0xc3381650 0t0 TCP *:kpasswd5 (LISTEN) samba 697 root 38u IPv4 0xc31371e0 0t0 UDP *:kpasswd5 samba 697 root 39u IPv6 0xc31371cc 0t0 UDP freebsd.corp.example.com:kerberos-sec samba 697 root 40u IPv6 0xc31371b8 0t0 UDP freebsd.corp.example.com:kpasswd5 samba 697 root 41u IPv4 0xc31371a4 0t0 UDP freebsd.corp.example.com:kerberos-sec samba 697 root 42u IPv4 0xc3137190 0t0 UDP freebsd.corp.example.com:kpasswd5
Testing
Let's see if we can get a list of the shares from another system:
$ smbclient -L //freebsd -U administrator
Enter administrator's password: ************
Domain=[CORP] OS=[Windows 6.1] Server=[Samba 4.3.13]
Sharename Type Comment
--------- ---- -------
netlogon Disk
sysvol Disk
IPC$ IPC IPC Service (Samba 4.3.13)
Domain=[CORP] OS=[Windows 6.1] Server=[Samba 4.3.13]
Server Comment
--------- -------
Workgroup Master
--------- -------
The netlogon
and sysvol
shares
must exist on a domain controller.
They were created automatically during the provisioning.
Let's test the sysvol
share:
$ smbclient //freebsd/sysvol -U administrator -c 'dir'
Enter administrator's password: ************
Domain=[CORP] OS=[Windows 6.1] Server=[Samba 4.3.13]
. D 0 Fri Feb 17 10:40:28 2025
.. D 0 Fri Feb 17 13:57:46 2025
corp.example.com D 0 Fri Feb 17 10:40:28 2025
30162908 blocks of size 1024. 25800308 blocks available
Let's see if we can get information about the AD server.
I should be able to do that from the AD server itself
and from another system,
so long as its Samba configuration file
/etc/samba/smb.conf
is set up reasonably.
Its [global]
stanza should have a
realm = REALM_NAME
line.
$ net ads info LDAP server: 10.1.1.235 LDAP server name: freebsd.corp.example.com Realm: CORP.EXAMPLE.COM Bind Path: dc=CORP,dc=EXAMPLE,dc=COM LDAP port: 389 Server time: Wed, 15 Mar 2017 14:16:53 EST KDC server: 10.1.1.235 Server time offset: 0
Can I get Kerberos credentials from a command prompt on the AD server?
$ klist
klist: No ticket file: /tmp/krb5cc_1000
$ kinit administrator@CORP.EXAMPLE.COM
administrator@CORP.EXAMPLE.COM's Password: ************
$ klist
Credentials cache: FILE:/tmp/krb5cc_1000
Principal: administrator@CORP.EXAMPLE.COM
Issued Expires Principal
Feb 17 16:43:02 2025 Feb 18 00:43:01 2025 krbtgt/CORP.EXAMPLE.COM@CORP.EXAMPLE.COM
$ klist -v
Credentials cache: FILE:/tmp/krb5cc_1000
Principal: administrator@CORP.EXAMPLE.COM
Cache version: 4
Server: krbtgt/CORP.EXAMPLE.COM@CORP.EXAMPLE.COM
Client: administrator@CORP.EXAMPLE.COM
Ticket etype: aes256-cts-hmac-sha1-96, kvno 1
Ticket length: 985
Auth time: Feb 17 16:43:02 2025
End time: Feb 18 00:43:01 2025
Ticket flags: pre-authent, initial, forwardable
Addresses: addressless
The above is on the AD server, so klist
is
from the Heimdal Kerberos implementation.
I'll do this from another system where klist
is from the MIT implementation.
Unfortunately, the two implementations
have different syntax.
$ klist
klist: No credentials cache found (filename: /tmp/krb5cc_1000)
$ kinit administrator@CORP.EXAMPLE.COM
administrator@CORP.EXAMPLE.COM's Password: ************
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: administrator@CORP.EXAMPLE.COM
Valid starting Expires Service principal
03/16/17 14:48:35 03/17/17 00:48:35 krbtgt/CORP.EXAMPLE.COM@CORP.EXAMPLE.COM
renew until 03/17/17 14:48:33
$ klist -ef
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: administrator@CORP.EXAMPLE.COM
Valid starting Expires Service principal
03/16/17 14:48:35 03/17/17 00:48:35 krbtgt/CORP.EXAMPLE.COM@CORP.EXAMPLE.COM
renew until 03/17/17 14:48:33, Flags: RIA
Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96
The MIT Kerberos Administrator's How-To Guide
MIT Kerberos Documentation
BIND9_DLZ Back End Troubleshooting
Red Hat Enterprise Linux
Windows Integration Guide
It's working!
If it didn't there is troubleshooting information at samba.org.
The MIT How-To Guide starts with a very good overview of Kerberos. MIT has further Kerberos documentation if you need it. The Heimdal project has some good documentation about their implementation, although you won't be interacting with it directly.
Now we need to create users and groups
We need to define users and groups in the
LDAP directory tree and Kerberos database.
All of our testing has used Administrator
,
the only user defined so far.
You use samba-tool
to define AD groups and users.
We will manage the Kerberos cryptography requirements
with ktutil
.
Yes, for standalone Kerberos you would use kadmin
to manage the Kerberos database in
/var/heimdal/heimdal.db
,
a Berkeley Btree database file.
However, Samba manages its own Kerberos database under
/var/db/samba4/private/
.
You do all interaction with the Samba database,
both the LDAP directory and the Kerberos database,
using the samba-tool
command.
The exception to this is the use of ktutil
to interact with the Kerberos keytab.
You will see that in the
next step.
The next page takes us through a practical deployment.