Samba AD-DC Migration How I Did It

Having recently migrated an old samba 3.6 PDC to a samba 4.9 AD-DC I decided to document the steps I went through. The Samba Wiki was helpful but over the duration of this project; the contents of the wiki changed and samba changed as well. This lead me to a few issues. I’m sure I missed a lot as well. Prior to this migration I had not really touched samba 4. I had printed a number of pages from the samba wiki when I started this project. The old server is running SuSE Enterprise Linux Server 10 and has been in operation since 2007.

I followed the “classicupgrade” process for the most part.

I exported the old LDAPSAM and copied all of the TDB and LDB files from the old server.

On the new server I setup OpenLDAP, adjusting the configuration so I could import the old data. The old server was running OpenLDAP 2.3 and the new server had OpenLDAP 2.4 so there were a few changes, thankfully I have done this before setting up LDAP replicate servers. I did have to change the port it was running on though. I used port 1389 and set it to only work on the localhost since network access was not required.

Once the data was imported and confirmed valid, I went through the users and removed those entries that were not needed. In this case the LDAP had a number of entries that were only used by the old server. I also removed a number of former staff whose accounts were still hanging around. This reduced the number of issues for the classicupgrade process.

It was during testing that I found Debian Stretch was still “shipping” with Samba 4.5. As I was having issues I forced an update to 4.9 from the “testing” version. After this things seemed to work much better. In my testing VM I only got through the classicupgrade steps as my “lab” does not have anything else to test the migration with.

I was using Bind 9 for DNS as I am used to it and already have a couple running on the network. Taking this into account I used the BIND_DLZ settings for the classicupgrade. I did have to remove the –use-xattrs=yes parameter as it has been removed in the 4.9 version.

samba-tool domain classicupgrade --dbdir=/home/ahaines/old-pdc/ --realm=samdom.example.net --dns-backend=BIND9_DLZ /home/ahaines/old-pdc/smb.conf

I did make a couple mistakes here. I forgot to change the LDAP server and I forgot to change the machine name. Thankfully it was easy to start over at this point. Unfortunately I made the same mistake in both testing and production. I was scratching my head trying to figure out why “bob” was showing up during the migration when “bob” was not even accessible at the time.

As the migration was started during business hours I moved the new servers into an isolated network after gathering the required files. This allowed me to keep the same IP addresses and not interfere with the end users. After everyone had left the office we disconnected all of the desktops, and Windows servers, from the network and moved the new servers back into the main network. I started syncing (via rsync) the files from the old server to the new ones. We had decided to split the server into 2 to provide extra bandwidth and separation. The new primary server would house the domain control and the user profiles, the other server would contain the shared files. I later learned it is no longer recommended to share files from the AD-DC server but we did it anyways.

I did have some issues with permissions on the AD-DC in setting up the user profiles.

After following the instructions I had I ended up with the following smb.conf on the AD-DC:

# Global parameters
[global]
netbios name = UPINSMOKE
realm = SAMDOM.EXAMPLE.NET
server role = active directory domain controller
server services = s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbindd, ntp_signd, kcc, dnsupdate
workgroup = SAMDOM
idmap_ldb:use rfc2307 = yes

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

winbind use default domain = Yes
winbind enum users = Yes
winbind enum groups = Yes
winbind nested groups = Yes
winbind separator = +
winbind refresh tickets = yes
winbind offline logon = yes
winbind cache time = 300
winbind nss info = rfc2307
winbind normalize names = Yes

template shell = /bin/false
template homedir = /home/%U

load printers = no

# Default ID mapping configuration for local BUILTIN accounts
# and groups on a domain member. The default (*) domain:
# - must not overlap with any domain ID mapping configuration!
# - must use a read-write-enabled back end, such as tdb.
idmap config * : backend = tdb
idmap config * : range = 100000-179999
# - You must set a DOMAIN backend configuration
# idmap config for the SAMDOM domain
idmap config SAMDOM:backend = ad
idmap config SAMDOM:schema_mode = rfc2307
idmap config SAMDOM:range = 1000-99999
idmap config SAMDOM:unix_nss_info = yes

deadtime = 60

log level = 3
server signing = auto
client signing = auto

[netlogon]
path = /var/lib/samba/sysvol/samdom.example.net/scripts
read only = No

[sysvol]
path = /var/lib/samba/sysvol
read only = No

[profiles]
path = /var/lib/samba/profiles
read only = No

[userhome]
path = /var/lib/samba/homes
read only = No

This configuration ended up causing some issues that were difficult to track down. The second server with all the shared files worked but the QNAP NAS units did not work completely. See this post for details. After all was said and done I ended up with the following smb.conf on the AD-DC server:

# Global parameters
[global]
netbios name = UPINSMOKE
realm = SAMDOM.EXAMPLE.NET
server role = active directory domain controller
server services = s3fs, rpc, nbt, wrepl, ldap, cldap, kdc, drepl, winbindd, ntp_signd, kcc, dnsupdate
workgroup = SAMDOM
idmap_ldb:use rfc2307 = yes

winbind enum users = Yes
winbind enum groups = Yes
winbind nested groups = Yes
winbind refresh tickets = yes
winbind offline logon = yes
winbind cache time = 300
winbind nss info = rfc2307

template shell = /bin/false
template homedir = /home/%U

load printers = no

deadtime = 60

log level = 3
server signing = auto
client signing = auto

[netlogon]
path = /var/lib/samba/sysvol/samdom.example.net/scripts
read only = No

[sysvol]
path = /var/lib/samba/sysvol
read only = No

[profiles]
path = /var/lib/samba/profiles
read only = No

[userhome]
path = /var/lib/samba/homes
read only = No

I created the profiles folder and set the permissions with:

mkdir /var/lib/samba/profiles
chgrp -R "PLATA\domain users" /var/lib/samba/profiles
chmod 1750 /var/lib/samba/profiles

Then I went to Windows Explorer and set the Windows ACLs as per the samba wiki. The home drives were done the same way. For the most part this worked. At first things did not come up as expected, I had to manually change each user’s profile in the AD-DC to point to the new server and new path. I never did like Microsoft’s way of doing things. I figure why expose information to someone if they do not need to see it. This is the way our old server worked, a user only saw their profile. The Microsoft method already does the recon for an attacker and a simple permissions “glitch” could expose all user profiles. But that’s another story.

The second server was easier to set up as it only has shared files. Its smb.conf ended up as:

[global]
netbios name = CHEECH
workgroup = SAMDOM
realm = SAMDOM.EXAMPLE.NET
server string = %h Debian Host
security = ads
encrypt passwords = yes
client signing = auto
server signing = auto
winbind use default domain = Yes
winbind enum users = Yes
winbind enum groups = Yes
winbind nested groups = Yes
winbind separator = +
winbind refresh tickets = yes
winbind offline logon = yes
winbind cache time = 300
winbind normalize names = Yes

template shell = /bin/false
template homedir = /home/%U

preferred master = no
dns proxy = no
wins server = upinsmoke.samdom.example.net
wins proxy = no

inherit acls = Yes
map acl inherit = Yes
acl group control = yes

load printers = no
debug level = 3
use sendfile = no

# Default ID mapping configuration for local BUILTIN accounts
# and groups on a domain member. The default (*) domain:
# - must not overlap with any domain ID mapping configuration!
# - must use a read-write-enabled back end, such as tdb.
idmap config * : backend = tdb
idmap config * : range = 100000-179999
# - You must set a DOMAIN backend configuration
# idmap config for the SAMDOM domain
idmap config SAMDOM:backend = ad
idmap config SAMDOM:schema_mode = rfc2307
idmap config SAMDOM:range = 1000-99999
idmap config SAMDOM:unix_nss_info = yes

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

kerberos method = secrets and keytab
dedicated keytab file = /etc/krb5.keytab

username map = /var/lib/samba/private/user.map

aio read size = 1
aio write size = 1

deadtime = 15

I needed to use the map file to map the domain administrator to root. Without this I could not use Computer Management on Windows to set the share permissions. I was trying to use Windows ACLs according to the Samba Wiki. I also messed around the the krb5.conf file while trying to get this to work ending up with the following on both servers:

[libdefaults]
ticket_lifetime = 24000
default_realm = SAMDOM.EXAMPLE.NET
dns_lookup_realm = true
dns_lookup_kdc = true
dns_fallback = yes
[realms]
SAMDOM.EXAMPLE.NET = {
kdc = upinsmoke.samdom.example.net
default_domain = samdom.example.net
}
[domain_realm]
.samdom.example.net = SAMDOM.EXAMPLE.NET
samdom.example.net = SAMDOM.EXAMPLE.NET
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
[logging]
default = FILE:/var/log/lrk5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

With the idmap lines in the AD-DC’s smb.conf the QNAP NAS units would see the user via wbinfo but would not see them when permissions were applied. Removing these entries allowed getent passwd to show all the user accounts in the domain as well as local users. See the post for the details.

The QNAP NAS uses a customized version of samba that reports itself as version 4.4.16. I say customized as QNAP has backported fixes from later versions since 4.4 was EOL last year. QNAP also has coded their setup to use the rid idmap backend. I manually changed this config file so I know I’ll have to make changes every time the firmware is updated. Here’s the smb.conf for the first QNAP unit I got working:

[global]
passdb backend = smbpasswd
workgroup = SAMDOM
security = ADS
server string =
encrypt passwords = Yes
username level = 0
map to guest = Never
null passwords = yes
max log size = 100
socket options = TCP_NODELAY SO_KEEPALIVE
os level = 20
preferred master = no
dns proxy = No
smb passwd file=/etc/config/smbpasswd
username map = /etc/config/smbusers
guest account = guest
directory mask = 0777
create mask = 0777
oplocks = yes
locking = yes
disable spoolss = no
load printers = yes
veto files = /.AppleDB/.AppleDouble/.AppleDesktop/:2eDS_Store/Network Trash Folder/Temporary Items/TheVolumeSettingsFolder/.@__thumb/.@__desc/:2e*/.@__qini/.Qsync/.@upload_cache/.qsync/.qsync_sn/.@qsys/.streams/.digest/
delete veto files = yes
map archive = no
map system = no
map hidden = no
map read only = no
deadtime = 10
server role = auto
use sendfile = yes
unix extensions = no
store dos attributes = yes
client ntlmv2 auth = yes
dos filetime resolution = no
follow symlinks = yes
wide links = yes
force unknown acl user = yes
template homedir = /share/homes/DOMAIN=%D/%U
inherit acls = yes
domain logons = no
min receivefile size = 256
case sensitive = auto
domain master = auto
local master = no
enhance acl v1 = yes
remove everyone = yes
conn log = no
kernel oplocks = no
max protocol = SMB2_10
min protocol = LANMAN1
smb2 leases = yes
durable handles = yes
kernel share modes = no
posix locking = no
lock directory = /share/CACHEDEV1_DATA/.samba/lock
state directory = /share/CACHEDEV1_DATA/.samba/state
cache directory = /share/CACHEDEV1_DATA/.samba/cache
printcap cache time = 0
acl allow execute always = yes
server signing = disabled
streams_depot:delete_lost = yes
streams_depot:check_valid = no
fruit:nfs_aces = no
fruit:veto_appledouble = no
pid directory = /var/lock
printcap name = /etc/printcap
printing = cups
show add printer wizard = no
winbind scan trusted domains = yes
realm = samdom.example.net
ldap timeout = 15
password server = UPINSMOKE.samdom.example.net
pam password change = yes
winbind enum users = Yes
winbind enum groups = Yes
winbind cache time = 3600
;idmap config * : backend = tdb
;idmap config * : range = 400001-500000
;idmap config SAMDOM : backend = rid
;idmap config SAMDOM : range = 10000001-20000000
winbind expand groups = 1
;
; added 2019-Jan-02
;
client schannel = yes
ea support = Yes
map acl inherit = yes
idmap config * : backend = tdb
idmap config * : range = 100000-179000
idmap config SAMDOM : backend = ad
idmap config SAMDOM : range = 1000-99999
idmap config SAMDOM : schema_mode = rfc2307
idmap config SAMDOM : unix_nss_info = yes
ntlm auth = no
server schannel = yes
log level = 3 winbind:10
;winbind normalize names = yes
winbind offline logon = yes
winbind refresh tickets = yes
;winbind separator = +
;winbind use default domain = yes
kccsrv:samba_kcc = yes
wins support = no
name resolve order = wins host bcast
restrict anonymous = 2
kerberos method = secrets and keytab
dedicated keytab file = /etc/krb5.keytab
wins server = 192.168.0.24
client ipc signing = auto
winbind nss info = rfc2307
idmap_ldb:use rfc2307 = yes
vfs objects = shadow_copy2 catia fruit qnap_macea streams_depot

As I want to keep things the same as much as possible across all devices I changed the idmap entries here to use the ad backend and set the range the same as the other servers.

There are some settings that should not be used and are being removed. The winbind use default domain = yes entry essentially converts any unknown domain into a known domain. This is bad for security but it did save some issues with my helpers mis-keying the logon credentials during the changing of 30 desktop machines.

I also edited the smb.sh init script to alter some of those hard coded configuration settings and I edited the uLinux.conf file for some configuration settings. The uLinux.conf file is used by the smb.sh init script.

I still have to go back and fill in the missing attributes in the AD-DC and then make changes to allow for some other functionality. I still need to get my email servers to use the AD-DC to lookup the mailHost, validate user credentials, and lookup valid email addresses, all of which is currently done via LDAP.

In the old LDAP setup every user had at least 2 email addresses, some have many more. I have to figure out how to get this information into the AD-DC and how do I manage it via Microsoft’s management tools.

Now I have much more reading, and experimenting, to do …

Bookmark the permalink.

Comments are closed.