aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_unix/pam_unix_passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pam_unix/pam_unix_passwd.c')
-rw-r--r--modules/pam_unix/pam_unix_passwd.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index c3417413..4a3784a5 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -67,6 +67,7 @@
#include <security/pam_modutil.h>
#include "pam_inline.h"
+#include "pam_i18n.h"
#include "pam_cc_compat.h"
#include "md5.h"
#include "support.h"
@@ -286,7 +287,7 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl,
DIAG_POP_IGNORE_CAST_QUAL;
/* should not get here: exit with error */
- D(("helper binary is not available"));
+ pam_syslog(pamh, LOG_ERR, "failed to execute %s: %m", UPDATE_HELPER);
_exit(PAM_AUTHINFO_UNAVAIL);
} else if (child > 0) {
/* wait for child */
@@ -339,25 +340,25 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl,
static int check_old_password(const char *forwho, const char *newpass)
{
- static char buf[16384];
+ char *buf = NULL;
char *s_pas;
int retval = PAM_SUCCESS;
FILE *opwfile;
+ size_t n = 0;
size_t len = strlen(forwho);
- opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ opwfile = fopen(OLD_PASSWORDS_FILE, "re");
if (opwfile == NULL)
return PAM_ABORT;
- while (fgets(buf, 16380, opwfile)) {
- if (!strncmp(buf, forwho, len) && (buf[len] == ':' ||
- buf[len] == ',')) {
+ for (; getline(&buf, &n, opwfile) != -1; pam_overwrite_n(buf, n)) {
+ if (!strncmp(buf, forwho, len) && buf[len] == ':') {
char *sptr;
buf[strlen(buf) - 1] = '\0';
- /* s_luser = */ strtok_r(buf, ":,", &sptr);
- /* s_uid = */ strtok_r(NULL, ":,", &sptr);
- /* s_npas = */ strtok_r(NULL, ":,", &sptr);
- s_pas = strtok_r(NULL, ":,", &sptr);
+ /* s_luser = */ strtok_r(buf, ":", &sptr);
+ /* s_uid = */ strtok_r(NULL, ":", &sptr);
+ /* s_npas = */ strtok_r(NULL, ":", &sptr);
+ s_pas = strtok_r(NULL, ",", &sptr);
while (s_pas != NULL) {
char *md5pass = Goodcrypt_md5(newpass, s_pas);
if (md5pass == NULL || !strcmp(md5pass, s_pas)) {
@@ -365,12 +366,14 @@ static int check_old_password(const char *forwho, const char *newpass)
retval = PAM_AUTHTOK_ERR;
break;
}
- s_pas = strtok_r(NULL, ":,", &sptr);
+ s_pas = strtok_r(NULL, ",", &sptr);
_pam_delete(md5pass);
}
break;
}
}
+ pam_overwrite_n(buf, n);
+ free(buf);
fclose(opwfile);
return retval;
@@ -572,9 +575,10 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
remark = _("You must choose a shorter password.");
D(("length exceeded [%s]", remark));
} else if (off(UNIX__IAMROOT, ctrl)) {
- if ((int)strlen(pass_new) < pass_min_len)
+ if ((int)strlen(pass_new) < pass_min_len) {
remark = _("You must choose a longer password.");
- D(("length check [%s]", remark));
+ D(("length check [%s]", remark));
+ }
if (on(UNIX_REMEMBER_PASSWD, ctrl)) {
if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
remark = _("Password has been already used. Choose another.");
@@ -600,6 +604,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
int remember = -1;
int rounds = 0;
int pass_min_len = 0;
+ struct passwd *pwd;
/* <DO NOT free() THESE> */
const char *user;
@@ -645,20 +650,16 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
* getpwnam() doesn't tell you *where* the information it gives you
* came from, nor should it. That's our job.
*/
- if (_unix_comesfromsource(pamh, user, 1, on(UNIX_NIS, ctrl)) == 0) {
+ if (_unix_getpwnam(pamh, user, 1, on(UNIX_NIS, ctrl), &pwd) == 0) {
pam_syslog(pamh, LOG_DEBUG,
"user \"%s\" does not exist in /etc/passwd%s",
user, on(UNIX_NIS, ctrl) ? " or NIS" : "");
return PAM_USER_UNKNOWN;
- } else {
- struct passwd *pwd;
- _unix_getpwnam(pamh, user, 1, 1, &pwd);
- if (pwd == NULL) {
- pam_syslog(pamh, LOG_DEBUG,
- "user \"%s\" has corrupted passwd entry",
- user);
- return PAM_USER_UNKNOWN;
- }
+ } else if (pwd == NULL) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "user \"%s\" has corrupted passwd entry",
+ user);
+ return PAM_USER_UNKNOWN;
}
/*
@@ -697,7 +698,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
} else {
D(("process run by root so do nothing this time around"));
pass_old = NULL;
- retval = PAM_SUCCESS; /* root doesn't have too */
+ retval = PAM_SUCCESS; /* root doesn't have to */
}
if (retval != PAM_SUCCESS) {
@@ -779,7 +780,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
* password is acceptable.
*/
- if (*(const char *)pass_new == '\0') { /* "\0" password = NULL */
+ if (*pass_new == '\0') { /* "\0" password = NULL */
pass_new = NULL;
}
retval = _pam_unix_approve_pass(pamh, ctrl, pass_old,