/*
- * $Id$
- *
* Copyright information at end of file.
*/
-#define _BSD_SOURCE
+#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <ctype.h>
+#include <syslog.h>
+#include <sys/resource.h>
#include <rpcsvc/ypclnt.h>
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-#include <security/_pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
-#include "md5.h"
#include "support.h"
+#include "passverify.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#define SELINUX_ENABLED is_selinux_enabled()>0
#else
#define SELINUX_ENABLED 0
#endif
-extern char *crypt(const char *key, const char *salt);
-extern char *bigcrypt(const char *key, const char *salt);
-
-/* syslogging function for errors and other information */
-
-void _log_err(int err, pam_handle_t *pamh, const char *format,...)
-{
- const void *service = NULL;
- char logname[256];
- va_list args;
-
- pam_get_item(pamh, PAM_SERVICE, &service);
- if (service) {
- strncpy(logname, service, sizeof(logname));
- logname[sizeof(logname) - 1 - strlen("(pam_unix)")] = '\0';
- strncat(logname, "(pam_unix)", strlen("(pam_unix)"));
- } else {
- strncpy(logname, "pam_unix", sizeof(logname) - 1);
- }
-
- va_start(args, format);
- openlog(logname, LOG_CONS | LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
- va_end(args);
- closelog();
-}
/* this is a front-end for module-application conversations */
-static int converse(pam_handle_t * pamh, int ctrl, int nargs
- ,struct pam_message **message
- ,struct pam_response **response)
-{
- int retval;
- const void *void_conv;
- const struct pam_conv *conv;
-
- D(("begin to converse"));
-
- retval = pam_get_item(pamh, PAM_CONV, &void_conv);
- conv = void_conv;
- if (retval == PAM_SUCCESS) {
-
- retval = conv->conv(nargs, (const struct pam_message **) message
- ,response, conv->appdata_ptr);
-
- D(("returned from application's conversation function"));
-
- if (retval != PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) {
- _log_err(LOG_DEBUG, pamh, "conversation failure [%s]"
- ,pam_strerror(pamh, retval));
- }
- } else if (retval != PAM_CONV_AGAIN) {
- _log_err(LOG_ERR, pamh
- ,"couldn't obtain coversation function [%s]"
- ,pam_strerror(pamh, retval));
- }
- D(("ready to return from module conversation"));
-
- return retval; /* propagate error status */
-}
-
-int _make_remark(pam_handle_t * pamh, unsigned int ctrl
- ,int type, const char *text)
+int _make_remark(pam_handle_t * pamh, unsigned int ctrl,
+ int type, const char *text)
{
int retval = PAM_SUCCESS;
if (off(UNIX__QUIET, ctrl)) {
- struct pam_message *pmsg[1], msg[1];
- struct pam_response *resp;
-
- pmsg[0] = &msg[0];
- msg[0].msg = text;
- msg[0].msg_style = type;
-
- resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
-
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
+ retval = pam_prompt(pamh, type, NULL, "%s", text);
}
return retval;
}
* set the control flags for the UNIX module.
*/
-int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
- const char **argv)
+int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
+ int argc, const char **argv)
{
unsigned int ctrl;
}
if (j >= UNIX_CTRLS_) {
- _log_err(LOG_ERR, pamh,
+ pam_syslog(pamh, LOG_ERR,
"unrecognized option [%s]", *argv);
} else {
ctrl &= unix_args[j].mask; /* for turning things off */
*remember = 400;
}
}
+ if (rounds != NULL && j == UNIX_ALGO_ROUNDS)
+ *rounds = strtol(*argv + 7, NULL, 10);
}
++argv; /* step to next argument */
D(("DISALLOW_NULL_AUTHTOK"));
set(UNIX__NONULL, ctrl);
}
+
+ /* Set default rounds for blowfish */
+ if (on(UNIX_BLOWFISH_PASS, ctrl) && off(UNIX_ALGO_ROUNDS, ctrl)) {
+ *rounds = 5;
+ set(UNIX_ALGO_ROUNDS, ctrl);
+ }
+
+ /* Enforce sane "rounds" values */
+ if (on(UNIX_ALGO_ROUNDS, ctrl)) {
+ if (on(UNIX_BLOWFISH_PASS, ctrl)) {
+ if (*rounds < 4 || *rounds > 31)
+ *rounds = 5;
+ } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) {
+ if ((*rounds < 1000) || (*rounds == INT_MAX))
+ /* don't care about bogus values */
+ unset(UNIX_ALGO_ROUNDS, ctrl);
+ if (*rounds >= 10000000)
+ *rounds = 9999999;
+ }
+ }
/* auditing is a more sensitive version of debug */
return ctrl;
}
-static void _cleanup(pam_handle_t * pamh, void *x, int error_status)
+static void _cleanup(pam_handle_t * pamh UNUSED, void *x, int error_status UNUSED)
{
_pam_delete(x);
}
&rhost);
(void) pam_get_item(pamh, PAM_TTY,
&tty);
- _log_err(LOG_NOTICE, pamh,
+ pam_syslog(pamh, LOG_NOTICE,
"%d more authentication failure%s; "
"logname=%s uid=%d euid=%d "
"tty=%s ruser=%s rhost=%s "
"%s%s",
failure->count - 1, failure->count == 2 ? "" : "s",
failure->name, failure->uid, failure->euid,
- tty ? tty : "", ruser ? ruser : "",
- rhost ? rhost : "",
+ tty ? (const char *)tty : "", ruser ? (const char *)ruser : "",
+ rhost ? (const char *)rhost : "",
(failure->user && failure->user[0] != '\0')
? " user=" : "", failure->user
);
if (failure->count > UNIX_MAX_RETRIES) {
- _log_err(LOG_ALERT, pamh
- ,"service(%s) ignoring max retries; %d > %d"
- ,service == NULL ? "**unknown**" : service
- ,failure->count
- ,UNIX_MAX_RETRIES);
+ pam_syslog(pamh, LOG_ALERT,
+ "service(%s) ignoring max retries; %d > %d",
+ service == NULL ? "**unknown**" : (const char *)service,
+ failure->count,
+ UNIX_MAX_RETRIES);
}
}
}
/*
* _unix_getpwnam() searches only /etc/passwd and NIS to find user information
*/
-static void _unix_cleanup(pam_handle_t *pamh, void *data, int error_status)
+static void _unix_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED)
{
free(data);
}
i = yp_match(domain, "passwd.byname", name,
strlen(name), &userinfo, &len);
yp_unbind(domain);
- if ((i == YPERR_SUCCESS) && (len < sizeof(buf))) {
+ if ((i == YPERR_SUCCESS) && ((size_t)len < sizeof(buf))) {
strncpy(buf, userinfo, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
matched = 1;
memset(*ret, '\0', buflen);
(*ret)->pw_uid = strtol(suid, &p, 10);
- if ((strlen(sgid) == 0) || (*p != '\0')) {
+ if ((strlen(suid) == 0) || (*p != '\0')) {
free(*ret);
*ret = NULL;
return matched;
return _unix_getpwnam(pamh, name, files, nis, NULL);
}
-/*
- * _unix_blankpasswd() is a quick check for a blank password
- *
- * returns TRUE if user does not have a password
- * - to avoid prompting for one in such cases (CG)
- */
-
-int
-_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
-{
- struct passwd *pwd = NULL;
- struct spwd *spwdent = NULL;
- char *salt = NULL;
- int retval;
-
- D(("called"));
-
- /*
- * This function does not have to be too smart if something goes
- * wrong, return FALSE and let this case to be treated somewhere
- * else (CG)
- */
-
- if (on(UNIX__NONULL, ctrl))
- return 0; /* will fail but don't let on yet */
-
- /* UNIX passwords area */
-
- /* Get password file entry... */
- pwd = _pammodutil_getpwnam (pamh, name);
-
- if (pwd != NULL) {
- if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
- { /* NIS+ */
- uid_t save_euid, save_uid;
-
- save_euid = geteuid();
- save_uid = getuid();
- if (save_uid == pwd->pw_uid)
- setreuid( save_euid, save_uid );
- else {
- setreuid( 0, -1 );
- if (setreuid( -1, pwd->pw_uid ) == -1) {
- setreuid( -1, 0 );
- setreuid( 0, -1 );
- if(setreuid( -1, pwd->pw_uid ) == -1)
- /* Will fail elsewhere. */
- return 0;
- }
- }
-
- spwdent = _pammodutil_getspnam (pamh, name);
- if (save_uid == pwd->pw_uid)
- setreuid( save_uid, save_euid );
- else {
- if (setreuid( -1, 0 ) == -1)
- setreuid( save_uid, -1 );
- setreuid( -1, save_euid );
- }
- } else if (_unix_shadowed(pwd)) {
- /*
- * ...and shadow password file entry for this user,
- * if shadowing is enabled
- */
- spwdent = _pammodutil_getspnam(pamh, name);
- }
- if (spwdent)
- salt = x_strdup(spwdent->sp_pwdp);
- else
- salt = x_strdup(pwd->pw_passwd);
- }
- /* Does this user have a password? */
- if (salt == NULL) {
- retval = 0;
- } else {
- if (strlen(salt) == 0)
- retval = 1;
- else
- retval = 0;
- }
-
- /* tidy up */
-
- if (salt)
- _pam_delete(salt);
-
- return retval;
-}
-
/*
* verify the password of a user
*/
/* XXX - should really tidy up PAM here too */
- close(0); close(1);
/* reopen stdin as pipe */
- close(fds[1]);
dup2(fds[0], STDIN_FILENO);
if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
- for (i=2; i < rlim.rlim_max; i++) {
- if (fds[0] != i)
+ if (rlim.rlim_max >= MAX_FD_NO)
+ rlim.rlim_max = MAX_FD_NO;
+ for (i=0; i < (int)rlim.rlim_max; i++) {
+ if (i != STDIN_FILENO)
close(i);
}
}
+
+ if (geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ setuid(0);
+ }
+
/* exec binary helper */
- args[0] = x_strdup(CHKPWD_HELPER);
+ args[0] = strdup(CHKPWD_HELPER);
args[1] = x_strdup(user);
if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
- args[2]=x_strdup("nullok");
+ args[2]=strdup("nullok");
} else {
- args[2]=x_strdup("nonull");
+ args[2]=strdup("nonull");
}
execve(CHKPWD_HELPER, args, envp);
close(fds[1]);
rc=waitpid(child, &retval, 0); /* wait for helper to complete */
if (rc<0) {
- _log_err(LOG_ERR, pamh, "unix_chkpwd waitpid returned %d: %s", rc, strerror(errno));
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
retval = PAM_AUTH_ERR;
} else {
retval = WEXITSTATUS(retval);
retval = PAM_AUTH_ERR;
}
- if (sighandler != NULL) {
+ if (sighandler != SIG_ERR) {
(void) signal(SIGCHLD, sighandler); /* restore old signal handler */
}
return retval;
}
+/*
+ * _unix_blankpasswd() is a quick check for a blank password
+ *
+ * returns TRUE if user does not have a password
+ * - to avoid prompting for one in such cases (CG)
+ */
+
+int
+_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
+{
+ struct passwd *pwd = NULL;
+ char *salt = NULL;
+ int retval;
+
+ D(("called"));
+
+ /*
+ * This function does not have to be too smart if something goes
+ * wrong, return FALSE and let this case to be treated somewhere
+ * else (CG)
+ */
+
+ if (on(UNIX__NONULL, ctrl))
+ return 0; /* will fail but don't let on yet */
+
+ /* UNIX passwords area */
+
+ retval = get_pwd_hash(pamh, name, &pwd, &salt);
+
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ /* salt will not be set here so we can return immediately */
+ if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS)
+ return 1;
+ else
+ return 0;
+ }
+
+ /* Does this user have a password? */
+ if (salt == NULL) {
+ retval = 0;
+ } else {
+ if (strlen(salt) == 0)
+ retval = 1;
+ else
+ retval = 0;
+ }
+
+ /* tidy up */
+
+ if (salt)
+ _pam_delete(salt);
+
+ return retval;
+}
+
int _unix_verify_password(pam_handle_t * pamh, const char *name
,const char *p, unsigned int ctrl)
{
struct passwd *pwd = NULL;
- struct spwd *spwdent = NULL;
char *salt = NULL;
- char *pp = NULL;
char *data_name;
int retval;
D(("locating user's record"));
- /* UNIX passwords area */
- pwd = _pammodutil_getpwnam (pamh, name); /* Get password file entry... */
-
- if (pwd != NULL) {
- if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
- { /* NIS+ */
- uid_t save_euid, save_uid;
-
- save_euid = geteuid();
- save_uid = getuid();
- if (save_uid == pwd->pw_uid)
- setreuid( save_euid, save_uid );
- else {
- setreuid( 0, -1 );
- if (setreuid( -1, pwd->pw_uid ) == -1) {
- setreuid( -1, 0 );
- setreuid( 0, -1 );
- if(setreuid( -1, pwd->pw_uid ) == -1)
- return PAM_CRED_INSUFFICIENT;
- }
- }
-
- spwdent = _pammodutil_getspnam (pamh, name);
- if (save_uid == pwd->pw_uid)
- setreuid( save_uid, save_euid );
- else {
- if (setreuid( -1, 0 ) == -1)
- setreuid( save_uid, -1 );
- setreuid( -1, save_euid );
- }
- } else if (_unix_shadowed(pwd)) {
- /*
- * ...and shadow password file entry for this user,
- * if shadowing is enabled
- */
- spwdent = _pammodutil_getspnam (pamh, name);
- }
- if (spwdent)
- salt = x_strdup(spwdent->sp_pwdp);
- else
- salt = x_strdup(pwd->pw_passwd);
- }
+ retval = get_pwd_hash(pamh, name, &pwd, &salt);
data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name));
if (data_name == NULL) {
- _log_err(LOG_CRIT, pamh, "no memory for data-name");
+ pam_syslog(pamh, LOG_CRIT, "no memory for data-name");
} else {
strcpy(data_name, FAIL_PREFIX);
strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name);
}
- retval = PAM_SUCCESS;
- if (pwd == NULL || salt == NULL || !strcmp(salt, "x") || ((salt[0] == '#') && (salt[1] == '#') && !strcmp(salt + 2, name))) {
-
- if (pwd != NULL && (geteuid() || SELINUX_ENABLED)) {
- /* we are not root perhaps this is the reason? Run helper */
+ if (retval != PAM_SUCCESS) {
+ if (retval == PAM_UNIX_RUN_HELPER) {
D(("running helper binary"));
retval = _unix_run_helper_binary(pamh, p, ctrl, name);
} else {
D(("user's record unavailable"));
p = NULL;
- if (pwd == NULL)
- retval = PAM_USER_UNKNOWN;
- else
- retval = PAM_AUTHINFO_UNAVAIL;
if (on(UNIX_AUDIT, ctrl)) {
/* this might be a typo and the user has given a password
instead of a username. Careful with this. */
- _log_err(LOG_ALERT, pamh,
+ pam_syslog(pamh, LOG_WARNING,
"check pass; user (%s) unknown", name);
} else {
name = NULL;
if (on(UNIX_DEBUG, ctrl) || pwd == NULL) {
- _log_err(LOG_ALERT, pamh,
+ pam_syslog(pamh, LOG_WARNING,
"check pass; user unknown");
} else {
/* don't log failure as another pam module can succeed */
}
}
} else {
- int salt_len = strlen(salt);
- if (!salt_len) {
- /* the stored password is NULL */
- if (off(UNIX__NONULL, ctrl)) {/* this means we've succeeded */
- D(("user has empty password - access granted"));
- retval = PAM_SUCCESS;
- } else {
- D(("user has empty password - access denied"));
- retval = PAM_AUTH_ERR;
- }
- } else if (!p || (*salt == '*') || (salt_len < 13)) {
- retval = PAM_AUTH_ERR;
- } else {
- if (!strncmp(salt, "$1$", 3)) {
- pp = Goodcrypt_md5(p, salt);
- if (strcmp(pp, salt) != 0) {
- _pam_delete(pp);
- pp = Brokencrypt_md5(p, salt);
- }
- } else {
- pp = bigcrypt(p, salt);
- }
- p = NULL; /* no longer needed here */
-
- /* the moment of truth -- do we agree with the password? */
- D(("comparing state of pp[%s] and salt[%s]", pp, salt));
-
- /*
- * Note, we are comparing the bigcrypt of the password with
- * the contents of the password field. If the latter was
- * encrypted with regular crypt (and not bigcrypt) it will
- * have been truncated for storage relative to the output
- * of bigcrypt here. As such we need to compare only the
- * stored string with the subset of bigcrypt's result.
- * Bug 521314: The strncmp comparison is for legacy support.
- */
- if (strncmp(pp, salt, salt_len) == 0) {
- retval = PAM_SUCCESS;
- } else {
- retval = PAM_AUTH_ERR;
- }
- }
+ retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl));
}
if (retval == PAM_SUCCESS) {
const void *void_old;
- login_name = _pammodutil_getlogin(pamh);
+ login_name = pam_modutil_getlogin(pamh);
if (login_name == NULL) {
login_name = "";
}
new->name = x_strdup(login_name);
/* any previous failures for this user ? */
- pam_get_data(pamh, data_name, &void_old);
- old = void_old;
+ if (pam_get_data(pamh, data_name, &void_old)
+ == PAM_SUCCESS)
+ old = void_old;
+ else
+ old = NULL;
if (old != NULL) {
new->count = old->count + 1;
(void) pam_get_item(pamh, PAM_TTY,
&tty);
- _log_err(LOG_NOTICE, pamh,
+ pam_syslog(pamh, LOG_NOTICE,
"authentication failure; "
"logname=%s uid=%d euid=%d "
"tty=%s ruser=%s rhost=%s "
"%s%s",
new->name, new->uid, new->euid,
- tty ? tty : "",
- ruser ? ruser : "",
- rhost ? rhost : "",
+ tty ? (const char *)tty : "",
+ ruser ? (const char *)ruser : "",
+ rhost ? (const char *)rhost : "",
(new->user && new->user[0] != '\0')
? " user=" : "",
new->user
pam_set_data(pamh, data_name, new, _cleanup_failures);
} else {
- _log_err(LOG_CRIT, pamh,
+ pam_syslog(pamh, LOG_CRIT,
"no memory for failure recorder");
}
}
_pam_delete(data_name);
if (salt)
_pam_delete(salt);
- if (pp)
- _pam_delete(pp);
D(("done [%d].", retval));
,const void **pass)
{
int authtok_flag;
- int retval;
+ int retval = PAM_SUCCESS;
char *token;
D(("called"));
retval = pam_get_item(pamh, authtok_flag, pass);
if (retval != PAM_SUCCESS) {
/* very strange. */
- _log_err(LOG_ALERT, pamh
- ,"pam_get_item returned error to unix-read-password"
+ pam_syslog(pamh, LOG_ALERT,
+ "pam_get_item returned error to unix-read-password"
);
return retval;
} else if (*pass != NULL) { /* we have a password! */
return PAM_SUCCESS;
- } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
- return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
} else if (on(UNIX_USE_AUTHTOK, ctrl)
&& off(UNIX__OLD_PASSWD, ctrl)) {
return PAM_AUTHTOK_ERR;
+ } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
+ return PAM_AUTHTOK_RECOVERY_ERR; /* didn't work */
}
}
/*
*/
{
- struct pam_message msg[3], *pmsg[3];
- struct pam_response *resp;
- int i, replies;
-
- /* prepare to converse */
+ int replies=1;
+ char *resp[2] = { NULL, NULL };
if (comment != NULL && off(UNIX__QUIET, ctrl)) {
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_TEXT_INFO;
- msg[0].msg = comment;
- i = 1;
- } else {
- i = 0;
+ retval = pam_info(pamh, "%s", comment);
}
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt1;
- replies = 1;
+ if (retval == PAM_SUCCESS) {
+ retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF,
+ &resp[0], "%s", prompt1);
- if (prompt2 != NULL) {
- pmsg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[i++].msg = prompt2;
- ++replies;
+ if (retval == PAM_SUCCESS && prompt2 != NULL) {
+ retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF,
+ &resp[1], "%s", prompt2);
+ ++replies;
+ }
}
- /* so call the conversation expecting i responses */
- resp = NULL;
- retval = converse(pamh, ctrl, i, pmsg, &resp);
-
- if (resp != NULL) {
+ if (resp[0] != NULL && resp[replies-1] != NULL) {
/* interpret the response */
if (retval == PAM_SUCCESS) { /* a good conversation */
- token = x_strdup(resp[i - replies].resp);
+ token = resp[0];
if (token != NULL) {
if (replies == 2) {
-
/* verify that password entered correctly */
- if (!resp[i - 1].resp
- || strcmp(token, resp[i - 1].resp)) {
- _pam_delete(token); /* mistyped */
- retval = PAM_AUTHTOK_RECOVER_ERR;
- _make_remark(pamh, ctrl
- ,PAM_ERROR_MSG, MISTYPED_PASS);
+ if (strcmp(token, resp[replies - 1])) {
+ /* mistyped */
+ retval = PAM_AUTHTOK_RECOVERY_ERR;
+ _make_remark(pamh, ctrl,
+ PAM_ERROR_MSG, MISTYPED_PASS);
}
}
} else {
- _log_err(LOG_NOTICE, pamh
- ,"could not recover authentication token");
+ pam_syslog(pamh, LOG_NOTICE,
+ "could not recover authentication token");
}
}
- /*
- * tidy up the conversation (resp_retcode) is ignored
- * -- what is it for anyway? AGM
- */
-
- _pam_drop_reply(resp, i);
} else {
retval = (retval == PAM_SUCCESS)
- ? PAM_AUTHTOK_RECOVER_ERR : retval;
+ ? PAM_AUTHTOK_RECOVERY_ERR : retval;
}
+
+ resp[0] = NULL;
+ if (replies > 1)
+ _pam_delete(resp[1]);
}
if (retval != PAM_SUCCESS) {
+ _pam_delete(token);
+
if (on(UNIX_DEBUG, ctrl))
- _log_err(LOG_DEBUG, pamh,
+ pam_syslog(pamh, LOG_DEBUG,
"unable to obtain a password");
return retval;
}
!= PAM_SUCCESS) {
*pass = NULL;
- _log_err(LOG_CRIT, pamh, "error manipulating password");
+ pam_syslog(pamh, LOG_CRIT, "error manipulating password");
return retval;
}
retval = pam_set_data(pamh, data_name, (void *) token, _cleanup);
if (retval != PAM_SUCCESS) {
- _log_err(LOG_CRIT, pamh
- ,"error manipulating password data [%s]"
- ,pam_strerror(pamh, retval));
+ pam_syslog(pamh, LOG_CRIT,
+ "error manipulating password data [%s]",
+ pam_strerror(pamh, retval));
_pam_delete(token);
return retval;
}
return PAM_SUCCESS;
}
-int _unix_shadowed(const struct passwd *pwd)
-{
- if (pwd != NULL) {
- if (strcmp(pwd->pw_passwd, "x") == 0) {
- return 1;
- }
- if ((pwd->pw_passwd[0] == '#') &&
- (pwd->pw_passwd[1] == '#') &&
- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) {
- return 1;
- }
- }
- return 0;
-}
-
/* ****************************************************************** *
* Copyright (c) Jan Rêkorajski 1999.
* Copyright (c) Andrew G. Morgan 1996-8.
* Copyright (c) Alex O. Yuriev, 1996.
* Copyright (c) Cristian Gafton 1996.
+ * Copyright (c) Red Hat, Inc. 2007.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions