diff options
author | Steve Langasek <vorlon@debian.org> | 2019-01-22 14:54:11 -0800 |
---|---|---|
committer | Steve Langasek <vorlon@debian.org> | 2019-01-22 14:54:11 -0800 |
commit | f00afb1ef201b2eef7f9ddbe5a0c6ca802cf49bb (patch) | |
tree | 402838c53047b0e21466a653ae88d86a8e4b7b65 /modules/pam_unix/passverify.c | |
parent | 795badba7f95e737f979917859cd32c9bd47bcad (diff) | |
parent | 1cad9fb2a0d729c5b5e5aa7297c521df7d5a2d33 (diff) | |
download | pam-f00afb1ef201b2eef7f9ddbe5a0c6ca802cf49bb.tar.gz pam-f00afb1ef201b2eef7f9ddbe5a0c6ca802cf49bb.tar.bz2 pam-f00afb1ef201b2eef7f9ddbe5a0c6ca802cf49bb.zip |
New upstream version 1.3.0
Diffstat (limited to 'modules/pam_unix/passverify.c')
-rw-r--r-- | modules/pam_unix/passverify.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 4840bb2d..5d6a1484 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -31,7 +31,7 @@ #ifdef WITH_SELINUX #include <selinux/selinux.h> -#define SELINUX_ENABLED is_selinux_enabled()>0 +#define SELINUX_ENABLED (is_selinux_enabled()>0) #else #define SELINUX_ENABLED 0 #endif @@ -377,6 +377,9 @@ PAMH_ARG_DECL(char * create_password_hash, const char *algoid; char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ char *sp; +#ifdef HAVE_CRYPT_R + struct crypt_data *cdata = NULL; +#endif if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ @@ -414,16 +417,22 @@ PAMH_ARG_DECL(char * create_password_hash, #endif sp = stpcpy(salt, algoid); if (on(UNIX_ALGO_ROUNDS, ctrl)) { - sp += snprintf(sp, sizeof(salt) - 3, "rounds=%u$", rounds); + sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds); } - crypt_make_salt(sp, 8); - /* For now be conservative so the resulting hashes - * are not too long. 8 bytes of salt prevents dictionary - * attacks well enough. */ + crypt_make_salt(sp, 16); #ifdef HAVE_CRYPT_GENSALT_R } #endif +#ifdef HAVE_CRYPT_R + sp = NULL; + cdata = malloc(sizeof(*cdata)); + if (cdata != NULL) { + cdata->initialized = 0; + sp = crypt_r(password, salt, cdata); + } +#else sp = crypt(password, salt); +#endif if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) { /* libxcrypt/libc doesn't know the algorithm, use MD5 */ pam_syslog(pamh, LOG_ERR, @@ -435,10 +444,16 @@ PAMH_ARG_DECL(char * create_password_hash, if(sp) { memset(sp, '\0', strlen(sp)); } +#ifdef HAVE_CRYPT_R + free(cdata); +#endif return crypt_md5_wrapper(password); } - - return x_strdup(sp); + sp = x_strdup(sp); +#ifdef HAVE_CRYPT_R + free(cdata); +#endif + return sp; } #ifdef WITH_SELINUX @@ -639,11 +654,23 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass, continue; buf[strlen(buf) - 1] = '\0'; s_luser = strtok_r(buf, ":", &sptr); + if (s_luser == NULL) { + found = 0; + continue; + } s_uid = strtok_r(NULL, ":", &sptr); + if (s_uid == NULL) { + found = 0; + continue; + } s_npas = strtok_r(NULL, ":", &sptr); + if (s_npas == NULL) { + found = 0; + continue; + } s_pas = strtok_r(NULL, ":", &sptr); npas = strtol(s_npas, NULL, 10) + 1; - while (npas > howmany) { + while (npas > howmany && s_pas != NULL) { s_pas = strpbrk(s_pas, ","); if (s_pas != NULL) s_pas++; @@ -931,7 +958,7 @@ PAMH_ARG_DECL(int unix_update_shadow, fclose(opwfile); if (!wroteentry && !err) { - spwdent.sp_namp = forwho; + spwdent.sp_namp = (char *)forwho; spwdent.sp_pwdp = towhat; spwdent.sp_lstchg = time(NULL) / (60 * 60 * 24); if (spwdent.sp_lstchg == 0) @@ -1085,12 +1112,15 @@ getuidname(uid_t uid) int read_passwords(int fd, int npass, char **passwords) { + /* The passwords array must contain npass preallocated + * buffers of length MAXPASS + 1 + */ int rbytes = 0; int offset = 0; int i = 0; char *pptr; while (npass > 0) { - rbytes = read(fd, passwords[i]+offset, MAXPASS-offset); + rbytes = read(fd, passwords[i]+offset, MAXPASS+1-offset); if (rbytes < 0) { if (errno == EINTR) continue; |