Moving a Samba/OpenLDAP domain controller from CentOS to Debian


Various errors on the way

November 2022.
openldap-logoSamba Logo

Today we are going to move a Samba/LDAP domain controller from a centos server to a debian server.

Source server:

admin@centos$ cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
admin@centos$ uname -a
Linux my-company-01 3.10.0-1160.11.1.el7.x86_64 #1 SMP Fri Dec 18 16:34:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Target server:

admin@debian$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye
admin@debian$ uname -a
Linux my-company 5.10.0-19-686 #1 SMP Debian 5.10.149-2 (2022-10-21) i686 GNU/Linux

Migrating the LDAP instance

Exporting and copying the database to the new server

Stop the openldap instance on the centos server:

systemctl stop slapd

Export the LDAP databases on the centos server:

slapcat -n 0 -l /somewhere/slapd-config-2022-11-12.ldif
slapcat -n 1 -l /somewhere/slapd-data-2022-11-12.ldif

Copy the LDAP data from the centos server to the debian server:

scp /somewhere/slapd-* admin@debian-server:/somewhere
slapd-config-2022-11-12.ldif                                                                                                                                                                                             100%  138KB  16.5MB/s   00:00
slapd-data-2022-11-12.ldif

Installing OpenLDAP

Install openldap on the debian server:

apt -y install slapd ldap-utils
[...]
[set a dummy password in the process]
[...]

Stop the instance on the debian server:

service slapd stop

Clear the slapd config directory:

rm -r /etc/ldap/slapd.d/
mkdir /etc/ldap/slapd.d/

Create a config file from the example:

zcat /usr/share/doc/slapd/examples/slapd.conf.gz > /etc/ldap/slapd.conf

Change the config so that your base DN is configured:

suffix          "dc=my-company,dc=com"

access to attrs=userPassword,shadowLastChange
        by dn="cn=admin,dc=my-company,dc=com" write
        by anonymous auth
        by self write
        by * none

access to *
        by dn="cn=admin,dc=my-company,dc=com" write
        by * read

Importing the config database

Let's import the config:

# slapadd -n 0 -l /home/erwan/slapd-config-2022-11-12.ldif
636f6e60 /etc/ldap/slapd.conf: line 69: unknown directive  inside backend database definition.

This is because the config file includes configuration items for the BDB/HDB databases, which we don't use. Let's comment those lines:

# sed -i 's/^dbconfig /#dbconfig /' /etc/ldap/slapd.conf

Let's see where the imported config expects to load its modules:

# cat /home/erwan/slapd-config-2022-11-12.ldif | grep olcModulePath | uniq
olcModulePath: /usr/lib64/openldap

On debian, these are stored in /usr/lib/ldap.

We need to change the entries in the ldif file:

# sed -i 's#/usr/lib64/openldap#/usr/lib/ldap#' /home/erwan/slapd-config-2022-11-12.ldif
# cat /home/erwan/slapd-config-2022-11-12.ldif | grep olcModulePath | uniq
olcModulePath: /usr/lib/ldap

Let's see where the imported config expects to create the PID file:

# cat /home/erwan/slapd-config-2022-11-12.ldif | grep olcPidFile
olcPidFile: /var/run/openldap/

On debian, it's stored in /var/run/slapd.

We need to change that path the in the ldif file:

sed -i 's#/var/run/openldap#/var/run/slapd#' /home/erwan/slapd-config-2022-11-12.ldif
# cat /home/erwan/slapd-config-2022-11-12.ldif | grep olcPidFile
olcPidFile: /var/run/slapd/

Let's see where the imported config expects to have the DB files:

# cat /home/erwan/slapd-config-2022-11-12.ldif | grep olcDbDirectory | uniq
olcDbDirectory: /var/lib/ldap

This times, the directories are the same on the two distributions.

Let's import the config:

# slapadd -n 0 -l /home/erwan/slapd-config-2022-11-12.ldif
slapadd: could not add entry dn="cn=config" (line=1):
_                       0.32% eta   none elapsed            none spd   4.2 M/s
Closing DB...

I have no idea why, but even though slapadd uses /etc/ldap/slapd.d/ by default, it still requires the directory to be provided on the command line in order to work properly:

# slapadd -F /etc/ldap/slapd.d/ -v -n 0 -l /home/erwan/slapd-config-2022-11-12.ldif
added: "cn=config" (00000001)
added: "cn=module{0},cn=config" (00000001)
added: "cn=module{1},cn=config" (00000001)
added: "cn=module{2},cn=config" (00000001)
636f76a0 lt_dlopenext failed: (smbk5pwd) file not found
slapadd: could not add entry dn="cn=module{3},cn=config" (line=56):
_                       1.62% eta   none elapsed            none spd 764.3 k/s
Closing DB...

This is because our LDAP database includes a domain controller. We need the schemas and modules from the samba package:

# apt-get install slapd-smbk5pwd
# rm -r /etc/ldap/slapd.d/ && mkdir /etc/ldap/slapd.d/
# slapadd -F /etc/ldap/slapd.d/ -v -n 0 -l /home/erwan/slapd-config-2022-11-12.ldif
added: "cn=config" (00000001)
added: "cn=module{0},cn=config" (00000001)
added: "cn=module{1},cn=config" (00000001)
added: "cn=module{2},cn=config" (00000001)
added: "cn=module{3},cn=config" (00000001)
added: "cn=schema,cn=config" (00000001)
added: "cn={0}core,cn=schema,cn=config" (00000001)
added: "cn={1}cosine,cn=schema,cn=config" (00000001)
added: "cn={2}nis,cn=schema,cn=config" (00000001)
added: "cn={3}inetorgperson,cn=schema,cn=config" (00000001)
added: "cn={4}core-fd,cn=schema,cn=config" (00000001)
added: "cn={5}core-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={6}ldapns,cn=schema,cn=config" (00000001)
added: "cn={7}template-fd,cn=schema,cn=config" (00000001)
added: "cn={8}samba-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={9}samba,cn=schema,cn=config" (00000001)
added: "cn={10}applications-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={11}applications-fd,cn=schema,cn=config" (00000001)
added: "cn={12}personal-fd,cn=schema,cn=config" (00000001)
added: "cn={13}personal-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={14}service-fd,cn=schema,cn=config" (00000001)
added: "cn={15}systems-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={16}systems-fd,cn=schema,cn=config" (00000001)
added: "cn={17}netgroups-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={18}mail-fd-conf,cn=schema,cn=config" (00000001)
added: "cn={19}mail-fd,cn=schema,cn=config" (00000001)
added: "cn={20}spagobi,cn=schema,cn=config" (00000001)
added: "cn={21}hdb,cn=schema,cn=config" (00000001)
added: "cn={22}dsa-fd-conf,cn=schema,cn=config" (00000001)
added: "olcBackend={0}mdb,cn=config" (00000001)
added: "olcDatabase={-1}frontend,cn=config" (00000001)
added: "olcDatabase={0}config,cn=config" (00000001)
added: "olcDatabase={1}mdb,cn=config" (00000001)
added: "olcOverlay={0}memberof,olcDatabase={1}mdb,cn=config" (00000001)
added: "olcOverlay={1}refint,olcDatabase={1}mdb,cn=config" (00000001)
added: "olcOverlay={2}smbk5pwd,olcDatabase={1}mdb,cn=config" (00000001)
_#################### 100.00% eta   none elapsed            none fast!
Closing DB...

All good!

Importing the data database

The command to import the data is very similar:

# slapadd -F /etc/ldap/slapd.d/ -v -n 1 -l /home/erwan/slapd-data-2022-11-12.ldif
added: "dc=my-company,dc=com" (00000002)
added: "cn=admin,dc=my-company,dc=com" (00000003)
added: "ou=aclroles,dc=my-company,dc=com" (00000006)
added: "cn=admin,ou=aclroles,dc=my-company,dc=com" (00000007)
added: "ou=Users,dc=my-company,dc=com" (00000008)
[...]
-#################### 100.00% eta   none elapsed             05s spd  28.6 k/s
Closing DB...

Starting the OpenLDAP instance

Let's set the permissions on the databases:

chown -R openldap:openldap /etc/ldap/slapd.d/

Start the OpenLDAP instance:

service slapd start

Check that the instance is running:

# service slapd status
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
     Loaded: loaded (/etc/init.d/slapd; generated)
    Drop-In: /usr/lib/systemd/system/slapd.service.d
             └─slapd-remain-after-exit.conf
     Active: active (running) since Sat 2022-11-12 11:43:46 CET; 46s ago
       Docs: man:systemd-sysv-generator(8)
    Process: 6523 ExecStart=/etc/init.d/slapd start (code=exited, status=0/SUCCESS)
      Tasks: 3 (limit: 4915)
     Memory: 6.6M
        CPU: 60ms
     CGroup: /system.slice/slapd.service
             └─6530 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d

nov. 12 11:43:46 my-company systemd[1]: Starting LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)...
nov. 12 11:43:46 my-company slapd[6529]: @(#) $OpenLDAP: slapd 2.4.57+dfsg-3+deb11u1 (May 14 2022 18:32:57) $
                                            Debian OpenLDAP Maintainers 
nov. 12 11:43:46 my-company slapd[6530]: slapd starting
nov. 12 11:43:46 my-company slapd[6523]: Starting OpenLDAP: slapd.
nov. 12 11:43:46 my-company systemd[1]: Started LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol).

Check that the PID file is created:

ll /var/run/slapd/
total 8,0K
   0 drwxr-xr-x  2 openldap openldap 100 12 nov.  11:43 .
   0 drwxr-xr-x 31 root     root     900 12 nov.  10:42 ..
   0 srwxrwxrwx  1 root     root       0 12 nov.  11:43 ldapi
4,0K -rw-r--r--  1 openldap openldap  84 12 nov.  11:43 slapd.args
4,0K -rw-r--r--  1 openldap openldap   5 12 nov.  11:43 slapd.pid

Check that the server is listening on the LDAP port:

# ss -lnp | grep 389
tcp   LISTEN 0      1024                                      0.0.0.0:389              0.0.0.0:*     users:(("slapd",pid=6530,fd=8))
tcp   LISTEN 0      1024                                         [::]:389                 [::]:*     users:(("slapd",pid=6530,fd=9))

Check that the database can be queried and that our data is there:

ldapsearch -x -b "dc=my-company,dc=com" | less

Configuring NSS LDAP

Installing NSS LDAP

apt-get install libnss-ldap

The installer will ask various questions to configure the LDAP client.

This is what our /etc/libnss-ldap.conf looks like now:

base dc=my-company,dc=com
uri ldapi:///127.0.0.1
ldap_version 3
rootbinddn cn=admin,dc=my-company,dc=com

The secret for the bind DN is stored in /etc/libnss-ldap.secret (mode 0600).

Using NSS LDAP

Configure /etc/nsswitch.conf to use LDAP for users and groups:

passwd:         files ldap
group:          files ldap
getent passwd
[...]
j.bon:x:1121:100:Jean BON:/home/j.bon:/bin/ash
a.husse:x:1123:100:Anne HUSSE:/home/a.husse:/bin/ash
getent group
[...]
domain_admins:*:512:root,j.bon
domain_guests:*:514:somenas
domain_computers:*:515:somenas
Administrators:*:544:somenas
Account Operators:*:548:somenas
print_operators:*:550:somenas
Backup Operators:*:551:somenas
Replicators:*:552:somenas

These are from LDAP. All good.

Migrating the samba domain controller

Installing and configuring samba

apt-get install samba

This is what we're using for the samba configuration in /etc/samba/smb.conf:

log level = 3 passdb:4 auth:4

[global]
   log file = /var/log/samba/log.%m
   max log size = 1000
   logging = file
   panic action = /usr/share/samba/panic-action %d

   workgroup = MYCOMPANY
   netbios name = MYDOMAINCONTROLLER
   dns proxy = no
   wins support = yes
   security = user
   server role = classic primary domain controller
   passdb backend = ldapsam:ldap://127.0.0.1
   encrypt passwords = true

   ldap suffix = dc=my-company,dc=com
   ldap machine suffix = ou=computers,ou=systems
   ldap user suffix = ou=users
   ldap group suffix = ou=groups
   ldap admin dn = cn=admin,dc=my-company,dc=com
   ldap delete dn = no
   ldap password sync = yes
   ldap ssl = off

   logon path = \\%N\%U\profile
   logon drive = H:
   logon home = \\%N\%U

   vfs objects = acl_xattr
   map acl inherit = yes
   store dos attributes = yes

   obey pam restrictions = yes
   domain logons = yes
   domain master = yes
   preferred master = yes

   printing = cups
   printcap name = cups
   load printers = yes
   cups options = raw

   # We're having some very old legacy clients, so we need to enable the legacy auth methods. This must only be done on a fully trusted network:
   lm announce = no
   lanman auth = no
   ntlm auth = no
   client lanman auth = no
   client ntlmv2 auth = yes
   ntlm auth = ntlmv1-permitted
   server min protocol = NT1

[netlogon]
   comment = Network Logon Service
   path = /home/samba/netlogon
   guest ok = yes
   read only = yes

[homes]
   comment = Home Directories
   valid users = %S, %D%w%S
   browseable = No
   read only = No
   inherit acls = Yes

[printers]
   comment = All Printers
   path = /var/tmp
   printable = Yes
   create mask = 0600
   browseable = No

[print$]
   comment = Printer Drivers
   path = /var/lib/samba/drivers
   write list = @printadmin root
   force group = @printadmin
   create mask = 0664
   directory mask = 0775

Set the password for samba to bind to the LDAP:

# smbpasswd -w '[bind-password]'
Processing section "[global]"
Setting stored password for "cn=admin,dc=my-company,dc=com" in secrets.tdb

Checking Samba's configuration

Start samba:

# service nmbd start
# service smbd start

Check that samba is running:

# tail /var/log/log.smbd
[2022/11/12 11:47:52.693497,  0] ../../source3/smbd/server.c:1784(main)
  smbd version 4.13.13-Debian started.
  Copyright Andrew Tridgell and the Samba Team 1992-2020
[2022/11/12 11:47:53.299819,  0] ../../lib/util/become_daemon.c:135(daemon_ready)
  daemon_ready: daemon 'smbd' finished starting up and ready to serve connections

# tail /var/log/log.nmbd
2022/11/12 11:47:52.464675,  0] ../../source3/nmbd/nmbd.c:960(main)
  nmbd version 4.13.13-Debian started.
  Copyright Andrew Tridgell and the Samba Team 1992-2020
[2022/11/12 11:47:52.467535,  0] ../../lib/util/become_daemon.c:135(daemon_ready)
  daemon_ready: daemon 'nmbd' finished starting up and ready to serve connections

Check that the usual TCP and UDP ports are listening:

# ss -tunlp | egrep '(smbd|nmbd)'
udp   UNCONN 0      0      192.168.200.255:137        0.0.0.0:*    users:(("nmbd",pid=7264,fd=20))
udp   UNCONN 0      0      192.168.200.118:137        0.0.0.0:*    users:(("nmbd",pid=7264,fd=19))
udp   UNCONN 0      0      192.168.200.255:137        0.0.0.0:*    users:(("nmbd",pid=7264,fd=16))
udp   UNCONN 0      0      192.168.200.152:137        0.0.0.0:*    users:(("nmbd",pid=7264,fd=15))
udp   UNCONN 0      0              0.0.0.0:137        0.0.0.0:*    users:(("nmbd",pid=7264,fd=13))
udp   UNCONN 0      0      192.168.200.255:138        0.0.0.0:*    users:(("nmbd",pid=7264,fd=22))
udp   UNCONN 0      0      192.168.200.118:138        0.0.0.0:*    users:(("nmbd",pid=7264,fd=21))
udp   UNCONN 0      0      192.168.200.255:138        0.0.0.0:*    users:(("nmbd",pid=7264,fd=18))
udp   UNCONN 0      0      192.168.200.152:138        0.0.0.0:*    users:(("nmbd",pid=7264,fd=17))
udp   UNCONN 0      0              0.0.0.0:138        0.0.0.0:*    users:(("nmbd",pid=7264,fd=14))
tcp   LISTEN 0      50             0.0.0.0:139        0.0.0.0:*    users:(("smbd",pid=7274,fd=49))
tcp   LISTEN 0      50             0.0.0.0:445        0.0.0.0:*    users:(("smbd",pid=7274,fd=48))
tcp   LISTEN 0      50                [::]:139           [::]:*    users:(("smbd",pid=7274,fd=47))
tcp   LISTEN 0      50                [::]:445           [::]:*    users:(("smbd",pid=7274,fd=46))

Check that our LDAP users are present in the Samba database:

pdbedit -L -v
[...]
---------------
Unix username:        j.bon
NT username:          j.bon
Account Flags:        [U          ]
User SID:             S-1-5-21-1234567890-3474475300-2450999395-3268
Failed to find a Unix account for j.guilbert
Primary Group SID:    (NULL SID)
Full Name:            Jean Bon
Home Directory:       \\MYDOMAINCONTROLLER\j.bon
HomeDir Drive:        H:
Logon Script:
Profile Path:         \\MYDOMAINCONTROLLER\j.bon\profile
Domain:               MY-COMPANY
Account desc:
Workstations:
Munged dial:          ...
Logon time:           0
Logoff time:          never
Kickoff time:         never
Password last set:    mar., 25 oct. 2022 09:30:14 CEST
Password can change:  mar., 25 oct. 2022 09:30:14 CEST
Password must change: never
Last bad password   : 0
Bad password count  : 0
Logon hours         : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

All good!