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