diff options
| author | Tomas Mraz <tm@t8m.info> | 2008-01-04 10:38:40 +0000 |
|---|---|---|
| committer | Tomas Mraz <tm@t8m.info> | 2008-01-04 10:38:40 +0000 |
| commit | bc86f86c3d25baf901ab1e4ded71a2e6f9c2a39a (patch) | |
| tree | 8fb531acbdc890db1665b4a5b405819b85c7d69b /modules/pam_unix/passverify.c | |
| parent | b5250a61addf9f93301b9ddf043658b9549803c0 (diff) | |
| download | linux-pam-git-bc86f86c3d25baf901ab1e4ded71a2e6f9c2a39a.tar.gz | |
Relevant BUGIDs:
Purpose of commit: refactorization
Commit summary:
---------------
* modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): Call
get_account_info() and check_shadow_expiry().
* modules/pam_unix/passverify.c: Add get_account_info() to
obtain shadow and passwd entry. Add check_shadow_expiry() to
for shadow password expiry check.
(get_pwd_hash): Call get_account_info().
* modules/pam_unix/passverify.h: Add prototypes for get_account_info()
and check_shadow_expiry().
Diffstat (limited to 'modules/pam_unix/passverify.c')
| -rw-r--r-- | modules/pam_unix/passverify.c | 109 |
1 files changed, 92 insertions, 17 deletions
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 2743bb27..9a3d72e6 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -13,6 +13,7 @@ #include <shadow.h> #include <syslog.h> #include <stdarg.h> +#include <time.h> #include "md5.h" #include "bigcrypt.h" @@ -28,8 +29,10 @@ #ifdef HELPER_COMPILE #define pam_modutil_getpwnam(h,n) getpwnam(n) #define pam_modutil_getspnam(h,n) getspnam(n) +#define pam_syslog(h,a,b,c) helper_log_err(a,b,c) #else #include <security/pam_modutil.h> +#include <security/pam_ext.h> #endif int @@ -107,19 +110,17 @@ is_pwd_shadowed(const struct passwd *pwd) #ifdef HELPER_COMPILE int -get_pwd_hash(const char *name, - struct passwd **pwd, char **hash) +get_account_info(const char *name, + struct passwd **pwd, struct spwd **spwdent) #else int -get_pwd_hash(pam_handle_t *pamh, const char *name, - struct passwd **pwd, char **hash) +get_account_info(pam_handle_t *pamh, const char *name, + struct passwd **pwd, struct spwd **spwdent) #endif { - struct spwd *spwdent = NULL; - /* UNIX passwords area */ *pwd = pam_modutil_getpwnam(pamh, name); /* Get password file entry... */ - *hash = NULL; + *spwdent = NULL; if (*pwd != NULL) { if (strcmp((*pwd)->pw_passwd, "*NP*") == 0) @@ -141,7 +142,7 @@ get_pwd_hash(pam_handle_t *pamh, const char *name, } } - spwdent = pam_modutil_getspnam(pamh, name); + *spwdent = pam_modutil_getspnam(pamh, name); if (save_uid == (*pwd)->pw_uid) setreuid(save_uid, save_euid); else { @@ -150,7 +151,7 @@ get_pwd_hash(pam_handle_t *pamh, const char *name, setreuid(-1, save_euid); } - if (spwdent == NULL || spwdent->sp_pwdp == NULL) + if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) return PAM_AUTHINFO_UNAVAIL; #else /* we must run helper for NIS+ passwords */ @@ -165,16 +166,10 @@ get_pwd_hash(pam_handle_t *pamh, const char *name, if (geteuid() || SELINUX_ENABLED) return PAM_UNIX_RUN_HELPER; #endif - spwdent = pam_modutil_getspnam(pamh, name); - if (spwdent == NULL || spwdent->sp_pwdp == NULL) + *spwdent = pam_modutil_getspnam(pamh, name); + if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) return PAM_AUTHINFO_UNAVAIL; } - if (spwdent) - *hash = x_strdup(spwdent->sp_pwdp); - else - *hash = x_strdup((*pwd)->pw_passwd); - if (*hash == NULL) - return PAM_BUF_ERR; } else { return PAM_USER_UNKNOWN; } @@ -182,6 +177,86 @@ get_pwd_hash(pam_handle_t *pamh, const char *name, } #ifdef HELPER_COMPILE +int +get_pwd_hash(const char *name, + struct passwd **pwd, char **hash) +#else +int +get_pwd_hash(pam_handle_t *pamh, const char *name, + struct passwd **pwd, char **hash) +#endif +{ + int retval; + struct spwd *spwdent = NULL; + +#ifdef HELPER_COMPILE + retval = get_account_info(name, pwd, &spwdent); +#else + retval = get_account_info(pamh, name, pwd, &spwdent); +#endif + if (retval != PAM_SUCCESS) { + return retval; + } + + if (spwdent) + *hash = x_strdup(spwdent->sp_pwdp); + else + *hash = x_strdup((*pwd)->pw_passwd); + if (*hash == NULL) + return PAM_BUF_ERR; + + return PAM_SUCCESS; +} + +#ifdef HELPER_COMPILE +int +check_shadow_expiry(struct spwd *spent, int *daysleft) +#else +int +check_shadow_expiry(pam_handle_t *pamh, struct spwd *spent, int *daysleft) +#endif +{ + long int curdays; + *daysleft = -1; + curdays = (long int)(time(NULL) / (60 * 60 * 24)); + D(("today is %d, last change %d", curdays, spent->sp_lstchg)); + if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)) { + D(("account expired")); + return PAM_ACCT_EXPIRED; + } + if (spent->sp_lstchg == 0) { + D(("need a new password")); + *daysleft = 0; + return PAM_NEW_AUTHTOK_REQD; + } + if (curdays < spent->sp_lstchg) { + pam_syslog(pamh, LOG_DEBUG, + "account %s has password changed in future", + spent->sp_namp); + return PAM_SUCCESS; + } + if ((curdays - spent->sp_lstchg > spent->sp_max) + && (curdays - spent->sp_lstchg > spent->sp_inact) + && (curdays - spent->sp_lstchg > spent->sp_max + spent->sp_inact) + && (spent->sp_max != -1) && (spent->sp_inact != -1)) { + *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays); + D(("authtok expired")); + return PAM_AUTHTOK_EXPIRED; + } + if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) { + D(("need a new password 2")); + return PAM_NEW_AUTHTOK_REQD; + } + if ((curdays - spent->sp_lstchg > spent->sp_max - spent->sp_warn) + && (spent->sp_max != -1) && (spent->sp_warn != -1)) { + *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays); + D(("warn before expiry")); + } + return PAM_SUCCESS; + +} + +#ifdef HELPER_COMPILE int helper_verify_password(const char *name, const char *p, int nullok) |
