I’d like to detail the process I used to “migrate” from a Samba domain controller on my old server to a newer Samba domain controller on my new server. My goal was not to have to remake my Windows profiles, and this was pretty easy to achieve.
A few words on the software versions in play, and a bit about their interactions:
- Fedora Core 5 i386 (I learned my lesson: no more x86-64 for a while)
- Samba 3.0.23a (with a patch that will be in 3.0.23b to make SMB signing work right)
- libuser 0.54.5 (with a patch; see below)
- Fedora Directory Server (henceforth FDS) 1.0.2
- nss_ldap-249-1 (FC5 RPM name-version-release)
Samba is acting as a domain controller, of course, and is using FDS
(LDAP) as its passdb backend. The system uses nss_ldap to read users
and groups out of LDAP as well. libuser is in there because it turned
out to be the nicest and easiest way to manage system users, complete
with an interface almost exactly like Fedora’s (and so maybe slightly
different from everyone else’s) useradd and friends.
libuser is important for another reason: Samba’s add machine script
points to it:
add machine script = LIBUSER_CONF=/etc/libuser.conf.smb-machines
/usr/sbin/luseradd -n -g samba-machines -c Machine
-M -d /dev/null -s /sbin/nologin %u
(Indentation added to make it more readable.) The command is run with
sh -c so setting the LIBUSER_CONF environment variable as I’ve
done there works fine. libuser.conf.smb-machines differs from the
default libuser.conf in one way: it specifies to make accounts in
ou=Computers rather than ou=People. The rest of the stuff should
be self explanatory.
One catch: libuser needs the bind password for an LDAP user with
privileges to create a new user. By default, it lacks the ability to
store this password in the configuration file. This change is the
patch I added to libuser. I’m reluctant to distribute this patch
because I really didn’t audit it for security, or audit all of libuser
to see what impact that change might have, in fact. It seems to work
fine, even when regular users go to change their passwords with
lpasswd. The patch is nearly entirely trivial, and you can find
other people distributing similar patches besides. Just beware that
I’m not sure using libuser like that is a good idea. (Don’t forget to
make libuser.conf unreadable except by privileged users. It should
be safe (I think?) to make luseradd and friends setuid root, so that
they can read the configuration file.)
Of course, I could avoid a lot of this trouble by not adding machines automatically. Your choice; I chose automation.
The old Samba server was Samba 2.2. It was also using LDAP, but the
LDAP schemas seemed different enough that I didn’t bother to try doing
some kind of copy/port of the LDAP data from the old server to the new
one. Instead, I created the new domain as specified in the Samba
HOWTO. Then I took the old Samba domain SID (I forget how I got this
out; it might have required smbpasswd; answer was readily available
via Google) and input it into the new domain with net setdomainsid
(again, I think that’s how I put it in; either that or I put it in by
hand directly in LDAP).
I figured out the SIDs of the (two) users I wanted to copy by looking
in the registry: I believe a user’s SID is their key as found in
HKEY_USERS when they’re logged in (when their hive is loaded
automatically). I found one of the SIDs by manually loading the hive
as local Administrator and then looking at the permissions on the
hive. Since the SID wasn’t found, it showed me the SID instead of a
user name. Adding the users was a matter of calling luseradd to add
the system user, then smbpasswd -a to add the Samba object classes
to the user object, and finally overwriting the sambasid attribute
with the value I got from looking in the registry on one of the client
machines. I’ll note that the SID seems to be composed of the domain
SID followed by what is (or was?) known as the RID, the RID being a
single integer; i.e., everything up to the last hyphen is the domain
SID, and the number following the last hyphen is the RID.
To get the computers on the new domain was just a matter of leaving the domain (this seemed harder in XP: I had to reboot before I could rejoin, and it always wanted an Administrator login/password to attempt to remove the (non-existent) account from the domain as I removed the computer from the domain) and then rejoining it. This seemed like the easiest way to get the machine account created in the new LDAP server. Having the machine SID change seems to have caused no adverse effects.
Now, I suppose I could have just created a new domain with a new SID,
since I was rejoining the (two) computers anyway. I suppose that the
fact that user SIDs change wouldn’t be a huge deal either:
theoretically I just modify the ownership and ACLs on their local
profile to get the correct SID on the profile. (I don’t know about
the case where local users have installed software in system
directories; i.e., my girlfriend’s user owns C:Program FilesFoo or
something.) “Cloning the SID” didn’t seem very hard at all, though,
and it meant me having to deal with Windows less, so I’m happy.
I’m not yet certain about a few things involving passwords. For one
thing, changing them from Linux: I haven’t configured a way to change
passwords from PAM, I think. It appears that there is no PAM module
that can change an SMB password on a remote computer, yet, without
lots of configuration. pam_smbpass, which comes with Samba, seems to
require you to configure the LDAP passdb backend on each machine you
want to use it from, including setting the proper bind password and
all that jazz. I don’t believe pam_smb_auth supports password
changing of any kind. I wonder if it’s somehow impossible to have a
PAM module that, given the user name, password, and domain (that last
as part of its configuration), will go out and find a login server for
that domain and then perform the proper SMB rituals to change a
password. Doing the SMB part itself doesn’t seem like it should be
that hard: hopefully parts of Samba could be reused. In fact,
smbpasswd -r can already talk SMB to change your password, I
believe; it just doesn’t do the “automatically find a login server”
bit (which Samba itself does do, I believe). Anyway, that situation
of changing SMB passwords from PAM seems ugly. Further, I’m not sure
if password expiration can work. My workstations are authenticating
from LDAP currently, I believe, not SMB; if I set LDAP restrictions on
the password, and have told Samba to obey PAM restrictions, will
pam_ldap figure out what the LDAP server is requesting (i.e., a better
password, change your password because it has expired, etc.) and will
Samba be able to read that information? I think PAM specifies
interfaces for this kind of communication (i.e., some constants for
“password expired” and things like that).
One final note: when nscd is running I think it does a negative caching of smbd’s first lookup before it decides it needs to create a machine account when adding a machine to the domain. Explained a different way:
- smbd gets a request to add a machine ‘foo’ to the domain.
- smbd tries to retrieve the system user ID for ‘foo$’.
- nscd gets the request, looks it up in LDAP, and comes up empty.
- nscd caches the negative result before returning it to smbd.
- smbd creates the account.
- smbd tries to retrieve the system user ID for ‘foo$’.
- nscd returns the cached negative result.
- smbd, unable to get the user ID, bails.
The moral of the story: stop nscd before doing a machine add. This is
a bit annoying; perhaps I can tweak negative caching with nscd. Ooh,
looks like you can: negative-time-to-live for the passwd map in
/etc/nscd.conf. However, setting this to 0 or 1 still seems to
make it take at least a couple of seconds before it expires the
negative result and tries the lookup again. So despite my attempts to
automate, I either have to disable nscd (big performance hit in my
experience) or else remember to stop nscd before I add a machine to
the domain.