20050104 Tuesday January 04, 2005

Debugging PAM in Native LDAP (Part 1)

Native LDAP PAM example:

Here is a commented debug of a successful “su – test1” operation where Password Management is implemented in the Directory and Secure Shell is configured for PAM and group authorization


# PAM configuration
#
# Authentication management
#
# ssh config
#
sshd    auth    sufficient      pam_ldap.so.1 debug
sshd    auth    required        pam_unix.so.1 try_first_pass
#
# 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_dial_auth.so.1
login  auth     binding   pam_unix_auth.so.1 server_policy
login  auth     required  pam_ldap.so.1 use_first_pass
#
# 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     binding    pam_unix_auth.so.1 server_policy
rlogin  auth     required   pam_ldap.so.1 use_first_pass
#
# 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_auth.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 use_first_pass
#
# Default definitions for Authentication management # Used when service
name is not explicitly mentioned for authentication #
other   auth requisite          pam_authtok_get.so.1
other   auth required           pam_dhkeys.so.1
other   auth binding            pam_unix_auth.so.1 server_policy
other   auth required           pam_ldap.so.1 use_first_pass
#
# 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 use_first_pass
#
# cron service (explicit because of non-usage of pam_roles.so.1) #
cron    account required        pam_projects.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  required  pam_projects.so.1
other  account  binding   pam_unix_account.so.1 server_policy
other  account  required  pam_ldap.so.1 use_first_pass 
# 
# 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 (uncomment to use Kerberos)

#
#rlogin         auth optional           pam_krb5.so.1 try_first_pass
#login          auth optional           pam_krb5.so.1 try_first_pass
#other          auth optional           pam_krb5.so.1 try_first_pass
#cron           account optional        pam_krb5.so.1
#other          account optional        pam_krb5.so.1
#other          session optional        pam_krb5.so.1
#other          password optional       pam_krb5.so.1 try_first_pass

In the following debug output, the standard text is from /var/adm/messages, the italicized text are inline comments and the indented text is derived from the Solaris MAN pages


PAM[23983]: pam_start(su,test1,23230:26f60) - debug = 17

pam_start():

service, user, conversation structure (pam_conv): PAM handle for subsequent calls (pamh)


The pam_start() function is called to initiate an authentication transaction. pam_start() takes as arguments the name of the current service, service, the name of the user to be authenticated, user, the address of the conversation structure, pam_conv, and the address of a variable to be assigned the authentication handle pamh. Upon successful completion, pamh refers to a PAM handle for use with subsequent calls to the authentication library.

The pam_conv structure contains the address of the conversation function provided by the application. The underlying PAM service module invokes this function to output information to and retrieve input from the user.


pam_start() service=su, user=test1, pam_conv= 23230, pamh= 26f60

Nov 18 13:26:09 ldapserver su[23983]: [ID 418019 local6.debug]
PAM[23983]: pam_set_item(26f60:service)=su

pam_set_item() handle, item type, item


The pam_get_item() and pam_set_item() functions allow applications and PAM service modules to access and to update PAM information as needed. The information is specified by item_type, and can be one of the following:

PAM_SERVICE: The service name.

PAM_USER: The user name.

PAM_AUTHTOK: The user authentication token.

PAM_OLDAUTHTOK: The old user authentication token.

PAM_TTY: The tty name.

PAM_RHOST: The remote host name.

PAM_RUSER: The remote user name.

PAM_CONV: The pam_conv structure.

PAM_USER_PROMPT: The default prompt used by pam_get_user()

the variable handle is the pamh value from pam_start()

the variable item is the raw data


pam_set_item() service=su

Nov 18 13:26:09 ldapserver su[23983]: [ID 418019 local6.debug]
PAM[23983]: pam_set_item(26f60:user)=test1

pam_set_item() user=test1

Nov 18 13:26:09 ldapserver su[23983]: [ID 418016 local6.debug]
PAM[23983]: pam_set_item(26f60:conv)=12618

pam_set_item() conv=12618

Nov 18 13:26:09 ldapserver su[23983]: [ID 393443 local6.debug]
PAM[23983]: pam_get_item(26f60:service)=su

pam_get_item() service=su

Nov 18 13:26:09 ldapserver su[23983]: [ID 418019 local6.debug]
PAM[23983]: pam_set_item(26f60:tty)=/dev/pts/4

pam_set_item() tty=/dev/pts/4

Nov 18 13:26:09 ldapserver su[23983]: [ID 418019 local6.debug]
PAM[23983]: pam_set_item(26f60:rhost)=ldapserver

pam_set_item() rhost=ldapserver

Nov 18 13:26:09 ldapserver su: [ID 473974 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0)

pam_authenticate() (pamh, flags)

The pam_authenticate() function is called to authenticate the current user. The user is usually required to enter a password or similar authentication token depending upon the authentication service configured within the system. The user in question should have been specified by a prior call to pam_start() or pam_set_item().


pam_authenticate() pamh=26f60 flags=0

Nov 18 13:26:09 ldapserver su: [ID 472425 local6.debug] PAM[23983]:
load_modules(26f60,pam_sm_authenticate)
/usr/lib/security/pam_authtok_get.so.1
Nov 18 13:26:09 ldapserver su: [ID 899501 local6.debug] PAM[23983]:
load_function: successful load of pam_sm_authenticate

pam_sm_authenticate is invoked by pam_authenticate 
library pam_authtok_get.so.1 loaded from module “stack”

Nov 18 13:26:09 ldapserver su: [ID 472425 local6.debug] PAM[23983]:
load_modules(26f60,
pam_sm_authenticate)=/usr/lib/security/pam_dhkeys.so.1
Nov 18 13:26:09 ldapserver su: [ID 899501 local6.debug] PAM[23983]:
load_function: successful load of pam_sm_authenticate

pam_sm_authenticate is invoked by pam_authenticate 
library pam_dhkeys.so.1 loaded from module “stack”

Nov 18 13:26:09 ldapserver su: [ID 472425 local6.debug] PAM[23983]:
load_modules(26f60,
pam_sm_authenticate)=/usr/lib/security/pam_unix_auth.so.1
Nov 18 13:26:09 ldapserver su: [ID 899501 local6.debug] PAM[23983]:
load_function: successful load of pam_sm_authenticate

pam_sm_authenticate is invoked by pam_authenticate 
library pam_unix_auth.so.1 loaded from module “stack”

Nov 18 13:26:09 ldapserver su: [ID 472425 local6.debug] PAM[23983]:
load_modules(26f60, pam_sm_authenticate)=/usr/lib/security/pam_ldap.so.1
Nov 18 13:26:09 ldapserver su: [ID 899501 local6.debug] PAM[23983]:
load_function: successful load of pam_sm_authenticate

pam_sm_authenticate is invoked by pam_authenticate 
library security/pam_ldap.so.1 loaded from module “stack”

Currently the libraries loaded into the module stack are as follows:

pam_authtok_get.so.1

pam_dhkeys.so.1

pam_unix_auth.so.1

pam_ldap.so.1

familiar? Look at the “other” authentication stack in the pam.conf above


Nov 18 13:26:09 ldapserver su: [ID 358027 local6.debug] PAM[23983]:
pam_get_user(26f60, 61746500, NULL)

The pam_get_user() function is used by PAM service modules to retrieve the current user name from the PAM handle. If the user name has not been set with pam_start() or pam_set_item(), the PAM conversation function will be used to prompt the user for the user name with the string "prompt".


pam_get_user (pamh=26f60)

Nov 18 13:26:09 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:user)=test1

pam_get_item() pamh, item_type, item


The pam_get_item() and pam_set_item() functions allow applications and PAM service modules to access and to update PAM information as needed. The information is specified by item_type, and can be one of the following:

    PAM_SERVICE - The service name.
    PAM_USER - The user name.
    PAM_AUTHTOK -The user authentication token.
    PAM_OLDAUTHTOK -The old user authentication token.
    PAM_TTY - The tty name.
    PAM_RHOST - The remote host name.
    PAM_RUSER - The remote user name.
    PAM_CONV - The pam_conv structure.
    PAM_USER_PROMPT - The default prompt used by pam_get_user().

The pam_set_item() function is passed the authentication handle, pamh, returned by pam_start(), a pointer to the object, item, and its type, item_type. If successful, pam_set_item() copies the item to an internal storage area allocated by the authentication module and returns PAM_SUCCESS. An item that had been previously set will be overwritten by the new value.

    The object data is valid until modified by a subsequent call to pam_set_item() for the same item_type, or unless it is modified by any of the underlying service modules. If the item has not been previously set, pam_get_item() returns a null pointer. An item retrieved by pam_get_item() should not be modified or freed. The item will be released by pam_end().


pam_get_item() user=test1


Nov 18 13:26:09 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:authtok)=NULL

pam_get_item() authtok=NULL


Nov 18 13:26:09 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:repository)=NULL

pam_get_item() repository=NULL


Nov 18 13:26:09 ldapserver su: [ID 975208 local6.debug] PAM[23983]:
pam_get_data(26f60:pam_authtok_get)=PAM_NO_MODULE_DATA

pam_set_data (pamh, module_data_name, data, (cleanup) (pamh, data, pam_end_status)

The pam_set_data() and pam_get_data() functions allow PAM service modules to access and update module specific information as needed. These functions should not be used by applications.

The pam_set_data() function stores module specific data within the PAM handle pamh. The module_data_name argument uniquely identifies the data, and the data argument represents the actual data. The module_data_name argument should be unique across all services.

The cleanup function frees up any memory used by the data after it is no longer needed, and is invoked by pam_end(). The cleanup function takes as its arguments a pointer to the PAM handle, pamh, a pointer to the actual data, data, and a status code, pam_end_status. The status code determines exactly what state information needs to be purged.

If pam_set_data() is called and module data already exists from a prior call to pam_set_data() under the same module_data_name, then the existing data is replaced by the new data, and the existing cleanup function is replaced by the new cleanup function.

The pam_get_data() function retrieves module-specific data stored in the PAM handle, pamh, identified by the unique name, module_data_name. The data argument is assigned the address of the requested data. The data retrieved by pam_get_data() should not be modified or freed. The data will be released by pam_end().


pam_get_data() pam_authtok_get=PAM_NO_MODULE_DATA

Nov 18 13:26:09 ldapserver su: [ID 999781 local6.debug] PAM[23983]:
pam_set_data(26f60:pam_authtok_get)=2ab50

pam_set_data() pam_authtok_get=2ab50

Nov 18 13:26:09 ldapserver su: [ID 975208 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=PAM_NO_MODULE_DATA

pam_get_data()libpam=PAM_NO_MODULE_DATA

Nov 18 13:26:09 ldapserver su: [ID 999781 local6.debug] PAM[23983]:
pam_set_data(26f60:libpam)=2ab70

pam_set_data() libpam=2ab70

Nov 18 13:26:09 ldapserver su: [ID 393440 local6.debug] PAM[23983]:
pam_get_item(26f60:conv)=12618

pam_get_item() conv=12618

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:authtok)=NULL

pam_get_item() authtok=NULL

Nov 18 13:26:10 ldapserver su: [ID 418019 local6.debug] PAM[23983]:
pam_set_item(26f60:authtok)=********

pam_set_item() authtok=********

Nov 18 13:26:10 ldapserver su: [ID 975205 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=2ab70

pam_get_data() libpam=2ab70

Nov 18 13:26:10 ldapserver su: [ID 579194 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0): /usr/lib/security/pam_authtok_get.so.1
returned Ignore module

The pam_authtok_get service module provides password prompting funtionality to the PAM stack. It implements pam_sm_authenticate() and pam_sm_chauthtok(), providing functionality to both the Authentication Stack and the Password Management Stack.

The implementation of pam_sm_authenticate() prompts the user name if not set and then tries to get the authentication token from the pam handle. If the token is not set, it then prompts the user for a password and stores it in the PAM item PAM_AUTHTOK. This module is meant to be the first module on an authentication stack where users are to authenticate using a keyboard.


Since the root user is allowed to “su -” to any other user, no password is needed.
pam_authenticate(): pam_authtok_get.so.1 returned Ignore module

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:user)=test1

pam_get_item() user=test1

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:authtok)=********

pam_get_item() authtok=********

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:

pam_get_item() repository=NULL

Nov 18 13:26:10 ldapserver su: [ID 975205 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=2ab70

pam_get_data()libpam=2ab70

Nov 18 13:26:10 ldapserver su: [ID 579194 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0): /usr/lib/security/pam_dhkeys.so.1 returned
Ignore module

The pam_dhkeys.so.1 service module provides functionality to two PAM services: Secure RPC authentication and Secure RPC authentication token management.

Secure RPC authentication differs from regular unix authentication because NIS+ and other ONC RPCs use Secure RPC as the underlying security mechanism.


Secure RPC is not used.
pam_authenticate()pam_dhkeys.so.1 returned Ignore module

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:user)=test1

pam_get_item() user=test1

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:authtok)=********

pam_get_item() authtok=********

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:repository)=NULL

pam_get_item() repository=NULL

Nov 18 13:26:10 ldapserver su: [ID 975205 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=2ab70

pam_get_data() libpam=2ab70

Nov 18 13:26:10 ldapserver su: [ID 579194 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0): /usr/lib/security/pam_unix_auth.so.1
returned Ignore module

The pam_unix_auth module implements pam_sm_authenticate(), which provides functionality to the PAM authentication stack. It provides functions to verify that the password contained in the PAM item PAM_AUTHTOK is the correct password for the user specified in the item PAM_USER. If PAM_REPOSITORY is specified, then user's passwd is fetched from that repository. Otherwise the default nsswitch.conf repository is searched for that user.


pam_authenticate() pam_unix_auth.so.1 returned Ignore module

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:service)=su

pam_get_item() service=su

Nov 18 13:26:10 ldapserver su: [ID 358027 local6.debug] PAM[23983]:
pam_get_user(26f60, 0, NULL)

pam_get_user(pamh=26f60)

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:user)=test1

pam_get_item() user=test1

Nov 18 13:26:10 ldapserver su: [ID 393440 local6.debug] PAM[23983]:
pam_get_item(26f60:conv)=12618

pam_get_item() conv=12618

Nov 18 13:26:10 ldapserver su: [ID 393443 local6.debug] PAM[23983]:
pam_get_item(26f60:authtok)=********

pam_get_item() authtok=********

Nov 18 13:26:11 ldapserver su: [ID 975205 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=2ab70

pam_get_data() libpam=2ab70

Nov 18 13:26:11 ldapserver su: [ID 579194 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0): /usr/lib/security/pam_ldap.so.1 returned
Success

Holy Cow!
pam_authenticate(): pam_ldap.so.1 returned Success

Nov 18 13:26:11 ldapserver su: [ID 975205 local6.debug] PAM[23983]:
pam_get_data(26f60:libpam)=2ab70

pam_get_data() libpam=2ab70

Nov 18 13:26:11 ldapserver su: [ID 560004 local6.debug] PAM[23983]:
pam_authenticate(26f60, 0): final: Success

( Jan 04 2005, 11:36:40 PM CST ) Permalink Comments [0]
Trackback URL: http://blogs.sun.com/mike_webb/en_US/entry/debugging_pam_in_native_ldap
Comments:

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed