Please, find attached PAM code from
linux/util-linux-2.10f/login-utils/login.c
file. This is User login procedure.
It works fine, except one major problem, which contradicts to PAM specification.
I use PAM module with remote user's database (LDAP, RADIUS, TACACS+)
retcode = pam_authenticate(pamh, 0);
retcode = pam_acct_mgmt(pamh, 0);
Authentication runs OK. Both functions above returned PAM_SUCCESS.
Great lets go further.
Would you, please, look at the following 3 lines of code
/* Grab the user information out of the password file for future usage
First get the username that we are actually using, though.
*/
retcode = pam_get_item(pamh, PAM_USER, (const void **) &username);
setpwent(); /* line 635 */
pwd = getpwnam(username); /* line 636 */
if (pwd) initgroups(username, pwd->pw_gid); /* line 637 */
If we use PAM module, how come we "Grab the user information out of the password file for future usage"
PAM doesn't have access to remote database, does it? It doesn't make any sense for me.
getpwnam() fails (user is unreachable), login fails as well.
I would appreciate clarification.
Best regards,
Leon
#ifdef USE_PAM
/* username is initialized to NULL
and if specified on the command line it is set.
Therefore, we are safe not setting it to anything
*/
retcode = pam_start("login",username, &conv, &pamh);
if(retcode != PAM_SUCCESS) {
}
/* hostname & tty are either set to NULL or their correct values,
depending on how much we know */
retcode = pam_set_item(pamh, PAM_RHOST, hostname);
PAM_FAIL_CHECK;
retcode = pam_set_item(pamh, PAM_TTY, tty);
PAM_FAIL_CHECK;
/* Andrew.Taylor@cal.montage.ca: Provide a user prompt to PAM
so that the "login: " prompt gets localized. Unfortunately,
PAM doesn't have an interface to specify the "Password: " string (yet). */
retcode = pam_set_item(pamh, PAM_USER_PROMPT, _("login: "));
PAM_FAIL_CHECK;
#if 0
/* other than iso-8859-1
* one more time due to reset tty by PAM
*/
printf("\033(K");
fprintf(stderr,"\033(K");
#endif
/* if fflag == 1, then the user has already been authenticated */
if (fflag && (getuid() == 0))
else
if(passwd_req == 1) {
/* note PAM_RHOST parameter keeps user's privilege level */
retcode = pam_set_item(pamh, PAM_RHOST, privilege);
PAM_FAIL_CHECK;
}
/* Grab the user information out of the password file for future usage
First get the username that we are actually using, though.
*/
retcode = pam_get_item(pamh, PAM_USER, (const void **) &username);
setpwent(); /* line 635 */
pwd = getpwnam(username); /* line 636 */
if (pwd) initgroups(username, pwd->pw_gid); /* line 637 */
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
PAM_FAIL_CHECK;
retcode = pam_open_session(pamh, 0);
PAM_FAIL_CHECK;
openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
#else /* ! USE_PAM */