Configuring Solaris 11 to use Active Directory accounts as unix accounts
Configuring Solaris 11 to use Active Directory accounts as unix accounts
How to
- Configure Active directory to serve unix (RFC2307) data over LDAP,
- Configure Solaris 11 to use this as a source of user accounts, with simple LDAP binds instead of Kerberos for authentication
Goal:
- Allow certain active directory users to be local unix users
- Avoid Kerberos complexity
- Allow unix users to login using password OR ssh keys.
Environment:
- Windows 2008 Active Directory
- Solaris 11 Client
Windows 2003 seems similar from various bits of documentation and should be very similar, as is solaris 10, but that's not what I've used here.
Active Directory:
This is a quick summary of steps. Other people have written this up better than I have, for example here: http://blog.scottlowe.org/2007/04/25/solaris-10-ad-integration-version-3/
Or here with http://www.seedsofgenius.net/solaris/solaris-authentication-login-with-active-directory
Install "Identity Management for Unix" Server Role on your AD Controllers:
Open Server Manager,
- click "Roles" on the left
- click "Add role services" on the right hand side
- select "server for network information services" and "administration tools"
Open the "Identity Management for Unix" program under administrative tools, then create a new NIS domain.
Populate Unix attributes on the relevant users
Now you need to populateunix related attributes -- uid, home directory (use /home/$uid ) etc under the unix tab of each user who should be able to log in.
Solaris:
Configuring active directory name service:
In this example:
- 10.1.1.21 and 10.1.1.22 are the active directory master servers
- "Unix Search User" is configured as a domain user (no need for administrator rights). You can get the user's LDAP DN using the
dsquery user -name Unix*
command - Customize the items in bold (at least)
Warning: this command will overwrite your nsswitch.conf file!
ldapclient manual \
-a authenticationMethod=simple \
-a defaultSearchBase=DC=domain,DC=name,DC=local \
-a credentialLevel=proxy \
-a proxyDN="cn=Unix LDAP Search,ou=users,DC=domain,DC=name,DC=local" \
-a domainName=domain.name.local \
-a proxyPassword=secret123 \
-a defaultSearchScope=sub \
-a attributeMap=passwd:gecos=cn \
-a attributeMap=passwd:homedirectory=unixHomeDirectory \
-a attributeMap=shadow:userpassword=unixUserPassword \
-a objectClassMap=group:posixGroup=group \
-a objectClassMap=passwd:posixAccount=user \
-a objectClassMap=shadow:shadowAccount=user \
-a serviceSearchDescriptor=passwd:ou=users,DC=domain,DC=name,DC=local?sub \
-a serviceSearchDescriptor=group:ou=Unix\ Groups,DC=domain,DC=name,DC=local?sub \
-a defaultServerList="10.1.1.21 10.1.1.22"
Using this data in the name service switch:
Add "ldap" to your "passwd" and "group" map lookups. Here's my file:
passwd: files ldap
group: files ldap
hosts: files dns
ipnodes: files dns
networks: files
protocols: files
rpc: files
ethers: files
netmasks: files
bootparams: files
publickey: files
netgroup: files
automount: files
aliases: files
services: files
printers: user files
project: files
auth_attr: files
prof_attr: files
tnrhtp: files
tnrhdb: files
sudoers: files
Apply with:
svcadm restart name-service/switch svcadm restart name-service/cache
Verify it's working
At this point, users should be in the passwd database (as if they were in the local /etc/passwd file), but they won't be able to log in because we haven't setup the PAM configuration yet.
On solaris, run getent passwd
and you should see LDAP related entries.
If you need to tweak anything, remember to restart the name service cache.
Configure PAM to use LDAP binds
Here's my /etc/pam.conf (it could just as easily be multiple files in /etc/pam.d/*)
#
# Sourced from http://docs.oracle.com/cd/E23824_01/html/821-1455/schemas-250.html#scrolltoc
# on 28 NOV 2012
#
# Authentication management
#
# login service (explicit because of pam_dial_auth)
#
login auth requisite pam_authtok_get.so.1
login auth required pam_dhkeys.so.1
login auth required pam_unix_cred.so.1
login auth required pam_dial_auth.so.1
login auth binding pam_unix_auth.so.1 server_policy
login auth required pam_ldap.so.1
#
# SSH public key shoudn't check LDAP/AD account lock status, but should use it
# for uid/home dir etc (pam_unix*)
#
sshd-pubkey auth requisite pam_authtok_get.so.1
sshd-pubkey auth required pam_dhkeys.so.1
sshd-pubkey auth required pam_unix_cred.so.1
sshd-pubkey auth required pam_unix_auth.so.1
sshd-pubkey auth required pam_dial_auth.so.1
sshd-pubkey account requisite pam_roles.so.1
sshd-pubkey account required pam_unix_account.so.1
#
# rlogin service (explicit because of pam_rhost_auth)
#
rlogin auth sufficient pam_rhosts_auth.so.1
rlogin auth requisite pam_authtok_get.so.1
rlogin auth required pam_dhkeys.so.1
rlogin auth required pam_unix_cred.so.1
rlogin auth binding pam_unix_auth.so.1 server_policy
rlogin auth required pam_ldap.so.1
#
# rsh service (explicit because of pam_rhost_auth,
# and pam_unix_auth for meaningful pam_setcred)
#
rsh auth sufficient pam_rhosts_auth.so.1
rsh auth required pam_unix_cred.so.1
rsh auth binding pam_unix_auth.so.1 server_policy
rsh auth required pam_ldap.so.1
#
# PPP service (explicit because of pam_dial_auth)
#
ppp auth requisite pam_authtok_get.so.1
ppp auth required pam_dhkeys.so.1
ppp auth required pam_dial_auth.so.1
ppp auth binding pam_unix_auth.so.1 server_policy
ppp auth required pam_ldap.so.1
#
# Default definitions for Authentication management
# Used when service name is not explicitly mentioned for authentication
#
other auth required pam_authtok_get.so.1
other auth required pam_dhkeys.so.1
other auth required pam_unix_cred.so.1
other auth binding pam_unix_auth.so.1 server_policy
other auth required pam_ldap.so.1
#
# passwd command (explicit because of a different authentication module)
#
passwd auth binding pam_passwd_auth.so.1 server_policy
passwd auth required pam_ldap.so.1
#
# cron service (explicit because of non-usage of pam_roles.so.1)
#
cron account required pam_unix_account.so.1
#
# Default definition for Account management
# Used when service name is not explicitly mentioned for account management
#
other account requisite pam_roles.so.1
other account binding pam_unix_account.so.1 server_policy
other account required pam_ldap.so.1
#
# Default definition for Session management
# Used when service name is not explicitly mentioned for session management
#
other session required pam_unix_session.so.1
#
# Default definition for Password management
# Used when service name is not explicitly mentioned for password management
#
other password required pam_dhkeys.so.1
other password requisite pam_authtok_get.so.1
other password requisite pam_authtok_check.so.1
other password required pam_authtok_store.so.1 server_policy
#
# Support for Kerberos V5 authentication and example configurations can
# be found in the pam_krb5(5) man page under the "EXAMPLES" section.
#
Configure PAM to allow SSH key logins while LDAP is enabled
You may have noticed that the pam.conf file above has a non-LDAP configuration for the sshd-pubkey service. This is because it seems that the default ("other") PAM service will use the ldap PAM module which attempts to confirm an account isn't locked. This isn't possible when authenticating with a simple LDAP bind, because the SSH daemon doesn't have access to the user's password and therefore can't verify whether the user's account is locked.
See the "sshd-pubkey" lines in the example above.
Site note: Oracle's documentation claims this isn't possible, but it works fine just fine -- however there is a compromise: if you lock a user account they will still be able to log in using SSH keys!
Automatic Home Directory creation
Full credit: this is based on the following blog post: http://znogger.blogspot.com.au/2010/05/solaris-automatic-creation-of-home-dirs.html
Solaris' automounter has a feature called "Executable maps" -- we can specify a shell script which will create a directory on the access attempt. Here it is:
#!/bin/bash #
Automounter executable script.
This script must be referenced in file /etc/auto_master in order
to have any effect. Furthermore it must have the sticky bit set.
#
This script receives as $1 the name of the object (file or directory)
that is being accessed under the moint point. For example if the
moint point is /home and someone is accessing /home/johndoe then
$1 will be "johndoe".
The script is expected to write the path of the physical location
on stdout.
------------------------------------------------------------------------------
Customizations
Path of our mount point. This must be the same as the name
in the first column in the file /etc/auto_master.
HOMEDIRPATH=/home
Where the physical user home directories are
PHYSICALDIRPATH=/export/home
The group owner to give to a user's home directory
HOMEDIRGROUP="staff"
------------------------------------------------------------------------------
hdir=$HOMEDIRPATH/$1
Sanity check
getent passwd $1 > /dev/null if [ $? -ne 0 ]; then exit fi
Now we know that $1 is a valid user with a home directory
under $HOMEDIRPATH
Next see if the user's physical home dir exist. If not create it.
phdir="$PHYSICALDIRPATH/$1"
if [ -d "$phdir" ]; then
Yes the user's physical home dir already exist.
Return the path of the physical home dir to the automounter
and exit.
echo "localhost:$phdir" exit fi
cp -r /etc/skel/ $phdir/
Set owner and group
chown -R "$1":"$HOMEDIRGROUP" $phdir
Return the path of the physical home dir to the automounter
and exit.
echo "localhost:$phdir"
exit
This script needs to be used by /etc/auto_master -- here's mine:
cat > /etc/auto_master << HOMEEOF #
Copyright (c) 1992, 2011, Oracle and/or its affiliates. All rights reserved.
#
Master map for automounter
# +automaster /net -hosts -nosuid,nobrowse /home /etc/autohomedir /nfs4 -fedfs -ro,nosuid,nobrowse
HOMEEOF
Don't forget to put a sensible .bash_profile and .bashrc into /etc/skel