From dce80b3f11b3c3aa137d18f22699809094dd64b6 Mon Sep 17 00:00:00 2001 From: Björn Esser Date: Thu, 15 Nov 2018 15:58:56 +0100 Subject: pam_unix: Prefer a gensalt function, that supports auto entropy. * modules/pam_unix/pam_unix_passwd.c: Initialize rounds parameter to 0. * modules/pam_unix/passverify.c: Prefer gensalt with auto entropy. * modules/pam_unix/support.c: Fix sanitizing of rounds parameter. --- modules/pam_unix/support.c | 7 +++++-- 1 file changed, 5 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 f2e28d35..753e5f89 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -175,6 +175,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, if (val) { *rounds = strtol(val, NULL, 10); + set(UNIX_ALGO_ROUNDS, ctrl); free (val); } } @@ -254,11 +255,13 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, 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)) + if ((*rounds < 1000) || (*rounds == INT_MAX)) { /* don't care about bogus values */ + *rounds = 0; unset(UNIX_ALGO_ROUNDS, ctrl); - if (*rounds >= 10000000) + } else if (*rounds >= 10000000) { *rounds = 9999999; + { } } -- cgit v1.2.3 From b8ba9fafae478ae96529d61e2ce163b338f9b29b Mon Sep 17 00:00:00 2001 From: Björn Esser Date: Thu, 22 Nov 2018 17:04:08 +0100 Subject: pam_unix: Fix closing curly brace. (#77) This has been overlooked during review of commit dce80b3f11b3. * modules/pam_unix/support.c (_set_ctrl): Fix closing curly brace. Closes: https://github.com/linux-pam/linux-pam/issues/77 --- 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 753e5f89..8cbc4217 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -261,7 +261,7 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, unset(UNIX_ALGO_ROUNDS, ctrl); } else if (*rounds >= 10000000) { *rounds = 9999999; - { + } } } -- cgit v1.2.3 From 16bd523f85ede9fa9115f80e826f2d803d7e61d4 Mon Sep 17 00:00:00 2001 From: Björn Esser Date: Thu, 15 Nov 2018 16:38:05 +0100 Subject: pam_unix: Add support for (gost-)yescrypt hashing methods. libxcrypt (v4.2 and later) has added support for the yescrypt hashing method; gost-yescrypt has been added in v4.3. * modules/pam_unix/pam_unix.8.xml: Documentation for (gost-)yescrypt. * modules/pam_unix/pam_unix_acct.c: Use 64 bit type for control flags. * modules/pam_unix/pam_unix_auth.c: Likewise. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_unix/pam_unix_sess.c: Likewise. * modules/pam_unix/passverify.c: Add support for (gost-)yescrypt. * modules/pam_unix/passverify.h: Use 64 bit type for control flags. * modules/pam_unix/support.c: Set sane rounds for (gost-)yescrypt. * modules/pam_unix/support.h: Add support for (gost-)yescrypt. --- modules/pam_unix/pam_unix.8.xml | 35 ++++++++++++- modules/pam_unix/pam_unix_acct.c | 4 +- modules/pam_unix/pam_unix_auth.c | 4 +- modules/pam_unix/pam_unix_passwd.c | 12 ++--- modules/pam_unix/pam_unix_sess.c | 4 +- modules/pam_unix/passverify.c | 8 ++- modules/pam_unix/passverify.h | 2 +- modules/pam_unix/support.c | 33 +++++++----- modules/pam_unix/support.h | 101 ++++++++++++++++++++----------------- 9 files changed, 128 insertions(+), 75 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 1b318f11..cae2aeaa 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -331,14 +331,45 @@ + + + + + + + When a user changes their password next, + encrypt it with the gost-yescrypt algorithm. If the + gost-yescrypt algorithm is not known to the + crypt3 + function, + fall back to MD5. + + + + + + + + + + When a user changes their password next, + encrypt it with the yescrypt algorithm. If the + yescrypt algorithm is not known to the + crypt3 + function, + fall back to MD5. + + + - Set the optional number of rounds of the SHA256, SHA512 - and blowfish password hashing algorithms to + Set the optional number of rounds of the SHA256, SHA512, + blowfish, gost-yescrypt, and yescrypt password hashing + algorithms to n. diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index fbc84e2f..d8d084ac 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -62,7 +62,7 @@ #include "support.h" #include "passverify.h" -int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, +int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user, int *daysleft) { int retval=0, child, fds[2]; @@ -185,7 +185,7 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; const void *void_uname; const char *uname; int retval, daysleft; diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c index 9d9f709d..905fc66c 100644 --- a/modules/pam_unix/pam_unix_auth.c +++ b/modules/pam_unix/pam_unix_auth.c @@ -96,7 +96,7 @@ setcred_free (pam_handle_t *pamh UNUSED, void *ptr, int err UNUSED) int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; int retval, *ret_data = NULL; const char *name; const char *p; @@ -194,7 +194,7 @@ pam_sm_setcred (pam_handle_t *pamh, int flags, { int retval; const void *pretval = NULL; - unsigned int ctrl; + unsigned long long ctrl; D(("called.")); diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index f2c42513..df4c1233 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -138,7 +138,7 @@ __taddr2port (const struct netconfig *nconf, const struct netbuf *nbuf) } #endif -static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) +static char *getNISserver(pam_handle_t *pamh, unsigned long long ctrl) { char *master; char *domainname; @@ -233,7 +233,7 @@ static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl) #ifdef WITH_SELINUX -static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, +static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user, const char *fromwhat, const char *towhat, int remember) { int retval, child, fds[2]; @@ -388,7 +388,7 @@ static int check_old_password(const char *forwho, const char *newpass) static int _do_setpass(pam_handle_t* pamh, const char *forwho, const char *fromwhat, - char *towhat, unsigned int ctrl, int remember) + char *towhat, unsigned long long ctrl, int remember) { struct passwd *pwd = NULL; int retval = 0; @@ -512,7 +512,7 @@ done: return retval; } -static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl) +static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned long long ctrl) { struct passwd *pwent = NULL; /* Password and shadow password */ struct spwd *spent = NULL; /* file entries for the user */ @@ -542,7 +542,7 @@ static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned in } static int _pam_unix_approve_pass(pam_handle_t * pamh - ,unsigned int ctrl + ,unsigned long long ctrl ,const char *pass_old ,const char *pass_new, int pass_min_len) @@ -600,7 +600,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { - unsigned int ctrl, lctrl; + unsigned long long ctrl, lctrl; int retval; int remember = -1; int rounds = 0; diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c index 03e7dcd9..4b8af530 100644 --- a/modules/pam_unix/pam_unix_sess.c +++ b/modules/pam_unix/pam_unix_sess.c @@ -67,7 +67,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *user_name, *service; - unsigned int ctrl; + unsigned long long ctrl; int retval; const char *login_name; @@ -103,7 +103,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { char *user_name, *service; - unsigned int ctrl; + unsigned long long ctrl; int retval; D(("called.")); diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 95dfe528..39e2bfac 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -387,7 +387,7 @@ crypt_md5_wrapper(const char *pass_new) } PAMH_ARG_DECL(char * create_password_hash, - const char *password, unsigned int ctrl, int rounds) + const char *password, unsigned long long ctrl, int rounds) { const char *algoid; #if defined(CRYPT_GENSALT_OUTPUT_SIZE) && CRYPT_GENSALT_OUTPUT_SIZE > 64 @@ -404,6 +404,10 @@ PAMH_ARG_DECL(char * create_password_hash, if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ return crypt_md5_wrapper(password); + } else if (on(UNIX_YESCRYPT_PASS, ctrl)) { + algoid = "$y$"; + } else if (on(UNIX_GOST_YESCRYPT_PASS, ctrl)) { + algoid = "$gy$"; } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { algoid = "$2b$"; } else if (on(UNIX_SHA256_PASS, ctrl)) { @@ -466,6 +470,8 @@ PAMH_ARG_DECL(char * create_password_hash, pam_syslog(pamh, LOG_ERR, "Algo %s not supported by the crypto backend, " "falling back to MD5\n", + on(UNIX_YESCRYPT_PASS, ctrl) ? "yescrypt" : + on(UNIX_GOST_YESCRYPT_PASS, ctrl) ? "gost_yescrypt" : on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : on(UNIX_SHA256_PASS, ctrl) ? "sha256" : on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index caf7ae8a..086c28ac 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -66,7 +66,7 @@ read_passwords(int fd, int npass, char **passwords); #endif PAMH_ARG_DECL(char * create_password_hash, - const char *password, unsigned int ctrl, int rounds); + const char *password, unsigned long long ctrl, int rounds); PAMH_ARG_DECL(int get_account_info, const char *name, struct passwd **pwd, struct spwd **spwdent); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 8cbc4217..6894288d 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -107,7 +107,7 @@ search_key (const char *key, const char *filename) /* this is a front-end for module-application conversations */ -int _make_remark(pam_handle_t * pamh, unsigned int ctrl, +int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, int type, const char *text) { int retval = PAM_SUCCESS; @@ -122,10 +122,11 @@ int _make_remark(pam_handle_t * pamh, unsigned int ctrl, * set the control flags for the UNIX module. */ -int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, - int *pass_min_len, int argc, const char **argv) +unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, + int *rounds, int *pass_min_len, int argc, + const char **argv) { - unsigned int ctrl; + unsigned long long ctrl; char *val; int j; @@ -243,15 +244,23 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds, set(UNIX__NONULL, ctrl); } - /* Set default rounds for blowfish */ - if (on(UNIX_BLOWFISH_PASS, ctrl) && off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) { - *rounds = 5; - set(UNIX_ALGO_ROUNDS, ctrl); + /* Set default rounds for blowfish, gost-yescrypt and yescrypt */ + if (off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) { + if (on(UNIX_BLOWFISH_PASS, ctrl) || + on(UNIX_GOST_YESCRYPT_PASS, ctrl) || + on(UNIX_YESCRYPT_PASS, 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 (on(UNIX_GOST_YESCRYPT_PASS, ctrl) || + on(UNIX_YESCRYPT_PASS, ctrl)) { + if (*rounds < 3 || *rounds > 11) + *rounds = 5; + } else 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)) { @@ -532,7 +541,7 @@ int _unix_comesfromsource(pam_handle_t *pamh, #include static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, - unsigned int ctrl, const char *user) + unsigned long long ctrl, const char *user) { int retval, child, fds[2]; struct sigaction newsa, oldsa; @@ -658,7 +667,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, */ int -_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) +_unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name) { struct passwd *pwd = NULL; char *salt = NULL; @@ -706,7 +715,7 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name) } int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl) + ,const char *p, unsigned long long ctrl) { struct passwd *pwd = NULL; char *salt = NULL; diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index 543e9b9f..e02c05e0 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -22,8 +22,8 @@ typedef struct { const char *token; - unsigned int mask; /* shall assume 32 bits of flags */ - unsigned int flag; + unsigned long long mask; /* shall assume 64 bits of flags */ + unsigned long long flag; unsigned int is_hash_algo; } UNIX_Ctrls; @@ -48,7 +48,7 @@ typedef struct { /* the generic mask */ -#define _ALL_ON_ (~0U) +#define _ALL_ON_ (~0ULL) /* end of macro definitions definitions for the control flags */ @@ -98,47 +98,51 @@ typedef struct { #define UNIX_QUIET 28 /* Don't print informational messages */ #define UNIX_NO_PASS_EXPIRY 29 /* Don't check for password expiration if not used for authentication */ #define UNIX_DES 30 /* DES, default */ +#define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */ +#define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */ /* -------------- */ -#define UNIX_CTRLS_ 31 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 33 /* number of ctrl arguments defined */ -#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)) +#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)) static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = { -/* symbol token name ctrl mask ctrl * - * ----------------------- ------------------- --------------------- -------- */ - -/* 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_AUTHTOK_TYPE */ {"authtok_type=", _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}, -/* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0}, -/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0}, -/* UNIX_DES */ {"des", _ALL_ON_^(0260420000), 0, 1}, +/* symbol token name ctrl mask ctrl * + * --------------------------- -------------------- ------------------------- ---------------- */ + +/* 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_^(060ULL), 020, 0}, +/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060ULL), 040, 0}, +/* UNIX_AUTHTOK_TYPE */ {"authtok_type=", _ALL_ON_, 0100, 0}, +/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600ULL), 0200, 0}, +/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600ULL), 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_^(015660420000ULL), 020000, 1}, +/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000ULL), 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_^(015660420000ULL), 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_^(015660420000ULL), 020000000, 1}, +/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(015660420000ULL), 040000000, 1}, +/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0}, +/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(015660420000ULL), 0200000000, 1}, +/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0}, +/* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0}, +/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0}, +/* UNIX_DES */ {"des", _ALL_ON_^(015660420000ULL), 0, 1}, +/* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1}, +/* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) @@ -151,20 +155,23 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = _pam_drop(xx); \ } -extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl - ,int type, const char *text); -extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int *rounds, - int *pass_min_len, int argc, const char **argv); +extern int _make_remark(pam_handle_t * pamh, unsigned long long ctrl, + int type, const char *text); +extern unsigned long long _set_ctrl(pam_handle_t * pamh, int flags, + int *remember, int *rounds, + int *pass_min_len, + int argc, const char **argv); extern int _unix_getpwnam (pam_handle_t *pamh, const char *name, int files, int nis, struct passwd **ret); extern int _unix_comesfromsource (pam_handle_t *pamh, const char *name, int files, int nis); -extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl, +extern int _unix_blankpasswd(pam_handle_t *pamh, unsigned long long ctrl, const char *name); -extern int _unix_verify_password(pam_handle_t * pamh, const char *name - ,const char *p, unsigned int ctrl); +extern int _unix_verify_password(pam_handle_t * pamh, const char *name, + const char *p, unsigned long long ctrl); extern int _unix_run_verify_binary(pam_handle_t *pamh, - unsigned int ctrl, const char *user, int *daysleft); + unsigned long long ctrl, + const char *user, int *daysleft); #endif /* _PAM_UNIX_SUPPORT_H */ -- cgit v1.2.3 From d8d11db2cef65da5d2afa7acf21aa9c8cd88abed Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 27 Nov 2018 16:11:03 +0100 Subject: pam_unix: Use pam_syslog instead of helper_log_err. * modules/pam_unix/passverify.c (verify_pwd_hash): Add pamh argument via PAMH_ARG_DECL. Call pam_syslog() instead of helper_log_err(). * modules/pam_unix/passverify.h: Adjust the declaration of verify_pwd_hash(). * modules/pam_unix/support.c (_unix_verify_password): Add the pamh argument to verify_pwd_hash() call. --- modules/pam_unix/passverify.c | 24 +++++++++++++----------- modules/pam_unix/passverify.h | 6 +++--- modules/pam_unix/support.c | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 2c808eb5..80e32767 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -65,8 +65,8 @@ strip_hpux_aging(char *hash) } } -int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok) +PAMH_ARG_DECL(int verify_pwd_hash, + const char *p, char *hash, unsigned int nullok) { size_t hash_len; char *pp = NULL; @@ -116,11 +116,10 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok) * pam_syslog() needs a pam handle, * but that's not available here. */ - helper_log_err(LOG_ERR, - "pam_unix(verify_pwd_hash): The method " - "for computing the hash \"%.6s\" has been " - "disabled in libcrypt by the preset from " - "the system's vendor and/or administrator.", + pam_syslog(pamh, LOG_ERR, + "The support for password hash \"%.6s\" " + "has been disabled in libcrypt " + "configuration.", hash); } /* @@ -132,12 +131,15 @@ verify_pwd_hash(const char *p, char *hash, unsigned int nullok) * recent implementations of libcrypt. */ if (retval_checksalt == CRYPT_SALT_INVALID) { - helper_log_err(LOG_ERR, - "pam_unix(verify_pwd_hash): The hash \"%.6s\"" - "does not use a method known by the version " - "of libcrypt this system is supplied with.", + pam_syslog(pamh, LOG_ERR, + "The password hash \"%.6s\" is unknown to " + "libcrypt.", hash); } +#else +#ifndef HELPER_COMPILE + (void)pamh; +#endif #endif #ifdef HAVE_CRYPT_R struct crypt_data *cdata; diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index 086c28ac..e9a88fbf 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -12,9 +12,6 @@ #define OLD_PASSWORDS_FILE "/etc/security/opasswd" -int -verify_pwd_hash(const char *p, char *hash, unsigned int nullok); - int is_pwd_shadowed(const struct passwd *pwd); @@ -65,6 +62,9 @@ read_passwords(int fd, int npass, char **passwords); #define PAMH_ARG(...) pamh, __VA_ARGS__ #endif +PAMH_ARG_DECL(int verify_pwd_hash, + const char *p, char *hash, unsigned int nullok); + PAMH_ARG_DECL(char * create_password_hash, const char *password, unsigned long long ctrl, int rounds); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 6894288d..ea5594d2 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -770,7 +770,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } } } else { - retval = verify_pwd_hash(p, salt, off(UNIX__NONULL, ctrl)); + retval = verify_pwd_hash(pamh, p, salt, off(UNIX__NONULL, ctrl)); } if (retval == PAM_SUCCESS) { -- cgit v1.2.3 From 00b38702c70ad3847a2b3d38930a6a390df81645 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 10 Dec 2018 16:41:47 +0100 Subject: Move the duplicated search_key function to pam_modutil. * libpam/pam_modutil_searchkey.c: New source file with pam_modutil_search_key(). * libpam/Makefile.am: Add the pam_modutil_searchkey.c. * libpam/include/security/pam_modutil.h: Add the pam_modutil_search_key() prototype. * libpam/libpam.map: Add the pam_modutil_search_key() into a new version. * modules/pam_faildelay/pam_faildelay.c: Drop search_key() and use pam_modutil_search_key(). * modules/pam_umask/pam_umask.c: Likewise. * modules/pam_unix/support.c: Likewise. --- libpam/Makefile.am | 2 +- libpam/include/security/pam_modutil.h | 6 +++ libpam/libpam.map | 5 ++ libpam/pam_modutil_searchkey.c | 91 +++++++++++++++++++++++++++++++++++ modules/pam_faildelay/pam_faildelay.c | 75 +---------------------------- modules/pam_umask/pam_umask.c | 80 ++---------------------------- modules/pam_unix/support.c | 78 +----------------------------- 7 files changed, 110 insertions(+), 227 deletions(-) create mode 100644 libpam/pam_modutil_searchkey.c (limited to 'modules/pam_unix/support.c') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 638bb5c4..875031ed 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -38,4 +38,4 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \ - pam_modutil_priv.c pam_modutil_sanitize.c + pam_modutil_priv.c pam_modutil_sanitize.c pam_modutil_searchkey.c diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h index 4ce8c552..3a6aec6a 100644 --- a/libpam/include/security/pam_modutil.h +++ b/libpam/include/security/pam_modutil.h @@ -142,6 +142,12 @@ pam_modutil_sanitize_helper_fds(pam_handle_t *pamh, enum pam_modutil_redirect_fd redirect_stdout, enum pam_modutil_redirect_fd redirect_stderr); +/* lookup a value for key in login.defs file or similar key value format */ +extern char * PAM_NONNULL((1,2,3)) +pam_modutil_search_key(pam_handle_t *pamh, + const char *file_name, + const char *key); + #ifdef __cplusplus } #endif diff --git a/libpam/libpam.map b/libpam/libpam.map index d6835b47..74fb55b2 100644 --- a/libpam/libpam.map +++ b/libpam/libpam.map @@ -72,3 +72,8 @@ LIBPAM_MODUTIL_1.1.9 { global: pam_modutil_sanitize_helper_fds; } LIBPAM_MODUTIL_1.1.3; + +LIBPAM_MODUTIL_1.3.2 { + global: + pam_modutil_search_key; +} LIBPAM_MODUTIL_1.1.9; diff --git a/libpam/pam_modutil_searchkey.c b/libpam/pam_modutil_searchkey.c new file mode 100644 index 00000000..338b44fd --- /dev/null +++ b/libpam/pam_modutil_searchkey.c @@ -0,0 +1,91 @@ +/* + * This file implements the following functions: + * pam_modutil_search_key: + * lookup a value for key in login.defs file or similar key value format + */ + +#include "config.h" + +#include "pam_private.h" +#include "pam_modutil_private.h" +#include +#include +#include +#include +#include + +#define BUF_SIZE 8192 + +/* lookup a value for key in login.defs file or similar key value format */ +char * +pam_modutil_search_key(pam_handle_t *pamh UNUSED, + const char *file_name, + const char *key) +{ + FILE *fp; + char *buf = NULL; + size_t buflen = 0; + char *retval = NULL; + + fp = fopen(file_name, "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; + if (cp[n - 1] == '\n') + cp[n - 1] = '\0'; + + 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; + + tmp = strsep (&cp, " \t="); + if (cp != NULL) + while (isspace((int)*cp) || *cp == '=') + ++cp; + else + cp = ""; + + if (strcasecmp(tmp, key) == 0) { + retval = strdup(cp); + break; + } + } + fclose(fp); + + free(buf); + + return retval; +} diff --git a/modules/pam_faildelay/pam_faildelay.c b/modules/pam_faildelay/pam_faildelay.c index 7ea8f837..215074b2 100644 --- a/modules/pam_faildelay/pam_faildelay.c +++ b/modules/pam_faildelay/pam_faildelay.c @@ -75,81 +75,10 @@ #include #include +#include - -#define BUF_SIZE 8192 #define LOGIN_DEFS "/etc/login.defs" -static char * -search_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); - } - 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, "FAIL_DELAY") == 0) - { - retval = strdup (cp); - break; - } - } - fclose (fp); - - free (buf); - - return retval; -} - - /* --- authentication management functions (only) --- */ int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, @@ -171,7 +100,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, if (delay == -1) { char *endptr; - char *val = search_key (LOGIN_DEFS); + char *val = pam_modutil_search_key (pamh, LOGIN_DEFS, "FAIL_DELAY"); const char *val_orig = val; if (val == NULL) diff --git a/modules/pam_umask/pam_umask.c b/modules/pam_umask/pam_umask.c index ab490645..3dcc5b10 100644 --- a/modules/pam_umask/pam_umask.c +++ b/modules/pam_umask/pam_umask.c @@ -56,7 +56,6 @@ #include #include -#define BUF_SIZE 4096 #define LOGIN_DEFS "/etc/login.defs" #define LOGIN_CONF "/etc/default/login" @@ -86,81 +85,8 @@ parse_option (const pam_handle_t *pamh, const char *argv, options_t *options) pam_syslog (pamh, LOG_ERR, "Unknown option: `%s'", argv); } -static char * -search_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, "UMASK") == 0) - { - retval = strdup (cp); - break; - } - } - fclose (fp); - - free (buf); - - return retval; -} - static int -get_options (const pam_handle_t *pamh, options_t *options, +get_options (pam_handle_t *pamh, options_t *options, int argc, const char **argv) { memset (options, 0, sizeof (options_t)); @@ -169,9 +95,9 @@ get_options (const pam_handle_t *pamh, options_t *options, parse_option (pamh, *argv, options); if (options->umask == NULL) - options->umask = search_key (LOGIN_DEFS); + options->umask = pam_modutil_search_key (pamh, LOGIN_DEFS, "UMASK"); if (options->umask == NULL) - options->umask = search_key (LOGIN_CONF); + options->umask = pam_modutil_search_key (pamh, LOGIN_CONF, "UMASK"); return 0; } diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index ea5594d2..75851508 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -31,80 +31,6 @@ #include "support.h" #include "passverify.h" -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 long long ctrl, @@ -154,7 +80,7 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, } /* preset encryption method with value from /etc/login.defs */ - val = search_key ("ENCRYPT_METHOD", LOGIN_DEFS); + val = pam_modutil_search_key(pamh, LOGIN_DEFS, "ENCRYPT_METHOD"); if (val) { for (j = 0; j < UNIX_CTRLS_; ++j) { if (unix_args[j].token && unix_args[j].is_hash_algo @@ -172,7 +98,7 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, /* read number of rounds for crypt algo */ if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) { - val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS); + val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS"); if (val) { *rounds = strtol(val, NULL, 10); -- cgit v1.2.3 From 65816326c285c5d5eec51766e1de329f177c28f7 Mon Sep 17 00:00:00 2001 From: Florian Best Date: Wed, 26 Jun 2019 13:49:23 +0200 Subject: Trim password at PAM_MAX_RESP_SIZE chars Issue #118: Protect against Denial of Service attacks. To prevent hashsum generation via crypt of very long passwords the password is now stripped to 512 characters. This is equivalent behavior to unix_chkpwd. --- modules/pam_unix/support.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 75851508..e5415f59 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -646,6 +646,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name struct passwd *pwd = NULL; char *salt = NULL; char *data_name; + char pw[MAX_PASS + 1]; int retval; @@ -672,6 +673,11 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); } + if (p != NULL && strlen(p) > MAX_PASS) { + memset(pw, 0, sizeof(pw)); + p = strncpy(pw, p, sizeof(pw) - 1); + } + if (retval != PAM_SUCCESS) { if (retval == PAM_UNIX_RUN_HELPER) { D(("running helper binary")); @@ -781,6 +787,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name } cleanup: + memset(pw, 0, sizeof(pw)); /* clear memory of the password */ if (data_name) _pam_delete(data_name); if (salt) -- cgit v1.2.3 From 5caf76b1655c22e28d1167b786f741ed47f301b1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 27 Jun 2019 19:00:41 +0200 Subject: pam_unix: Correct MAXPASS define name in the previous two commits. * modules/pam_unix/pam_unix_passwd.c: Change MAX_PASS to MAXPASS. * modules/pam_unix/support.c: Likewise. --- modules/pam_unix/pam_unix_passwd.c | 2 +- modules/pam_unix/support.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 4d2f5e2c..4bb1bc56 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -577,7 +577,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh } } - if (strlen(pass_new) > MAX_PASS) { + if (strlen(pass_new) > MAXPASS) { remark = _("You must choose a shorter password."); D(("length exceeded [%s]", remark)); } else if (off(UNIX__IAMROOT, ctrl)) { diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index e5415f59..81c7651c 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -646,7 +646,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name struct passwd *pwd = NULL; char *salt = NULL; char *data_name; - char pw[MAX_PASS + 1]; + char pw[MAXPASS + 1]; int retval; @@ -673,7 +673,7 @@ int _unix_verify_password(pam_handle_t * pamh, const char *name strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name); } - if (p != NULL && strlen(p) > MAX_PASS) { + if (p != NULL && strlen(p) > MAXPASS) { memset(pw, 0, sizeof(pw)); p = strncpy(pw, p, sizeof(pw) - 1); } -- cgit v1.2.3 From f87a953d223d5305adfe3bbb00b4c037c9ae7cd3 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 10 Oct 2019 11:11:14 +0200 Subject: pam_unix: Fix the spelling of Jan RÄ™korajski's name. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/pam_unix/CHANGELOG | 18 +++++++++--------- modules/pam_unix/pam_unix_acct.c | 2 +- modules/pam_unix/pam_unix_auth.c | 2 +- modules/pam_unix/pam_unix_passwd.c | 2 +- modules/pam_unix/pam_unix_sess.c | 2 +- modules/pam_unix/passverify.c | 2 +- modules/pam_unix/support.c | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/CHANGELOG b/modules/pam_unix/CHANGELOG index c18acc27..f8f70f59 100644 --- a/modules/pam_unix/CHANGELOG +++ b/modules/pam_unix/CHANGELOG @@ -1,6 +1,6 @@ $Id$ -* Mon Aug 16 1999 Jan Rêkorajski +* Mon Aug 16 1999 Jan RÄ™korajski - fixed reentrancy problems * Sun Jul 4 21:03:42 PDT 1999 @@ -15,7 +15,7 @@ $Id$ * Sun Jun 27 1999 Steve Langasek - fix to uid-handling code for NIS+ -* Sat Jun 26 1999 Jan Rêkorajski +* Sat Jun 26 1999 Jan RÄ™korajski - merged MD5 fix and early failure syslog by Andrey Vladimirovich Savochkin - minor fixes @@ -24,31 +24,31 @@ $Id$ * Fri Jun 25 1999 Stephen Langasek - reorganized the code to let it build as separate C files -* Sun Jun 20 1999 Jan Rêkorajski +* Sun Jun 20 1999 Jan RÄ™korajski - fixes in pam_unix_auth, it incorrectly saved and restored return value when likeauth option was used -* Tue Jun 15 1999 Jan Rêkorajski +* Tue Jun 15 1999 Jan RÄ™korajski - added NIS+ support -* Mon Jun 14 1999 Jan Rêkorajski +* Mon Jun 14 1999 Jan RÄ™korajski - total rewrite based on pam_pwdb module, now there is ONE pam_unix.so module, it accepts the same options as pam_pwdb - all of them correctly ;) (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means) -* Tue Apr 20 1999 Jan Rêkorajski +* Tue Apr 20 1999 Jan RÄ™korajski - Arghhh, pam_unix_passwd was not updating /etc/shadow when used with pam_cracklib. -* Mon Apr 19 1999 Jan Rêkorajski +* Mon Apr 19 1999 Jan RÄ™korajski - added "remember=XXX" option that means 'remember XXX old passwords' Old passwords are stored in /etc/security/opasswd, there can be maximum of 400 passwords per user. -* Sat Mar 27 1999 Jan Rêkorajski +* Sat Mar 27 1999 Jan RÄ™korajski - added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm is too lame to use it in real life) -* Sun Mar 21 1999 Jan Rêkorajski +* Sun Mar 21 1999 Jan RÄ™korajski - pam_unix_auth now correctly behave when user has NULL AUTHTOK - pam_unix_auth returns PAM_PERM_DENIED when seteuid fails diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index d8d084ac..e99c2d03 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -1,6 +1,6 @@ /* * Copyright Elliot Lee, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c index 905fc66c..681e49db 100644 --- a/modules/pam_unix/pam_unix_auth.c +++ b/modules/pam_unix/pam_unix_auth.c @@ -1,7 +1,7 @@ /* * Copyright Alexander O. Yuriev, 1996. All rights reserved. * NIS+ support by Thorsten Kukuk - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 4bb1bc56..87db7cf1 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -1,7 +1,7 @@ /* * Main coding by Elliot Lee , Red Hat Software. * Copyright (C) 1996. - * Copyright (c) Jan Rêkorajski, 1999. + * Copyright (c) Jan RÄ™korajski, 1999. * Copyright (c) Red Hat, Inc., 2007, 2008. * * Redistribution and use in source and binary forms, with or without diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c index 71f5594d..437d1242 100644 --- a/modules/pam_unix/pam_unix_sess.c +++ b/modules/pam_unix/pam_unix_sess.c @@ -2,7 +2,7 @@ * $Id$ * * Copyright Alexander O. Yuriev, 1996. All rights reserved. - * Copyright Jan Rêkorajski, 1999. All rights reserved. + * Copyright Jan RÄ™korajski, 1999. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 80e32767..2f9a4306 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -1217,7 +1217,7 @@ read_passwords(int fd, int npass, char **passwords) #endif /* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. + * Copyright (c) Jan RÄ™korajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. * Copyright (c) Alex O. Yuriev, 1996. * Copyright (c) Cristian Gafton 1996. diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 81c7651c..4f15b61b 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -799,7 +799,7 @@ cleanup: } /* ****************************************************************** * - * Copyright (c) Jan Rêkorajski 1999. + * Copyright (c) Jan RÄ™korajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. * Copyright (c) Alex O. Yuriev, 1996. * Copyright (c) Cristian Gafton 1996. -- cgit v1.2.3 From 03f46bbe3f22d800a1516f4c535a1bfb573068de Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 16 Dec 2019 10:38:52 +0100 Subject: Fix or suppress various warnings when compiling with -Wall -Wextra * conf/pam_conv1/Makefile.am: Add -Wno-unused-function -Wno-sign-compare to CFLAGS. * doc/specs/Makefile.am: Likewise. * libpamc/include/security/pam_client.h: Explicitly compare old_p with NULL. * modules/pam_access/pam_access.c: Avoid double const. * modules/pam_filter/pam_filter.c: Avoid arbitrary constants. Avoid strncpy() without copying the NUL byte. * modules/pam_group/pam_group.c: Mark switch fallthrough with comment. * modules/pam_time/pam_time.c: Likewise. * modules/pam_limits/pam_limits.c: Remove unused units variable. * modules/pam_listfile/pam_listfile.c: Avoid unnecessary strncpy, use pointers. * modules/pam_rootok/pam_rootok.c (log_callback): Mark unused parameter. * modules/pam_selinux/pam_selinux.c: Use string_to_security_class() instead of hardcoded value. * modules/pam_sepermit/pam_sepermit.c: Properly cast when comparing. * modules/pam_succeed_if/pam_succeed_if.c: Mark unused parameters. * modules/pam_unix/pam_unix_passwd.c: Remove unused variables and properly cast for comparison. * modules/pam_unix/support.c: Remove unused function. --- conf/pam_conv1/Makefile.am | 2 ++ doc/specs/Makefile.am | 2 ++ libpamc/include/security/pam_client.h | 2 +- modules/pam_access/pam_access.c | 2 +- modules/pam_filter/pam_filter.c | 16 ++++++++-------- modules/pam_group/pam_group.c | 1 + modules/pam_limits/pam_limits.c | 7 ++----- modules/pam_listfile/pam_listfile.c | 9 ++++----- modules/pam_rootok/pam_rootok.c | 2 +- modules/pam_selinux/pam_selinux.c | 4 +--- modules/pam_sepermit/pam_sepermit.c | 2 +- modules/pam_succeed_if/pam_succeed_if.c | 11 +++++++++-- modules/pam_time/pam_time.c | 1 + modules/pam_unix/pam_unix_passwd.c | 10 +++++----- modules/pam_unix/support.c | 5 ----- 15 files changed, 39 insertions(+), 37 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/conf/pam_conv1/Makefile.am b/conf/pam_conv1/Makefile.am index ce50b686..2e643306 100644 --- a/conf/pam_conv1/Makefile.am +++ b/conf/pam_conv1/Makefile.am @@ -8,6 +8,8 @@ EXTRA_DIST = README AM_YFLAGS = -d +pam_conv1_CFLAGS = -Wno-unused-function -Wno-sign-compare + BUILT_SOURCES = pam_conv_y.h noinst_PROGRAMS = pam_conv1 diff --git a/doc/specs/Makefile.am b/doc/specs/Makefile.am index 99ecc70e..de20decd 100644 --- a/doc/specs/Makefile.am +++ b/doc/specs/Makefile.am @@ -16,6 +16,8 @@ CPPFLAGS = @BUILD_CPPFLAGS@ CFLAGS = @BUILD_CFLAGS@ LDFLAGS = @BUILD_LDFLAGS@ +padout_CFLAGS = -Wno-unused-function -Wno-sign-compare + BUILT_SOURCES = parse_y.h noinst_PROGRAMS = padout diff --git a/libpamc/include/security/pam_client.h b/libpamc/include/security/pam_client.h index 47e41aaf..86672a2e 100644 --- a/libpamc/include/security/pam_client.h +++ b/libpamc/include/security/pam_client.h @@ -109,7 +109,7 @@ char **pamc_list_agents(pamc_handle_t pch); #define PAM_BP_RENEW(old_p, cntrl, data_length) \ do { \ - if (old_p) { \ + if ((old_p) != NULL) { \ if (*(old_p)) { \ u_int32_t __size; \ __size = PAM_BP_SIZE(*(old_p)); \ diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c index 80d885dd..128da01d 100644 --- a/modules/pam_access/pam_access.c +++ b/modules/pam_access/pam_access.c @@ -806,7 +806,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, const char *user=NULL; const void *void_from=NULL; const char *from; - const char const *default_config = PAM_ACCESS_CONFIG; + const char *default_config = PAM_ACCESS_CONFIG; struct passwd *user_pw; char hostname[MAXHOSTNAMELEN + 1]; int rv; diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c index 8ab7981a..de8c35ad 100644 --- a/modules/pam_filter/pam_filter.c +++ b/modules/pam_filter/pam_filter.c @@ -120,8 +120,8 @@ static int process_args(pam_handle_t *pamh /* the "ARGS" variable */ -#define ARGS_OFFSET 5 /* strlen('ARGS='); */ #define ARGS_NAME "ARGS=" +#define ARGS_OFFSET (sizeof(ARGS_NAME) - 1) size += ARGS_OFFSET; @@ -134,7 +134,7 @@ static int process_args(pam_handle_t *pamh return -1; } - strncpy(levp[0],ARGS_NAME,ARGS_OFFSET); + strcpy(levp[0], ARGS_NAME); for (i=0,size=ARGS_OFFSET; i terminate */ /* the "USER" variable */ -#define USER_OFFSET 5 /* strlen('USER='); */ #define USER_NAME "USER=" +#define USER_OFFSET (sizeof(USER_NAME) - 1) if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL) { @@ -194,14 +194,14 @@ static int process_args(pam_handle_t *pamh return -1; } - strncpy(levp[2],USER_NAME,USER_OFFSET); + strcpy(levp[2], USER_NAME); strcpy(levp[2]+USER_OFFSET, user); levp[2][size] = '\0'; /* terminate */ /* the "USER" variable */ -#define TYPE_OFFSET 5 /* strlen('TYPE='); */ #define TYPE_NAME "TYPE=" +#define TYPE_OFFSET (sizeof(TYPE_NAME) - 1) size = TYPE_OFFSET+strlen(type); @@ -217,7 +217,7 @@ static int process_args(pam_handle_t *pamh return -1; } - strncpy(levp[3],TYPE_NAME,TYPE_OFFSET); + strcpy(levp[3], TYPE_NAME); strcpy(levp[3]+TYPE_OFFSET, type); levp[3][size] = '\0'; /* terminate */ diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c index 8cd178c0..66252c78 100644 --- a/modules/pam_group/pam_group.c +++ b/modules/pam_group/pam_group.c @@ -183,6 +183,7 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) ++src; /* skip it */ break; } + /* fallthrough */ default: *to++ = c; onspace = 0; diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c index cac36999..02967f36 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -384,7 +384,7 @@ static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int FILE *limitsfile; const char *proclimits = "/proc/1/limits"; char line[256]; - char *units, *hard, *soft, *name; + char *hard, *soft, *name; if (!(limitsfile = fopen(proclimits, "r"))) { pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM defaults", proclimits, strerror(errno)); @@ -410,10 +410,7 @@ static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int if (pos == maxlen) { /* step backwards over "Units" name */ LIMITS_SKIP_WHITESPACE; - LIMITS_MARK_ITEM(units); - } - else { - units = ""; + LIMITS_MARK_ITEM(hard); /* not a typo, units unused */ } /* step backwards over "Hard Limit" value */ diff --git a/modules/pam_listfile/pam_listfile.c b/modules/pam_listfile/pam_listfile.c index 5723598e..1fe5f495 100644 --- a/modules/pam_listfile/pam_listfile.c +++ b/modules/pam_listfile/pam_listfile.c @@ -65,14 +65,14 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, char mybuf[256],myval[256]; struct stat fileinfo; FILE *inf; - char apply_val[256]; + const char *apply_val; int apply_type; /* Stuff for "extended" items */ struct passwd *userinfo; apply_type=APPLY_TYPE_NULL; - memset(apply_val,0,sizeof(apply_val)); + apply_val=""; for(i=0; i < argc; i++) { { @@ -140,13 +140,12 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, citem = 0; } else if(!strcmp(mybuf,"apply")) { apply_type=APPLY_TYPE_NONE; - memset(apply_val,'\0',sizeof(apply_val)); if (myval[0]=='@') { apply_type=APPLY_TYPE_GROUP; - strncpy(apply_val,myval+1,sizeof(apply_val)-1); + apply_val=myval+1; } else { apply_type=APPLY_TYPE_USER; - strncpy(apply_val,myval,sizeof(apply_val)-1); + apply_val=myval; } } else { free(ifname); diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c index 17baabe4..80a67f6d 100644 --- a/modules/pam_rootok/pam_rootok.c +++ b/modules/pam_rootok/pam_rootok.c @@ -61,7 +61,7 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv) #ifdef WITH_SELINUX static int -log_callback (int type, const char *fmt, ...) +log_callback (int type UNUSED, const char *fmt, ...) { int audit_fd; va_list ap; diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c index 9b3fe22e..5affec4f 100644 --- a/modules/pam_selinux/pam_selinux.c +++ b/modules/pam_selinux/pam_selinux.c @@ -63,8 +63,6 @@ #include #include -#include -#include #include #include #include @@ -591,7 +589,7 @@ compute_tty_context(const pam_handle_t *pamh, module_data_t *data) } if (security_compute_relabel(data->exec_context, data->prev_tty_context, - SECCLASS_CHR_FILE, &data->tty_context)) { + string_to_security_class("chr_file"), &data->tty_context)) { data->tty_context = NULL; pam_syslog(pamh, LOG_ERR, "Failed to compute new context for %s: %m", data->tty_path); diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c index c6532907..f37af0fb 100644 --- a/modules/pam_sepermit/pam_sepermit.c +++ b/modules/pam_sepermit/pam_sepermit.c @@ -353,7 +353,7 @@ sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user, if (*sense == PAM_SUCCESS) { if (ignore) *sense = PAM_IGNORE; - if (geteuid() == 0 && exclusive && get_loginuid(pamh) == -1) + if (geteuid() == 0 && exclusive && get_loginuid(pamh) == (uid_t)-1) if (sepermit_lock(pamh, user, debug) < 0) *sense = PAM_AUTH_ERR; } diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c index afa61b3e..2a791d26 100644 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ b/modules/pam_succeed_if/pam_succeed_if.c @@ -229,9 +229,16 @@ evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *group) return PAM_SUCCESS; return PAM_AUTH_ERR; } + +#ifdef HAVE_INNETGR +# define SOMETIMES_UNUSED UNUSED +#else +# define SOMETIMES_UNUSED +#endif + /* Return PAM_SUCCESS if the (host,user) is in the netgroup. */ static int -evaluate_innetgr(const pam_handle_t* pamh, const char *host, const char *user, const char *group) +evaluate_innetgr(const pam_handle_t* pamh SOMETIMES_UNUSED, const char *host, const char *user, const char *group) { #ifdef HAVE_INNETGR if (innetgr(group, host, user, NULL) == 1) @@ -244,7 +251,7 @@ evaluate_innetgr(const pam_handle_t* pamh, const char *host, const char *user, c } /* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */ static int -evaluate_notinnetgr(const pam_handle_t* pamh, const char *host, const char *user, const char *group) +evaluate_notinnetgr(const pam_handle_t* pamh SOMETIMES_UNUSED, const char *host, const char *user, const char *group) { #ifdef HAVE_INNETGR if (innetgr(group, host, user, NULL) == 0) diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c index 26a374b5..4863ea4e 100644 --- a/modules/pam_time/pam_time.c +++ b/modules/pam_time/pam_time.c @@ -213,6 +213,7 @@ read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) ++src; /* skip it */ break; } + /* fallthrough */ default: *to++ = c; onspace = 0; diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 99a4c40f..93300f46 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -350,7 +350,7 @@ 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 *s_luser, *s_uid, *s_npas, *s_pas; + char *s_pas; int retval = PAM_SUCCESS; FILE *opwfile; size_t len = strlen(forwho); @@ -364,9 +364,9 @@ static int check_old_password(const char *forwho, const char *newpass) 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_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); @@ -581,7 +581,7 @@ 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 (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)); if (on(UNIX_REMEMBER_PASSWD, ctrl)) { diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 4f15b61b..814d4c08 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -211,11 +211,6 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, return ctrl; } -static void _cleanup(pam_handle_t * pamh UNUSED, void *x, int error_status UNUSED) -{ - _pam_delete(x); -} - /* ************************************************************** * * Useful non-trivial functions * * ************************************************************** */ -- cgit v1.2.3 From df86351adfbe6a5dc7a68dce1074403f97fd1046 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Sat, 18 Jan 2020 00:35:14 +0000 Subject: Fix remaining -Wcast-qual compilation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a new internal header file with definitions of DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL macros, use them to temporary silence -Wcast-qual compilation warnings in various modules. * libpam/include/pam_cc_compat.h: New file. * libpam/Makefile.am (noinst_HEADERS): Add include/pam_cc_compat.h. * modules/pam_mkhomedir/pam_mkhomedir.c: Include "pam_cc_compat.h". (create_homedir): Wrap execve invocation in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_namespace/pam_namespace.c: Include "pam_cc_compat.h". (pam_sm_close_session): Wrap the cast that discards ‘const’ qualifier in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_tty_audit/pam_tty_audit.c: Include "pam_cc_compat.h". (nl_send): Wrap the cast that discards ‘const’ qualifier in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_unix/pam_unix_acct.c: Include "pam_cc_compat.h". (_unix_run_verify_binary): Wrap execve invocation in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_unix/pam_unix_passwd.c: Include "pam_cc_compat.h". (_unix_run_update_binary): Wrap execve invocation in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_unix/passverify.c: Include "pam_cc_compat.h". (unix_update_shadow): Wrap the cast that discards ‘const’ qualifier in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_unix/support.c: Include "pam_cc_compat.h". (_unix_run_helper_binary): Wrap execve invocation in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. * modules/pam_xauth/pam_xauth.c: Include "pam_cc_compat.h". (run_coprocess): Wrap execv invocation in DIAG_PUSH_IGNORE_CAST_QUAL and DIAG_POP_IGNORE_CAST_QUAL. --- libpam/Makefile.am | 2 +- libpam/include/pam_cc_compat.h | 35 +++++++++++++++++++++++++++++++++++ modules/pam_mkhomedir/pam_mkhomedir.c | 4 ++++ modules/pam_namespace/pam_namespace.c | 3 +++ modules/pam_tty_audit/pam_tty_audit.c | 4 ++++ modules/pam_unix/pam_unix_acct.c | 3 +++ modules/pam_unix/pam_unix_passwd.c | 3 +++ modules/pam_unix/passverify.c | 3 +++ modules/pam_unix/support.c | 3 +++ modules/pam_xauth/pam_xauth.c | 4 ++++ 10 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 libpam/include/pam_cc_compat.h (limited to 'modules/pam_unix/support.c') diff --git a/libpam/Makefile.am b/libpam/Makefile.am index d9f9e041..9d5c844d 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -23,7 +23,7 @@ include_HEADERS = include/security/_pam_compat.h \ include/security/pam_ext.h include/security/pam_modutil.h noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ - pam_modutil_private.h + pam_modutil_private.h include/pam_cc_compat.h libpam_la_LDFLAGS = -no-undefined -version-info 84:2:84 libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ diff --git a/libpam/include/pam_cc_compat.h b/libpam/include/pam_cc_compat.h new file mode 100644 index 00000000..a4b84c62 --- /dev/null +++ b/libpam/include/pam_cc_compat.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Dmitry V. Levin + */ + +#ifndef PAM_CC_COMPAT_H +#define PAM_CC_COMPAT_H + +#include "config.h" +#include + +#if defined __clang__ && defined __clang_major__ && defined __clang_minor__ +# define PAM_CLANG_PREREQ(maj, min) \ + ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min)) +#else +# define PAM_CLANG_PREREQ(maj, min) 0 +#endif + +#if PAM_GNUC_PREREQ(4, 6) +# define DIAG_PUSH_IGNORE_CAST_QUAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +# define DIAG_POP_IGNORE_CAST_QUAL \ + _Pragma("GCC diagnostic pop") +#elif PAM_CLANG_PREREQ(2, 6) +# define DIAG_PUSH_IGNORE_CAST_QUAL \ + _Pragma("clang diagnostic push"); \ + _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +# define DIAG_POP_IGNORE_CAST_QUAL \ + _Pragma("clang diagnostic pop") +#else +# define DIAG_PUSH_IGNORE_CAST_QUAL /* empty */ +# define DIAG_POP_IGNORE_CAST_QUAL /* empty */ +#endif + +#endif /* PAM_CC_COMPAT_H */ diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index aec1e7e5..1a4dab47 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -58,6 +58,8 @@ #include #include +#include "pam_cc_compat.h" + /* argument parsing */ #define MKHOMEDIR_DEBUG 020 /* be verbose about things */ #define MKHOMEDIR_QUIET 040 /* keep quiet about things */ @@ -143,7 +145,9 @@ create_homedir (pam_handle_t *pamh, options_t *opt, args[2] = opt->umask; args[3] = opt->skeldir; + DIAG_PUSH_IGNORE_CAST_QUAL; execve(MKHOMEDIR_HELPER, (char **)args, envp); + DIAG_POP_IGNORE_CAST_QUAL; /* should not get here: exit with error */ D(("helper binary is not available")); diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c index d49dc621..155d3965 100644 --- a/modules/pam_namespace/pam_namespace.c +++ b/modules/pam_namespace/pam_namespace.c @@ -34,6 +34,7 @@ #define _ATFILE_SOURCE +#include "pam_cc_compat.h" #include "pam_namespace.h" #include "argv_parse.h" @@ -2230,7 +2231,9 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, /* nothing to reset */ return PAM_SUCCESS; + DIAG_PUSH_IGNORE_CAST_QUAL; idata.polydirs_ptr = (void *)polyptr; + DIAG_POP_IGNORE_CAST_QUAL; if (idata.flags & PAMNS_DEBUG) pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d", diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c index 79e5d511..7dbcada2 100644 --- a/modules/pam_tty_audit/pam_tty_audit.c +++ b/modules/pam_tty_audit/pam_tty_audit.c @@ -54,6 +54,8 @@ #include #include +#include "pam_cc_compat.h" + #define DATANAME "pam_tty_audit_last_state" /* Open an audit netlink socket */ @@ -79,7 +81,9 @@ nl_send (int fd, unsigned type, unsigned flags, const void *data, size_t size) nlm.nlmsg_pid = 0; iov[0].iov_base = &nlm; iov[0].iov_len = sizeof (nlm); + DIAG_PUSH_IGNORE_CAST_QUAL; iov[1].iov_base = (void *)data; + DIAG_POP_IGNORE_CAST_QUAL; iov[1].iov_len = size; addr.nl_family = AF_NETLINK; addr.nl_pid = 0; diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index e99c2d03..36f68eff 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -59,6 +59,7 @@ #include #include +#include "pam_cc_compat.h" #include "support.h" #include "passverify.h" @@ -127,7 +128,9 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl, args[1] = user; args[2] = "chkexpiry"; + DIAG_PUSH_IGNORE_CAST_QUAL; execve(CHKPWD_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m"); /* should not get here: exit with error */ diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 93300f46..636ace97 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -70,6 +70,7 @@ #include #include +#include "pam_cc_compat.h" #include "md5.h" #include "support.h" #include "passverify.h" @@ -293,7 +294,9 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl, snprintf(buffer, sizeof(buffer), "%d", remember); args[4] = buffer; + DIAG_PUSH_IGNORE_CAST_QUAL; execve(UPDATE_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; /* should not get here: exit with error */ D(("helper binary is not available")); diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 67f9e6f7..65307e11 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -25,6 +25,7 @@ #include #endif +#include "pam_cc_compat.h" #include "md5.h" #include "bigcrypt.h" #include "passverify.h" @@ -1020,7 +1021,9 @@ PAMH_ARG_DECL(int unix_update_shadow, fclose(opwfile); if (!wroteentry && !err) { + DIAG_PUSH_IGNORE_CAST_QUAL; spwdent.sp_namp = (char *)forwho; + DIAG_POP_IGNORE_CAST_QUAL; spwdent.sp_pwdp = towhat; spwdent.sp_lstchg = time(NULL) / (60 * 60 * 24); if (spwdent.sp_lstchg == 0) diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 814d4c08..33761840 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -28,6 +28,7 @@ #include #include +#include "pam_cc_compat.h" #include "support.h" #include "passverify.h" @@ -526,7 +527,9 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, args[2]="nonull"; } + DIAG_PUSH_IGNORE_CAST_QUAL; execve(CHKPWD_HELPER, (char *const *) args, envp); + DIAG_POP_IGNORE_CAST_QUAL; /* should not get here: exit with error */ D(("helper binary is not available")); diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c index 3339def8..61e98253 100644 --- a/modules/pam_xauth/pam_xauth.c +++ b/modules/pam_xauth/pam_xauth.c @@ -65,6 +65,8 @@ #include #endif +#include "pam_cc_compat.h" + #define DATANAME "pam_xauth_cookie_file" #define XAUTHENV "XAUTHORITY" #define HOMEENV "HOME" @@ -179,7 +181,9 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, } } /* Run the command. */ + DIAG_PUSH_IGNORE_CAST_QUAL; execv(command, (char *const *) args); + DIAG_POP_IGNORE_CAST_QUAL; /* Never reached. */ _exit(1); } -- cgit v1.2.3 From f5adefa106e28c92dd73dbabac12bad667ef7b8f Mon Sep 17 00:00:00 2001 From: Pavel BÅ™ezina Date: Thu, 31 Oct 2019 12:26:31 +0100 Subject: pam_unix: add nullresetok option to allow reset blank passwords Adding nullresetok to auth phase of pam_unix module will allow users with blank password to authenticate in order to immediatelly change their password even if nullok is not set. This allows to have blank password authentication disabled but still allows administrator to create new user accounts with expired blank password that must be change on the first login. --- modules/pam_unix/pam_unix.8.xml | 13 +++++++++++ modules/pam_unix/pam_unix_acct.c | 26 +--------------------- modules/pam_unix/support.c | 47 ++++++++++++++++++++++++++++++++++++++++ modules/pam_unix/support.h | 7 +++++- 4 files changed, 67 insertions(+), 26 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml index 93a01c89..607ec85c 100644 --- a/modules/pam_unix/pam_unix.8.xml +++ b/modules/pam_unix/pam_unix.8.xml @@ -163,6 +163,19 @@ + + + + + + + Allow users to authenticate with blank password if password reset + is enforced even if is not set. If password + reset is not required and is not set the + authentication with blank password will be denied. + + + diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 36f68eff..0c5dff96 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -192,8 +192,6 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) const void *void_uname; const char *uname; int retval, daysleft; - struct spwd *spent; - struct passwd *pwent; char buf[256]; D(("called.")); @@ -210,29 +208,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_USER_UNKNOWN; } - retval = get_account_info(pamh, uname, &pwent, &spent); - if (retval == PAM_USER_UNKNOWN) { - pam_syslog(pamh, LOG_ERR, - "could not identify user (from getpwnam(%s))", - uname); - return retval; - } - - if (retval == PAM_SUCCESS && spent == NULL) - return PAM_SUCCESS; - - if (retval == PAM_UNIX_RUN_HELPER) { - retval = _unix_run_verify_binary(pamh, ctrl, uname, &daysleft); - if (retval == PAM_AUTHINFO_UNAVAIL && - on(UNIX_BROKEN_SHADOW, ctrl)) - return PAM_SUCCESS; - } else if (retval != PAM_SUCCESS) { - if (on(UNIX_BROKEN_SHADOW,ctrl)) - return PAM_SUCCESS; - else - return retval; - } else - retval = check_shadow_expiry(pamh, spent, &daysleft); + retval = _unix_verify_user(pamh, ctrl, uname, &daysleft); if (on(UNIX_NO_PASS_EXPIRY, ctrl)) { const void *pretval = NULL; diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 33761840..6a840a26 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -595,6 +595,7 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name { struct passwd *pwd = NULL; char *salt = NULL; + int daysleft; int retval; D(("called")); @@ -605,6 +606,15 @@ _unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name * else (CG) */ + if (on(UNIX_NULLRESETOK, ctrl)) { + retval = _unix_verify_user(pamh, ctrl, name, &daysleft); + if (retval == PAM_NEW_AUTHTOK_REQD) { + /* password reset is enforced, allow authentication with empty password */ + pam_syslog(pamh, LOG_DEBUG, "user [%s] has expired blank password, enabling nullok", name); + set(UNIX__NULLOK, ctrl); + } + } + if (on(UNIX__NONULL, ctrl)) return 0; /* will fail but don't let on yet */ @@ -796,6 +806,43 @@ cleanup: return retval; } +int +_unix_verify_user(pam_handle_t *pamh, + unsigned long long ctrl, + const char *name, + int *daysleft) +{ + int retval; + struct spwd *spent; + struct passwd *pwent; + + retval = get_account_info(pamh, name, &pwent, &spent); + if (retval == PAM_USER_UNKNOWN) { + pam_syslog(pamh, LOG_ERR, + "could not identify user (from getpwnam(%s))", + name); + return retval; + } + + if (retval == PAM_SUCCESS && spent == NULL) + return PAM_SUCCESS; + + if (retval == PAM_UNIX_RUN_HELPER) { + retval = _unix_run_verify_binary(pamh, ctrl, name, daysleft); + if (retval == PAM_AUTHINFO_UNAVAIL && + on(UNIX_BROKEN_SHADOW, ctrl)) + return PAM_SUCCESS; + } else if (retval != PAM_SUCCESS) { + if (on(UNIX_BROKEN_SHADOW,ctrl)) + return PAM_SUCCESS; + else + return retval; + } else + retval = check_shadow_expiry(pamh, spent, daysleft); + + return retval; +} + /* ****************************************************************** * * Copyright (c) Jan RÄ™korajski 1999. * Copyright (c) Andrew G. Morgan 1996-8. diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h index e02c05e0..19754dc1 100644 --- a/modules/pam_unix/support.h +++ b/modules/pam_unix/support.h @@ -100,8 +100,9 @@ typedef struct { #define UNIX_DES 30 /* DES, default */ #define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */ #define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */ +#define UNIX_NULLRESETOK 33 /* allow empty password if password reset is enforced */ /* -------------- */ -#define UNIX_CTRLS_ 33 /* number of ctrl arguments defined */ +#define UNIX_CTRLS_ 34 /* number of ctrl arguments defined */ #define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl)) @@ -143,6 +144,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = /* UNIX_DES */ {"des", _ALL_ON_^(015660420000ULL), 0, 1}, /* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1}, /* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1}, +/* UNIX_NULLRESETOK */ {"nullresetok", _ALL_ON_, 020000000000, 0}, }; #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) @@ -171,6 +173,9 @@ extern int _unix_blankpasswd(pam_handle_t *pamh, unsigned long long ctrl, extern int _unix_verify_password(pam_handle_t * pamh, const char *name, const char *p, unsigned long long ctrl); +extern int _unix_verify_user(pam_handle_t *pamh, unsigned long long ctrl, + const char *name, int *daysleft); + extern int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user, int *daysleft); -- cgit v1.2.3 From 9569de568a7eeaf91e2134ee3e1dd00978882903 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Thu, 5 Mar 2020 19:33:12 +0000 Subject: pam_unix: fix --disable-nis compilation warnings When the build is configured using --disable-nis option, gcc complains: pam_unix_passwd.c: In function '_do_setpass': pam_unix_passwd.c:398:8: warning: unused variable 'master' [-Wunused-variable] support.c: In function '_unix_getpwnam': support.c:305:21: warning: parameter 'nis' set but not used [-Wunused-but-set-parameter] * modules/pam_unix/pam_unix_passwd.c (_do_setpass): Move the definition of "master" variable to [HAVE_NIS]. * modules/pam_unix/support.c (_unix_getpwnam) [!(HAVE_YP_GET_DEFAULT_DOMAIN && HAVE_YP_BIND && HAVE_YP_MATCH && HAVE_YP_UNBIND)]: Do not assign the unused parameter but mark it as used. --- modules/pam_unix/pam_unix_passwd.c | 3 ++- modules/pam_unix/support.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index a8eec77a..7985ad1b 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -395,7 +395,6 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, struct passwd *pwd = NULL; int retval = 0; int unlocked = 0; - char *master = NULL; D(("called")); @@ -408,6 +407,8 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { #ifdef HAVE_NIS + char *master; + if ((master=getNISserver(pamh, ctrl)) != NULL) { struct timeval timeout; struct yppasswd yppwd; diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index 6a840a26..a04211cd 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -351,7 +351,7 @@ int _unix_getpwnam(pam_handle_t *pamh, const char *name, } #else /* we don't have NIS support, make compiler happy. */ - nis = 0; + (void) nis; #endif if (matched && (ret != NULL)) { -- cgit v1.2.3 From a49bdd6697c51625a52275fe8616bce0d77431c6 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 16 Mar 2020 21:02:18 +0000 Subject: modules/pam_unix: use pam_str_skip_prefix and pam_str_skip_prefix_len * modules/pam_unix/passverify.c: Include "pam_inline.h". (verify_pwd_hash): Use pam_str_skip_prefix instead of ugly strncmp invocations. * modules/pam_unix/support.c: Include "pam_inline.h". (_set_ctrl): Use pam_str_skip_prefix_len instead of hardcoding string lengths. * modules/pam_unix/md5_crypt.c: Include "pam_inline.h". (crypt_md5): Use pam_str_skip_prefix_len. squash! modules/pam_unix: use pam_str_skip_prefix and pam_str_skip_prefix_len --- modules/pam_unix/md5_crypt.c | 5 +++-- modules/pam_unix/passverify.c | 3 ++- modules/pam_unix/support.c | 14 +++++++++----- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'modules/pam_unix/support.c') diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c index 4ab9ec84..94f7b434 100644 --- a/modules/pam_unix/md5_crypt.c +++ b/modules/pam_unix/md5_crypt.c @@ -15,6 +15,7 @@ #include #include #include "md5.h" +#include "pam_inline.h" static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; @@ -55,8 +56,8 @@ char *MD5Name(crypt_md5)(const char *pw, const char *salt) return NULL; /* If it starts with the magic string, then skip that */ - if (!strncmp(sp, magic, strlen(magic))) - sp += strlen(magic); + if ((ep = pam_str_skip_prefix_len(sp, magic, strlen(magic))) != NULL) + sp = ep; /* It stops at the first '$', max 8 chars */ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 234db341..a571b4f7 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -26,6 +26,7 @@ #endif #include "pam_cc_compat.h" +#include "pam_inline.h" #include "md5.h" #include "bigcrypt.h" #include "passverify.h" @@ -88,7 +89,7 @@ PAMH_ARG_DECL(int verify_pwd_hash, } else if (!p || *hash == '*' || *hash == '!') { retval = PAM_AUTH_ERR; } else { - if (!strncmp(hash, "$1$", 3)) { + if (pam_str_skip_prefix(hash, "$1$") != NULL) { pp = Goodcrypt_md5(p, hash); if (pp && strcmp(pp, hash) != 0) { _pam_delete(pp); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index a04211cd..41db1f04 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -29,6 +29,7 @@ #include #include "pam_cc_compat.h" +#include "pam_inline.h" #include "support.h" #include "passverify.h" @@ -112,17 +113,20 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, /* now parse the arguments to this module */ for (; argc-- > 0; ++argv) { + const char *str = NULL; D(("pam_unix arg: %s", *argv)); for (j = 0; j < UNIX_CTRLS_; ++j) { if (unix_args[j].token - && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) { + && (str = pam_str_skip_prefix_len(*argv, + unix_args[j].token, + strlen(unix_args[j].token))) != NULL) { break; } } - if (j >= UNIX_CTRLS_) { + if (str == NULL) { pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", *argv); } else { @@ -133,7 +137,7 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, "option remember not allowed for this module type"); continue; } - *remember = strtol(*argv + 9, NULL, 10); + *remember = strtol(str, NULL, 10); if ((*remember == INT_MIN) || (*remember == INT_MAX)) *remember = -1; if (*remember > 400) @@ -144,14 +148,14 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember, "option minlen not allowed for this module type"); continue; } - *pass_min_len = atoi(*argv + 7); + *pass_min_len = atoi(str); } else if (j == UNIX_ALGO_ROUNDS) { if (rounds == NULL) { pam_syslog(pamh, LOG_ERR, "option rounds not allowed for this module type"); continue; } - *rounds = strtol(*argv + 7, NULL, 10); + *rounds = strtol(str, NULL, 10); } ctrl &= unix_args[j].mask; /* for turning things off */ -- cgit v1.2.3