Goal: Don't call openlog() or closelog() from pam_smbpass Fixes: bug #434372 Upstream status: submitted as bugzilla bug #4831 Index: samba-3.0.28a/source/pam_smbpass/support.c =================================================================== --- samba-3.0.28a.orig/source/pam_smbpass/support.c +++ samba-3.0.28a/source/pam_smbpass/support.c @@ -15,6 +15,7 @@ * Mass Ave, Cambridge, MA 02139, USA. */ + #include "config.h" #include "includes.h" #include "general.h" @@ -66,19 +67,44 @@ char *servicesf = dyn_CONFIGFILE; - /* syslogging function for errors and other information */ - - void _log_err( int err, const char *format, ... ) - { - va_list args; +/* syslogging function for errors and other information */ +#ifdef HAVE_PAM_VSYSLOG +void _log_err( pam_handle_t *pamh, int err, const char *format, ... ) +{ + va_list args; - va_start( args, format ); - openlog( "PAM_smbpass", LOG_CONS | LOG_PID, LOG_AUTH ); - vsyslog( err, format, args ); - va_end( args ); - closelog(); + va_start(args, format); + pam_vsyslog(pamh, err, format, args); + va_end(args); +} +#else +void _log_err( pam_handle_t *pamh, int err, const char *format, ... ) +{ + va_list args; + const char tag[] = "(pam_smbpass) "; + char *mod_format; + + mod_format = SMB_MALLOC_ARRAY(char, sizeof(tag) + strlen(format)); + /* try really, really hard to log something, since this may have + been a message about a malloc() failure... */ + if (mod_format == NULL) { + va_start(args, format); + vsyslog(err | LOG_AUTH, format, args); + va_end(args); + return; } + strncpy(mod_format, tag, strlen(tag)+1); + strncat(mod_format, format, strlen(format)); + + va_start(args, format); + vsyslog(err | LOG_AUTH, mod_format, args); + va_end(args); + + free(mod_format); +} +#endif + /* this is a front-end for module-application conversations */ int converse( pam_handle_t * pamh, int ctrl, int nargs @@ -95,12 +121,14 @@ ,response, conv->appdata_ptr); if (retval != PAM_SUCCESS && on(SMB_DEBUG, ctrl)) { - _log_err(LOG_DEBUG, "conversation failure [%s]" - ,pam_strerror(pamh, retval)); + _log_err(pamh, LOG_DEBUG, + "conversation failure [%s]", + pam_strerror(pamh, retval)); } } else { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" - ,pam_strerror(pamh, retval)); + _log_err(pamh, LOG_ERR, + "couldn't obtain coversation function [%s]", + pam_strerror(pamh, retval)); } return retval; /* propagate error status */ @@ -126,7 +154,7 @@ /* set the control flags for the SMB module. */ -int set_ctrl( int flags, int argc, const char **argv ) +int set_ctrl( pam_handle_t *pamh, int flags, int argc, const char **argv ) { int i = 0; const char *service_file = dyn_CONFIGFILE; @@ -168,7 +196,7 @@ /* Read some options from the Samba config. Can be overridden by the PAM config. */ if(lp_load(service_file,True,False,False,True) == False) { - _log_err( LOG_ERR, "Error loading service file %s", service_file ); + _log_err(pamh, LOG_ERR, "Error loading service file %s", service_file); } secrets_init(); @@ -191,7 +219,7 @@ } if (j >= SMB_CTRLS_) { - _log_err( LOG_ERR, "unrecognized option [%s]", *argv ); + _log_err(pamh, LOG_ERR, "unrecognized option [%s]", *argv); } else { ctrl &= smb_args[j].mask; /* for turning things off */ ctrl |= smb_args[j].flag; /* for turning things on */ @@ -230,7 +258,7 @@ * evidence of old token around for later stack analysis. * */ -char * smbpXstrDup( const char *x ) +char * smbpXstrDup( pam_handle_t *pamh, const char *x ) { register char *newstr = NULL; @@ -240,7 +268,7 @@ for (i = 0; x[i]; ++i); /* length of string */ if ((newstr = SMB_MALLOC_ARRAY(char, ++i)) == NULL) { i = 0; - _log_err( LOG_CRIT, "out of memory in smbpXstrDup" ); + _log_err(pamh, LOG_CRIT, "out of memory in smbpXstrDup"); } else { while (i-- > 0) { newstr[i] = x[i]; @@ -282,7 +310,7 @@ /* log the number of authentication failures */ if (failure->count != 0) { pam_get_item( pamh, PAM_SERVICE, (const void **) &service ); - _log_err( LOG_NOTICE + _log_err(pamh, LOG_NOTICE , "%d authentication %s " "from %s for service %s as %s(%d)" , failure->count @@ -291,7 +319,7 @@ , service == NULL ? "**unknown**" : service , failure->user, failure->id ); if (failure->count > SMB_MAX_RETRIES) { - _log_err( LOG_ALERT + _log_err(pamh, LOG_ALERT , "service(%s) ignoring max retries; %d > %d" , service == NULL ? "**unknown**" : service , failure->count @@ -327,8 +355,7 @@ if (!pdb_get_lanman_passwd(sampass)) { - _log_err( LOG_DEBUG, "user %s has null SMB password" - , name ); + _log_err(pamh, LOG_DEBUG, "user %s has null SMB password", name); if (off( SMB__NONULL, ctrl ) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) @@ -338,15 +365,16 @@ const char *service; pam_get_item( pamh, PAM_SERVICE, (const void **)&service ); - _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s", - uidtoname(getuid()), service ? service : "**unknown**", name); + _log_err(pamh, LOG_NOTICE, + "failed auth request by %s for service %s as %s", + uidtoname(getuid()), service ? service : "**unknown**", name); return PAM_AUTH_ERR; } } data_name = SMB_MALLOC_ARRAY(char, sizeof(FAIL_PREFIX) + strlen( name )); if (data_name == NULL) { - _log_err( LOG_CRIT, "no memory for data-name" ); + _log_err(pamh, LOG_CRIT, "no memory for data-name"); } strncpy( data_name, FAIL_PREFIX, sizeof(FAIL_PREFIX) ); strncpy( data_name + sizeof(FAIL_PREFIX) - 1, name, strlen( name ) + 1 ); @@ -392,31 +420,31 @@ retval = PAM_MAXTRIES; } } else { - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); newauth->count = 1; } if (!sid_to_uid(pdb_get_user_sid(sampass), &(newauth->id))) { - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); } - newauth->user = smbpXstrDup( name ); - newauth->agent = smbpXstrDup( uidtoname( getuid() ) ); + newauth->user = smbpXstrDup(pamh, name); + newauth->agent = smbpXstrDup(pamh, uidtoname( getuid() )); pam_set_data( pamh, data_name, newauth, _cleanup_failures ); } else { - _log_err( LOG_CRIT, "no memory for failure recorder" ); - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_CRIT, "no memory for failure recorder"); + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); } } else { - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); @@ -490,8 +518,8 @@ retval = pam_get_item( pamh, authtok_flag, (const void **) &item ); if (retval != PAM_SUCCESS) { /* very strange. */ - _log_err( LOG_ALERT - , "pam_get_item returned error to smb_read_password" ); + _log_err(pamh, LOG_ALERT, + "pam_get_item returned error to smb_read_password"); return retval; } else if (item != NULL) { /* we have a password! */ *pass = item; @@ -543,7 +571,7 @@ if (retval == PAM_SUCCESS) { /* a good conversation */ - token = smbpXstrDup(resp[j++].resp); + token = smbpXstrDup(pamh, resp[j++].resp); if (token != NULL) { if (expect == 2) { /* verify that password entered correctly */ @@ -555,7 +583,8 @@ } } } else { - _log_err(LOG_NOTICE, "could not recover authentication token"); + _log_err(pamh, LOG_NOTICE, + "could not recover authentication token"); } } @@ -568,7 +597,7 @@ if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) - _log_err( LOG_DEBUG, "unable to obtain a password" ); + _log_err(pamh, LOG_DEBUG, "unable to obtain a password"); return retval; } /* 'token' is the entered password */ @@ -583,7 +612,7 @@ || (retval = pam_get_item( pamh, authtok_flag ,(const void **)&item )) != PAM_SUCCESS) { - _log_err( LOG_CRIT, "error manipulating password" ); + _log_err(pamh, LOG_CRIT, "error manipulating password"); return retval; } } else { @@ -597,8 +626,8 @@ || (retval = pam_get_data( pamh, data_name, (const void **)&item )) != PAM_SUCCESS) { - _log_err( LOG_CRIT, "error manipulating password data [%s]" - , pam_strerror( pamh, retval )); + _log_err(pamh, LOG_CRIT, "error manipulating password data [%s]", + pam_strerror( pamh, retval )); _pam_delete( token ); item = NULL; return retval; @@ -622,8 +651,8 @@ if (pass_new == NULL || (pass_old && !strcmp( pass_old, pass_new ))) { if (on(SMB_DEBUG, ctrl)) { - _log_err( LOG_DEBUG, - "passwd: bad authentication token (null or unchanged)" ); + _log_err(pamh, LOG_DEBUG, + "passwd: bad authentication token (null or unchanged)"); } make_remark( pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? "No password supplied" : "Password unchanged" ); Index: samba-3.0.28a/source/pam_smbpass/pam_smb_auth.c =================================================================== --- samba-3.0.28a.orig/source/pam_smbpass/pam_smb_auth.c +++ samba-3.0.28a/source/pam_smbpass/pam_smb_auth.c @@ -75,10 +75,9 @@ /* Samba initialization. */ load_case_tables(); - setup_logging("pam_smbpass",False); in_client = True; - ctrl = set_ctrl(flags, argc, argv); + ctrl = set_ctrl(pamh, flags, argc, argv); /* Get a few bytes so we can pass our return value to pam_sm_setcred(). */ @@ -93,12 +92,12 @@ retval = pam_get_user( pamh, &name, "Username: " ); if ( retval != PAM_SUCCESS ) { if (on( SMB_DEBUG, ctrl )) { - _log_err(LOG_DEBUG, "auth: could not identify user"); + _log_err(pamh, LOG_DEBUG, "auth: could not identify user"); } AUTH_RETURN; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "username [%s] obtained", name ); + _log_err(pamh, LOG_DEBUG, "username [%s] obtained", name ); } if (geteuid() != 0) { @@ -108,14 +107,14 @@ } if (!initialize_password_db(True)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } sampass = samu_new( NULL ); if (!sampass) { - _log_err( LOG_ALERT, "Cannot talloc a samu struct" ); + _log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" ); retval = nt_status_to_pam(NT_STATUS_NO_MEMORY); AUTH_RETURN; } @@ -129,7 +128,7 @@ } if (!found) { - _log_err(LOG_ALERT, "Failed to find entry for user %s.", name); + _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name); retval = PAM_USER_UNKNOWN; TALLOC_FREE(sampass); sampass = NULL; @@ -148,7 +147,7 @@ retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL, _SMB_AUTHTOK, &p); if (retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "auth: no password provided for [%s]", name); + _log_err(pamh,LOG_CRIT, "auth: no password provided for [%s]", name); TALLOC_FREE(sampass); AUTH_RETURN; } @@ -200,8 +199,8 @@ retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass ); if (retval != PAM_SUCCESS) { - _log_err( LOG_ALERT - , "pam_get_item returned error to pam_sm_authenticate" ); + _log_err(pamh, LOG_ALERT, + "pam_get_item returned error to pam_sm_authenticate"); return PAM_AUTHTOK_RECOVER_ERR; } else if (pass == NULL) { return PAM_AUTHTOK_RECOVER_ERR; Index: samba-3.0.28a/source/pam_smbpass/pam_smb_acct.c =================================================================== --- samba-3.0.28a.orig/source/pam_smbpass/pam_smb_acct.c +++ samba-3.0.28a/source/pam_smbpass/pam_smb_acct.c @@ -52,22 +52,21 @@ /* Samba initialization. */ load_case_tables(); - setup_logging( "pam_smbpass", False ); in_client = True; - ctrl = set_ctrl( flags, argc, argv ); + ctrl = set_ctrl(pamh, flags, argc, argv ); /* get the username */ retval = pam_get_user( pamh, &name, "Username: " ); if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "acct: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "acct: could not identify user" ); } return retval; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "acct: username [%s] obtained", name ); + _log_err(pamh, LOG_DEBUG, "acct: username [%s] obtained", name ); } if (geteuid() != 0) { @@ -79,7 +78,7 @@ from a SIGPIPE it's not expecting */ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(True)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } @@ -93,7 +92,7 @@ } if (!pdb_getsampwnam(sampass, name )) { - _log_err( LOG_DEBUG, "acct: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "acct: could not identify user"); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } @@ -106,8 +105,8 @@ if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG - , "acct: account %s is administratively disabled", name ); + _log_err(pamh, LOG_DEBUG, + "acct: account %s is administratively disabled", name); } make_remark( pamh, ctrl, PAM_ERROR_MSG , "Your account has been disabled; " Index: samba-3.0.28a/source/pam_smbpass/pam_smb_passwd.c =================================================================== --- samba-3.0.28a.orig/source/pam_smbpass/pam_smb_passwd.c +++ samba-3.0.28a/source/pam_smbpass/pam_smb_passwd.c @@ -104,10 +104,9 @@ /* Samba initialization. */ load_case_tables(); - setup_logging( "pam_smbpass", False ); in_client = True; - ctrl = set_ctrl(flags, argc, argv); + ctrl = set_ctrl(pamh, flags, argc, argv); /* * First get the name of a user. No need to do anything if we can't @@ -117,12 +116,12 @@ retval = pam_get_user( pamh, &user, "Username: " ); if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "password: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "password: could not identify user"); } return retval; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "username [%s] obtained", user ); + _log_err(pamh, LOG_DEBUG, "username [%s] obtained", user); } if (geteuid() != 0) { @@ -135,7 +134,7 @@ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(False)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database"); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } @@ -147,12 +146,12 @@ } if (!pdb_getsampwnam(sampass,user)) { - _log_err( LOG_ALERT, "Failed to find entry for user %s.", user ); + _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", user); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "Located account for %s", user ); + _log_err(pamh, LOG_DEBUG, "Located account for %s", user); } if (flags & PAM_PRELIM_CHECK) { @@ -178,7 +177,7 @@ #define greeting "Changing password for " Announce = SMB_MALLOC_ARRAY(char, sizeof(greeting)+strlen(user)); if (Announce == NULL) { - _log_err(LOG_CRIT, "password: out of memory"); + _log_err(pamh, LOG_CRIT, "password: out of memory"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_BUF_ERR; @@ -193,8 +192,8 @@ SAFE_FREE( Announce ); if (retval != PAM_SUCCESS) { - _log_err( LOG_NOTICE - , "password - (old) token not obtained" ); + _log_err(pamh, LOG_NOTICE, + "password - (old) token not obtained"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; @@ -239,7 +238,7 @@ } if (retval != PAM_SUCCESS) { - _log_err( LOG_NOTICE, "password: user not authenticated" ); + _log_err(pamh, LOG_NOTICE, "password: user not authenticated"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; @@ -264,8 +263,8 @@ if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_ALERT - , "password: new password not obtained" ); + _log_err(pamh, LOG_ALERT, + "password: new password not obtained"); } pass_old = NULL; /* tidy up */ TALLOC_FREE(sampass); @@ -286,7 +285,7 @@ retval = _pam_smb_approve_pass(pamh, ctrl, pass_old, pass_new); if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, "new password not acceptable"); + _log_err(pamh, LOG_NOTICE, "new password not acceptable"); pass_new = pass_old = NULL; /* tidy up */ TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); @@ -306,16 +305,17 @@ /* password updated */ if (!sid_to_uid(pdb_get_user_sid(sampass), &uid)) { - _log_err( LOG_NOTICE, "Unable to get uid for user %s", + _log_err(pamh, LOG_NOTICE, + "Unable to get uid for user %s", pdb_get_username(sampass)); - _log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)", + _log_err(pamh, LOG_NOTICE, "password for (%s) changed by (%s/%d)", user, uidtoname(getuid()), getuid()); } else { - _log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)", + _log_err(pamh, LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)", user, uid, uidtoname(getuid()), getuid()); } } else { - _log_err( LOG_ERR, "password change failed for user %s", user); + _log_err(pamh, LOG_ERR, "password change failed for user %s", user); } pass_old = pass_new = NULL; @@ -326,7 +326,7 @@ } else { /* something has broken with the library */ - _log_err( LOG_ALERT, "password received unknown request" ); + _log_err(pamh, LOG_ALERT, "password received unknown request"); retval = PAM_ABORT; } Index: samba-3.0.28a/source/pam_smbpass/support.h =================================================================== --- samba-3.0.28a.orig/source/pam_smbpass/support.h +++ samba-3.0.28a/source/pam_smbpass/support.h @@ -1,8 +1,8 @@ /* syslogging function for errors and other information */ -extern void _log_err(int, const char *, ...); +extern void _log_err(pam_handle_t *, int, const char *, ...); /* set the control flags for the UNIX module. */ -extern int set_ctrl(int, int, const char **); +extern int set_ctrl(pam_handle_t *, int, int, const char **); /* generic function for freeing pam data segments */ extern void _cleanup(pam_handle_t *, void *, int); @@ -12,7 +12,7 @@ * evidence of old token around for later stack analysis. */ -extern char *smbpXstrDup(const char *); +extern char *smbpXstrDup(pam_handle_t *,const char *); /* ************************************************************** * * Useful non-trivial functions *