From 1814aec611a5f9e03eceee81237ad3a3f51c954a Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 26 Oct 2011 23:56:54 +0000 Subject: Fix whitespace issues Cleanup trailing whitespaces, indentation that uses spaces before tabs, and blank lines at EOF. Make the project free of warnings reported by git diff --check 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD --- modules/pam_unix/support.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index cc350e58..ab04535f 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -475,7 +475,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, rlim.rlim_max = MAX_FD_NO; for (i=0; i < (int)rlim.rlim_max; i++) { if (i != STDIN_FILENO) - close(i); + close(i); } } @@ -530,7 +530,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, } else { D(("fork failed")); close(fds[0]); - close(fds[1]); + close(fds[1]); retval = PAM_AUTH_ERR; } -- cgit v1.2.3 From a36df58aa78531a4629f90f732be475e9296a842 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 18 Jun 2013 16:27:15 +0200 Subject: Use hash from /etc/login.defs as default if no other one is specified as argument. * modules/pam_unix/support.c: Add search_key, call from __set_ctrl * modules/pam_unix/support.h: Add define for /etc/login.defs * modules/pam_unix/pam_unix.8.xml: Document new behavior. * modules/pam_umask/pam_umask.c: Add missing NULL pointer check --- modules/pam_umask/pam_umask.c | 6 ++- modules/pam_unix/pam_unix.8.xml | 7 ++- modules/pam_unix/support.c | 106 +++++++++++++++++++++++++++++++++++++++- modules/pam_unix/support.h | 63 +++++++++++++----------- 4 files changed, 151 insertions(+), 31 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_umask/pam_umask.c b/modules/pam_umask/pam_umask.c index 6d2ec1ac..863f0387 100644 --- a/modules/pam_umask/pam_umask.c +++ b/modules/pam_umask/pam_umask.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, 2007, 2010 Thorsten Kukuk + * Copyright (c) 2005, 2006, 2007, 2010, 2013 Thorsten Kukuk * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -112,6 +112,10 @@ search_key (const char *filename) { buflen = BUF_SIZE; buf = malloc (buflen); + if (buf == NULL) { + fclose (fp); + return NULL; + } } buf[0] = '\0'; if (fgets (buf, buflen - 1, fp) == NULL) diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 0a42d7a3..9ce084e3 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -81,7 +81,9 @@ The password component of this module performs the task of updating - the user's password. + the user's password. The default encryption hash is taken from the + ENCRYPT_METHOD variable from + /etc/login.defs @@ -392,6 +394,9 @@ session required pam_unix.so SEE ALSO + + login.defs5 + , pam.conf5 , diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index ab04535f..f36786e4 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -37,6 +37,80 @@ #define SELINUX_ENABLED 0 #endif +static char * +search_key (const char *key, const char *filename) +{ + FILE *fp; + char *buf = NULL; + size_t buflen = 0; + char *retval = NULL; + + fp = fopen (filename, "r"); + if (NULL == fp) + return NULL; + + while (!feof (fp)) + { + char *tmp, *cp; +#if defined(HAVE_GETLINE) + ssize_t n = getline (&buf, &buflen, fp); +#elif defined (HAVE_GETDELIM) + ssize_t n = getdelim (&buf, &buflen, '\n', fp); +#else + ssize_t n; + + if (buf == NULL) + { + buflen = BUF_SIZE; + buf = malloc (buflen); + if (buf == NULL) { + fclose (fp); + return NULL; + } + } + buf[0] = '\0'; + if (fgets (buf, buflen - 1, fp) == NULL) + break; + else if (buf != NULL) + n = strlen (buf); + else + n = 0; +#endif /* HAVE_GETLINE / HAVE_GETDELIM */ + cp = buf; + + if (n < 1) + break; + + tmp = strchr (cp, '#'); /* remove comments */ + if (tmp) + *tmp = '\0'; + while (isspace ((int)*cp)) /* remove spaces and tabs */ + ++cp; + if (*cp == '\0') /* ignore empty lines */ + continue; + + if (cp[strlen (cp) - 1] == '\n') + cp[strlen (cp) - 1] = '\0'; + + tmp = strsep (&cp, " \t="); + if (cp != NULL) + while (isspace ((int)*cp) || *cp == '=') + ++cp; + + if (strcasecmp (tmp, key) == 0) + { + retval = strdup (cp); + break; + } + } + fclose (fp); + + free (buf); + + return retval; +} + + /* this is a front-end for module-application conversations */ int _make_remark(pam_handle_t * pamh, unsigned int ctrl, @@ -58,6 +132,8 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, int *pass_min_len, int argc, const char **argv) { unsigned int ctrl; + char *val; + int j; D(("called.")); @@ -81,10 +157,38 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, D(("SILENT")); set(UNIX__QUIET, ctrl); } + + /* preset encryption method with value from /etc/login.defs */ + val = search_key ("ENCRYPT_METHOD", LOGIN_DEFS); + if (val) { + for (j = 0; j < UNIX_CTRLS_; ++j) { + if (unix_args[j].token && unix_args[j].is_hash_algo + && !strncasecmp(val, unix_args[j].token, strlen(unix_args[j].token))) { + break; + } + } + if (j >= UNIX_CTRLS_) { + pam_syslog(pamh, LOG_WARNING, "unrecognized ENCRYPT_METHOD value [%s]", val); + } else { + ctrl &= unix_args[j].mask; /* for turning things off */ + ctrl |= unix_args[j].flag; /* for turning things on */ + } + free (val); + + /* read number of rounds for crypt algo */ + if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) { + val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); + + if (val) { + *rounds = strtol(val, NULL, 10); + free (val); + } + } + } + /* now parse the arguments to this module */ for (; argc-- > 0; ++argv) { - int j; D(("pam_unix arg: %s", *argv)); diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index db4cd953..65759384 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -7,6 +7,12 @@ #include +/* + * File to read value of ENCRYPT_METHOD from. + */ +#define LOGIN_DEFS "/etc/login.defs" + + /* * here is the string to inform the user that the new passwords they * typed were not the same. @@ -20,6 +26,7 @@ typedef struct { const char *token; unsigned int mask; /* shall assume 32 bits of flags */ unsigned int flag; + unsigned int is_hash_algo; } UNIX_Ctrls; /* @@ -100,34 +107,34 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* symbol token name ctrl mask ctrl * * ----------------------- ------------------- --------------------- -------- */ -/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01}, -/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02}, -/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04}, -/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010}, -/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020}, -/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040}, -/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100}, -/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200}, -/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400}, -/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000}, -/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000}, -/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000}, -/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000}, -/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0260420000), 020000}, -/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0}, -/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000}, -/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000}, -/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000}, -/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(0260420000), 0400000}, -/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000}, -/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000}, -/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000}, -/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000}, -/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(0260420000), 020000000}, -/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0260420000), 040000000}, -/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000}, -/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000}, -/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000}, +/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01, 0}, +/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02, 0}, +/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04, 0}, +/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010, 0}, +/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020, 0}, +/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040, 0}, +/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100, 0}, +/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200, 0}, +/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400, 0}, +/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000, 0}, +/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000, 0}, +/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000, 0}, +/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000, 0}, +/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0260420000), 020000, 1}, +/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0, 0}, +/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000, 0}, +/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000, 0}, +/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000, 0}, +/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(0260420000), 0400000, 1}, +/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000, 0}, +/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000, 0}, +/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000, 0}, +/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000, 0}, +/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(0260420000), 020000000, 1}, +/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0260420000), 040000000, 1}, +/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, +/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000, 1}, +/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) -- cgit v1.2.3 From a9ac7fd64000712fdedd4c38b408ffebd2988156 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Thu, 29 Aug 2013 14:09:39 +0200 Subject: Restart waitpid if it returns with EINTR (ticket #17) * modules/pam_unix/pam_unix_acct.c: run waitpid in a while loop. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_unix/support.c: Likewise. --- modules/pam_unix/pam_unix_acct.c | 3 ++- modules/pam_unix/pam_unix_passwd.c | 3 ++- modules/pam_unix/support.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 4a362f88..7f8250ca 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -142,7 +142,8 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, if (child > 0) { char buf[32]; int rc=0; - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ + /* wait for helper to complete: */ + while ((rc=waitpid(child, &retval, 0) < 0 && errno == EINTR); if (rc<0) { pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc); retval = PAM_AUTH_ERR; diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 94bc3ec8..9bc1cd9e 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -254,7 +254,8 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const close(fds[0]); /* close here to avoid possible SIGPIPE above */ close(fds[1]); - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ + /* wait for helper to complete: */ + while ((rc=waitpid(child, &retval, 0) < 0 && errno == EINTR); if (rc<0) { pam_syslog(pamh, LOG_ERR, "unix_update waitpid failed: %m"); retval = PAM_AUTHTOK_ERR; diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index f36786e4..d8f4a6f7 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -621,7 +621,8 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, } close(fds[0]); /* close here to avoid possible SIGPIPE above */ close(fds[1]); - rc=waitpid(child, &retval, 0); /* wait for helper to complete */ + /* wait for helper to complete: */ + while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR); if (rc<0) { pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc); retval = PAM_AUTH_ERR; -- cgit v1.2.3 From 45ec020678ffc82f6c2849935907e2d83710a1f2 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 13 Sep 2013 15:20:01 +0200 Subject: Write to *rounds only if non-NULL. modules/pam_unix/support.c(_set_ctrl): Write to *rounds only if non-NULL. --- modules/pam_unix/support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index d8f4a6f7..9284dbaa 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -176,7 +176,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, free (val); /* read number of rounds for crypt algo */ - if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) { + if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) { val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); if (val) { -- cgit v1.2.3 From ba315ae8effdcad591608c99452dad05c4cf20ab Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Mon, 16 Sep 2013 11:48:12 +0200 Subject: Check return value of setuid to remove glibc warnings. * modules/pam_unix/pam_unix_acct.c: Check setuid return value. * modules/pam_unix/support.c: Likewise. --- modules/pam_unix/pam_unix_acct.c | 7 ++++++- modules/pam_unix/support.c | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 865dc290..8ec44492 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -121,7 +121,12 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, 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); + if (setuid(0) == -1) { + pam_syslog(pamh, LOG_ERR, "setuid failed: %m"); + printf("-1\n"); + fflush(stdout); + _exit(PAM_AUTHINFO_UNAVAIL); + } } /* exec binary helper */ diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 9284dbaa..19d72e66 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -586,7 +586,10 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, 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); + if (setuid(0) == -1) { + D(("setuid failed")); + _exit(PAM_AUTHINFO_UNAVAIL); + } } /* exec binary helper */ -- cgit v1.2.3