Samba and Active Directory

Much of this is covered in the howto on the samba wiki. Their method didn't quite work for me, but might work in your situation. Although I'm not going to be saying, "As the wiki says," all the time, most of this is, "As the wiki says."

As of Samba-4.0.3 in Fedora this has stopped working for me. If I solve it, I'll put it up here. I have only tried Fedora's version of samba-4.0.3 so don't know if it's a samba issue or Fedora issue. I've seen one other person with the problem on Fedora forums. Check this thread for some links but at present, I'd say install samba from the install DVD and don't upgrade.

In the examples, we'll have a domain called EXAMPLE.com. The Windows AD server will be called WINAD and the samba server will be called SAMSERV. The administrator account will have a password of 1234.

This was tested on CentOS 5.1, which is similar to RedHat Enterprise. Hopefully, the reader will be able to adjust it to their system. You should have samba, samba-common and samba-client installed.

CentOS has an /etc/init.d/smb script which will also start, stop and restart nmb. Winbind is run by a separate script. As there will be times you'll want to start, stop or restart all of them, the following simple script might be of use. I keep it in /usr/bin and call it samba.sh.
#!/bin/sh
CMD=$1
case $CMD in
start)
for i in smb winbind;do /etc/init.d/$i start; done;;
restart)
for i in smb winbind;do /etc/init.d/$i restart; done;;
stop)
for i in smb winbind;do /etc/init.d/$i stop; done;;
esac
exit 0

For the newcomer, if you'd like to use that script, just copy it to /usr/bin, name it samba.sh and make it executable.
chmod 700 /usr/bin/samba.sh

Doing chmod 700 means that only root can run it. You can also make it 750 or 755 if there are no security concerns.

Preparation

If samba and winbind are running, stop them for now. There's a bit of preparation to be done. In all these examples, case is important. If something is typed in UPPER CASE then imitate it.

We're going to use Kerberos for authentication. Edit your /etc/krb5.conf file. Change the sections for libdefaults, realms and domain_realm.
[libdefaults]
 default_realm = EXAMPLE.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 EXAMPLE.COM = {
  kdc = winad.example.com:88
  admin_server = winad.example.com:749
  default_domain = example.com
 }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM

Test it.
kinit administrator@EXAMPLE.COM

It should ask you for the password. Type the password for AD administrator and you should be back at a command prompt. Make sure you've gotten a ticket.
klist -5

You should see something like
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: administrator@EXAMPLE.COM

If you don't use smart cards you might get some error about not being able to open a pcscd file. (I've forgotten the details at this point.) I solved it by removing pkinit-nss and coolkey. We don't use smart cards, so I didn't need those programs.

Edit smb.conf. On CentOS it's located in /etc/samba.

In the [global] section add the domain name. The server string is what will be seen when viewed in Windows' My Network Places. For this example, we'll use AD Samba Server.
[global]
workgroup = EXAMPLE
server string = AD Samba Server

Further down, in the Domain Members Options section put the following
 security = ads 
 realm = EXAMPLE.COM
 winbind enum users = yes
 winbind enum groups = yes
 winbind use default domain = yes
 winbind separator = +
 idmap uid = 10000-20000
 idmap gid = 10000-20000
 template shell = /bin/false

The windbind enum users and groups will allow the getent command (covered below) to work correctly. It's definitely useful to make sure your nsswitch.conf, covered below, is working properly. Logins should work without it, and in a large domain, it can be resource intensive, as it goes through the entire list of users and groups in the AD. Right now, we have it in there for testing.

The winbind separater line means that instead of using EXAMPLE\john, user john will show as EXAMPLE+john. Most documentation suggests doing it this, I'm not really sure why, save for the possible confusion between / and \ between Unix and Windows. It will cause testparm to mention a possible problem, but that warning can be ignored.

windbind use default domain = yes means that when you list users and groups they won't have the EXAMPLE+ prefix. So, if we check users with getent as mentioned below, john will show up as john, rather that EXAMPLE+john.

The idmap entries set the range of user and group IDs for the Active Directory users. Make sure the starting values are higher than the user and group ids of any existing local users and groups. Leave some room for expansion. If the last entry in /etc/passwd is sue, with an ID of 800, start the AD uid list at 1000 or so.

Assuming that these users are only accessing shares on the samba server, we don't really want them to have a login shell, which is why we're using /bin/false as their shell. The [homes] section can look something like
[homes]
       comment = Home Directories
       browseable = no
       writable = yes
       valid users = %D+%S

The %D+%S is for Domain and share. (The smb.conf page calls %S service, which can be confusing. In this case, service means share.) The + is because we're using that winbind separator line. Otherwise, we'd use %D\%S, to imitate the standard Windows pattern of DOMAIN\share.

By default, these home directories will be created in /home/EXAMPLE/,e.g., /home/EXAMPLE/sue, /home/EXAMPLE/john, etc. If your users will have home directories on the samba server, create the parent directory.
mkdir /home/EXAMPLE

We'll also include a share. This will be for members of the AD sales unit. We can actually give it 777 permissions but only AD sales members will be able to use it. (Further refinement is possible with ACLs, but that is beyond the scope of this article.
[sales]
        path = /usr/testing
        valid users = @EXAMPLE+sales
        writeable = yes
        browseable = yes

This will allow all members of EXAMPLE AD sales group to have access to the sales directory. If you just wanted user john to have access, you can do EXAMPLE+john (without the @.) If it seems confusing, just remember that @ is for an entire group and we use the + sign in the way Windows usually uses \. So it would be similar to saying EXAMPLE\john can use this directory.

Run testparm to make sure you have no obvious syntax errors. As mentioned above, the + separator will give a warning message, but you can ignore that.

Startup samba and winbind. If you used my script then you can run
samba.sh start

Join the machine to Active Directory.
net ads join -U administrator

It should ask for the Active Directory administrative password.

Once this is done restart samba and winbind and run a few tests. In our example, we have an AD member named john, with a password of 2468.
net ads testjoin
wbinfo -u
wbinfo -g
wbinfo -a john%2468

net ads testjoin should show that joining the directory was OK.
wbinfo -u should give you a list of AD users and wbinfo -g should show a list of groups. (If you chose use default domain = no in smb.conf this might show as EXAMPLE+username, EXAMPLE+groupname.

wbinfo -a john%2468 should return something like
 plaintext password authentication succeeded
 challenge/response password authentication succeeded

Edit /etc/nsswitch.conf which tells the system what databases to use for various things. Look for three lines
 passwd:     files
 shadow:     files
 group:      files

Change them to
 passwd:     files winbind
 shadow:     files winbind 
 group:      files winbind

The order is important, make sure winbind comes after files or it will always check the AD password list. You don't want it doing that for local logins.

Check that that this is working
getent passwd

This should give you your /etc/passwd, followed by the AD users. You can do the same with groups
getent group

and see similar results.

Edit /etc/pam.d/system-auth.

One should use authconfig-tui and it should work. However, I've had experience with using authconfig-tui and finding that things don't work for some reason. Still, I would definitely try using authconfig-tui first, as it's always a bit risky to directly edit the system-auth file.

If using authconfig-tui, on the first screen check off Use Winbind, Use Kerebos, Use Winbind Authorization. (Sometimes, it doesn't work with Use Kerebos--if it doesn't, it can be removed the same way, with the authconfig-tui interface.)

To check off things, use the up and down arrows to get to a selection and hit the space bar--you will see an asterisk appear. To navigate to the next screen, use tab and when it highlights next (or whatever you choice may be), hit the space bar.

The next screen, as you've already edited krb5.conf should have your realm and KDC already filled in. (When done with authconfig-tui, it's good to recheck your krb5.conf, when finished. I've sometimes found that using authconfig-tui after manually editing krb5 puts in additional KDC listings, so that suddenly, I have three KDC=EXAMPLE.COM lines.)

In the next authconfig-tui screen, assuming you've edited smb.conf, it may already have security model as ads, the domain name and domain controller. (If not, fill them in. They should get written to /etc/smb.conf, so again, if you've already edited smb.conf, you might want to check for duplicate lines.)

It might also have the ADS Realm (our EXAMPLE.COM) and the template shell, both of which will also, if you fill them in again, be written to /etc/smb.conf.

Next you can choose join domain if you haven't already, and it will ask for the administrator password--if you just click OK, it will then restart winbind (and on Fedora, at least, nslcd).

The reader may wonder why I suggest first manually configuring krb5.conf and smb.conf. The answer is that I have, at least once or twice, found authconfig-tui to not do it properly, and as neither krb5.conf nor smb.conf require extensive editing, I prefer to do it by hand.

If things don't work, on CentOS, at least, I will, as mentioned above, now edit /etc/pam.d/system-auth. On CentOS, this is the only file that needs editing, I don't know about other systems. BE CAREFUL! Mess this up and you can lock yourself out of the system. First copy to it to something like /etc/pam.d/system-auth.bak. Also, open another session, where you're logged in as root. This way, you should be able to fix it if there are any problems. The following file works on CentOS-5.1
auth required /lib/security/$ISA/pam_env.so
auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok
auth sufficient /lib/security/$ISA/pam_winbind.so use_first_pass
auth required /lib/security/$ISA/pam_deny.so

account required /lib/security/$ISA/pam_unix.so
account sufficient /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet
account sufficient /lib/security/$ISA/pam_winbind.so use_first_pass
account required /lib/security/$ISA/pam_permit.so

password requisite /lib/security/$ISA/pam_cracklib.so retry=3 type=
password sufficient /lib/security/$ISA/pam_unix.so nullok use_authtok
md5 shadow
password sufficient /lib/security/$ISA/pam_winbind.so use_first_pass
password required /lib/security/$ISA/pam_deny.so

session required /lib/security/$ISA/pam_limits.so
session required /lib/security/$ISA/pam_unix.so
session required /lib/security/$ISA/pam_winbind.so use_first_pass

Save it and then open up another session, making sure that root can log in, a regular user can log in, anyone who can normally su to root can still do so and that any sudo rights that someone had still exist. If any of these cause a problem, the file can be replaced with that backup file you made. You might be able to do it from the session you're working with, but if not, you have that other root session open and can use that.

Hopefully, that won't be necessary. At this point, an AD member of the sales group should be able to access the shared sales directory we created.

One frequently sees posts that all these tests are working but the user still can't access the samba shares from Windows machines. We'll assume that user john has access to the sales share on SAMSERV. (Our samba server.) His AD password is 2468. On the samba machine run
smbclient //SAMSERV/sales -Ujohn%2468

If it comes back with something like bad password, there's a good chance that something is wrong with the valid users line or lines in smb.conf. You can try commenting valid user lines out and seeing if the command now works. (When it works, you should have the smb> prompt.) If it now works, see if the Windows users can access the share. If they can, then see if you made some sort of error with the valid user line. (You don't want to leave the valid user line commented out, as it would allow anyone to access the share.)

Hopefully, it will turn out to be a typo of some sort, for example, using / or \ instead of + in the @EXAMPLE+sales line.

Home directories

Home directories can be a problem. You can manually create them, then change ownership. Like share directories, if they're created with 777 permissions, only the user will be able to access it without a password, thanks to the valid user line we put in smb.conf. If only a few users need it, you can let them generate it on the fly by adding the following line to that /etc/pam.d/system-auth file. (Once again, take the same precautions you took before, of making a backup and having a root session open in another terminal.)
session required /lib/security/pam_mkhomedir.so
If that line exists, and you let the user log into the Linux box with their AD username and password, even though though their shell is /bin/false, it will create john's /home/EXAMPLE/john directory. If you then do a ls -l you'll see that it's owned by john with the group of domain users. (With the space, as shown.) So if you manually create user sue's directory, you would then do a chown like

chown sue:'domain users' /home/EXAMPLE/sue

If you decided to use default domain = no in /etc/samba/smb.conf you would use EXAMPLE+sue instead. (Which is also what would show for a ls -l).

Once one figures out the syntax, connecting samba to an AD domain is actually pretty straightforward.

The troubleshooting section at samba.org can often be helpful in finding errors.