lists.arthurdejong.org
RSS feed

Newbie questions: knowledge of login procedure in general and configuration of nss-pam-ldapd for Acive Directory

[Date Prev][Date Next] [Thread Prev][Thread Next]

Newbie questions: knowledge of login procedure in general and configuration of nss-pam-ldapd for Acive Directory




Dear Arthur, dear list,


I am challenged with the task of integrating a bunch of diskless Linux clients into an already set-up and working Active Directory domain. Before I started to work on this topic two weeks ago I never had to work with PAM, LDAP or AD. So before I begin to talk about the specifics of my setup, I'd like to show what I found out about Linux's login and authentication mechanism. Please confirm or correct what little knowledge I earned.


If a user tries to sign into his account, either in text or graphical mode, the corresponding piece of software ("login" in text, "gdm, kdm, xdm,..." in graphics mode) uses PAM's "auth" sections to authenticate the user with his credentials (typically username and password). PAM itself uses the name service switch (NSS) functions provided by glibc to discover where the user account informations are located. NSS is configured by /etc/nsswitch.conf while PAM's configuration is in /etc/pam.conf and in /etc/pam.d/* . If the user's credentials match the ones in the account informations, then PAM executes it's "account" section to check if the user's password has expired and other stuff that relates to whether the user is allowed to sign on. On success PAM then executes it's "session" section that performs actions like mounting the user's home directory. PAM then returns to the login software which then starts a shell or a X server and window manager.

I'm not quiet sure about the order in which these tasks are executed so perhaps one of you could bring light into the dark. What I know is that PAM and NSS talk to each other; in case /etc/passwd, /etc/shadow and /etc/group are used (nsswitch.conf: passwd files, shadow files, group files), PAM uses glib functions to read these files.

I have no clue how this is with LDAP. Why do you need both a PAM and a NSS module? Wouldn't it suffice if NSS would communicate with an LDAP server if configured in nsswitch.conf?

The way I think it works with LDAP is: the PAM/NSS combination talks to nslcd, which caches authentication and account information. nslcd even maps attribute names if configured correspondingly. nslcd then asks the LDAP server for the required information and passes them back to PAM/NSS.


This is how I think works the login process in Linux. I appreciate every correction. Now lets move on to my special situation:

I have a 3/4 working configuration that allows logging in using an Active Directory domain controller. I'm using Ubuntu 10.04.3 LTS Desktop as client and nss-pam-ldapd (which is devided into libpam-ldapd, libnss-ldapd and nslcd). My configs are:

/etc/nsswitch.conf:
passwd:         files ldap
group:          files ldap
shadow:         files ldap

/etc/nslcd.conf:
uid nslcd
gid nslcd
uri ldaps://adserv03.xxxx.de
base dc=xxxx,dc=de
ldap_version 3
binddn cn=ldapquery,ou=ServiceAccounts,dc=xxxx,dc=de
bindpw xxxxxxxxxx
bind_timelimit 60
timelimit 60
tls_reqcert try
tls_cacertfile /etc/ssl/certs/ca-certificates.crt
scope sub
filter passwd (&(objectClass=user)(!(objectClass=computer))(uidNumber=*))
map     passwd      uid                 sAMAccountName
map passwd gidNumber primaryGroupID <- I know that this is one of my problems, see below
map     passwd      gecos               displayName
map passwd homeDirectory "${unixHomeDirectory:-/home/$sAMAccountName}" filter shadow (&(objectClass=user)(!(objectClass=computer))(uidNumber=*))
map     shadow      uid                 sAMAccountName
map     shadow      shadowLastChange    pwdLastSet
filter  group       (objectClass=group)
map     group       uniqueMember        member

/etc/pam.d/* was configured during installation of the packages and wasn't changed since.


Why do I map primaryGroupID to gidNumber instead of gidNumber? Well, I work at a university where there are about 50.000 user entries in the AD. While the uidNumber attribute can easily be filled uniquely by the identity management system, it is much more complicated to have unique gidNumber attributes. The problem is that each institute is allowed to create groups, be it just for logical partitioning, for licence management, etc... and no chance to convice the AD admins to use the posixGroup attributes. They even aren't sure if it could be automated to assign a gidNumber to existing or newly created groups. And no ambitions to manually fill these fields.

So the idea was to use primaryGroupID which defaults to 513 aka "Domain User". The problem with this: a search for this "gid" won't return "Domain Users" or any other kind of information. Reason is that ADs use distinguished names to refer to a group or user:

- a user entry can have multiple "memberOf" attributes that contain DNs of the particular group
- group entries have a "member" attribute that holds a list of user DNs


So, what works and what doesn't?

I can log in using an Active Directory user. I get my home directory mounted using pam_mount. But I get the message "groups: cannot find name for group ID 513".

This is a log from running nslcd -d and trying to login:


nslcd: DEBUG: add_uri(ldaps://adserv03.xxxx.de)
nslcd: DEBUG: ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT,4)
nslcd: DEBUG: ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE,"/etc/ssl/certs/ca-certificates.crt")
nslcd: version 0.7.2 starting
nslcd: DEBUG: setgroups(0,NULL) done
nslcd: DEBUG: setgid(123) done
nslcd: DEBUG: setuid(115) done
nslcd: accepting connections
nslcd: [8b4567] DEBUG: connection from pid=2341 uid=0 gid=0
nslcd: [8b4567] DEBUG: nslcd_pam_authc("ac107767","","login","***")
nslcd: [8b4567] DEBUG: myldap_search(base="dc=xxxx,dc=de", filter="(&(&(objectClass=user)(!(objectClass=computer))(uidNumber=*))(sAMAccountName=ac107767))")
nslcd: [8b4567] DEBUG: ldap_initialize(ldaps://adserv03.xxxx.de)
nslcd: [8b4567] DEBUG: ldap_set_rebind_proc()
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)
nslcd: [8b4567] DEBUG: ldap_simple_bind_s("cn=ldapquery,ou=ServiceAccounts,dc=xxxx,dc=de","*****") (uri="ldaps://adserv03.xxxx.de")
nslcd: [8b4567] connected to LDAP server ldaps://adserv03.xxxx.de
nslcd: [8b4567] DEBUG: ldap_initialize(ldaps://adserv03.xxxx.de)
nslcd: [8b4567] DEBUG: ldap_set_rebind_proc()
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,60)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [8b4567] DEBUG: ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)
nslcd: [8b4567] DEBUG: ldap_simple_bind_s("CN=EE8C9BF4-3E78-DD11-9C85-005056A46000,OU=users,DC=xxxx,DC=de","*****") (uri="ldaps://adserv03.xxxx.de")
nslcd: [8b4567] connected to LDAP server ldaps://adserv03.xxxx.de
nslcd: [8b4567] DEBUG: myldap_search(base="CN=EE8C9BF4-3E78-DD11-9C85-005056A46000,OU=users,DC=xxxx,DC=de", filter="(&(objectClass=user)(!(objectClass=computer))(uidNumber=*))")
nslcd: [8b4567] DEBUG: ldap_unbind()
nslcd: [7b23c6] DEBUG: connection from pid=704 uid=0 gid=0
nslcd: [7b23c6] DEBUG: nslcd_group_bygid(513)
nslcd: [7b23c6] DEBUG: myldap_search(base="dc=xxxx,dc=de", filter="(&(objectClass=group)(gidNumber=513))")
nslcd: [7b23c6] DEBUG: ldap_initialize(ldaps://adserv03.xxxx.de)
nslcd: [7b23c6] DEBUG: ldap_set_rebind_proc()
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,60)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,60)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,60)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [7b23c6] DEBUG: ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)
nslcd: [7b23c6] DEBUG: ldap_simple_bind_s("cn=ldapquery,ou=ServiceAccounts,dc=xxxx,dc=de","*****") (uri="ldaps://adserv03.xxxx.de")
nslcd: [7b23c6] connected to LDAP server ldaps://adserv03.xxxx.de
nslcd: [3c9869] DEBUG: connection from pid=2341 uid=0 gid=0
nslcd: [3c9869] DEBUG: nslcd_group_bygid(513)
nslcd: [3c9869] DEBUG: myldap_search(base="dc=xxxx,dc=de", filter="(&(objectClass=group)(gidNumber=513))")
nslcd: [3c9869] DEBUG: ldap_initialize(ldaps://adserv03.xxxx.de)
nslcd: [3c9869] DEBUG: ldap_set_rebind_proc()
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,60)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,60)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,60)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [3c9869] DEBUG: ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)
nslcd: [3c9869] DEBUG: ldap_simple_bind_s("cn=ldapquery,ou=ServiceAccounts,dc=xxxx,dc=de","*****") (uri="ldaps://adserv03.xxxx.de")
nslcd: [3c9869] connected to LDAP server ldaps://adserv03.xxxx.de
nslcd: [7b23c6] DEBUG: ldap_result(): end of results
nslcd: [3c9869] DEBUG: ldap_result(): end of results
nslcd: [334873] DEBUG: connection from pid=2341 uid=0 gid=0
nslcd: [334873] DEBUG: nslcd_pam_sess_o("ac107767","CN=EE8C9BF4-3E78-DD11-9C85-005056A46000,OU=users,DC=xxxx,DC=de","login","/dev/tty4","","")
nslcd: [b0dc51] DEBUG: connection from pid=2341 uid=0 gid=513
nslcd: [b0dc51] DEBUG: nslcd_group_bymember(ac107767)
nslcd: [b0dc51] DEBUG: myldap_search(base="dc=xxxx,dc=de", filter="(&(&(objectClass=user)(!(objectClass=computer))(uidNumber=*))(sAMAccountName=ac107767))")
nslcd: [b0dc51] DEBUG: ldap_initialize(ldaps://adserv03.xxxx.de)
nslcd: [b0dc51] DEBUG: ldap_set_rebind_proc()
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,60)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,60)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,60)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [b0dc51] DEBUG: ldap_set_option(LDAP_OPT_X_TLS,LDAP_OPT_X_TLS_HARD)
nslcd: [b0dc51] DEBUG: ldap_simple_bind_s("cn=ldapquery,ou=ServiceAccounts,dc=xxxx,dc=de","*****") (uri="ldaps://adserv03.xxxx.de")
nslcd: [b0dc51] connected to LDAP server ldaps://adserv03.xxxx.de
nslcd: [b0dc51] DEBUG: myldap_search(base="dc=xxxx,dc=de", filter="(&(objectClass=group)(|(memberUid=ac107767)(member=CN=EE8C9BF4-3E78-DD11-9C85-005056A46000,OU=users,DC=xxxx,DC=de)))") nslcd: [b0dc51] group entry CN=addrBookUsers,OU=Users,OU=IuK-IS,DC=xxxx,DC=de does not contain gidNumber value
nslcd: [b0dc51] DEBUG: ldap_result(): end of results
nslcd: [495cff] DEBUG: connection from pid=2341 uid=0 gid=513
nslcd: [495cff] DEBUG: nslcd_pam_sess_c("ac107767","CN=EE8C9BF4-3E78-DD11-9C85-005056A46000,OU=users,DC=xxxx,DC=de","login",12345)
nslcd: [7b23c6] DEBUG: ldap_unbind()
nslcd: [495cff] DEBUG: ldap_unbind()
nslcd: [3c9869] DEBUG: ldap_unbind()
nslcd: [b0dc51] DEBUG: ldap_unbind()
nslcd: caught signal SIGTERM (15), shutting down
nslcd: version 0.7.2 bailing out


I know the problem comes from the different behavior from Windows and Linux, using DNs vs. numerical IDs to identify users, groups and their assignment. But it's not in my power to make the admins use gidNumber and corresponding attributes. I would be grateful if someone had an idea how to solve this dilemma. My other possibility would be to use Samba's winbind to achieve an artificial mapping for the gids. But I think this would be a dirty solution as it is in each admin's hand to configure the bias that winbind uses to calculate uids and gids. And as most admins would keep the default, that would result in different groups having the same gid.


If you followed this mail to it's end, I'd like to thank you for your patience. I hope I didn't forget any information that you could need to help me.


Thank you,

        Uwe Sauter
--
To unsubscribe send an email to
nss-pam-ldapd-users-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/nss-pam-ldapd-users/