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 | |
| 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().
| -rw-r--r-- | modules/pam_unix/pam_unix_acct.c | 164 | ||||
| -rw-r--r-- | modules/pam_unix/passverify.c | 109 | ||||
| -rw-r--r-- | modules/pam_unix/passverify.h | 13 |
3 files changed, 164 insertions, 122 deletions
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 26cdd1d7..c58735c5 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -196,7 +196,6 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, const void *void_uname; const char *uname; int retval, daysleft; - time_t curdays; struct spwd *spent; struct passwd *pwent; char buf[256]; @@ -215,134 +214,89 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags, return PAM_USER_UNKNOWN; } - pwent = pam_modutil_getpwnam(pamh, uname); - if (!pwent) { + retval = get_account_info(pamh, uname, &pwent, &spent); + if (retval == PAM_USER_UNKNOWN) { pam_syslog(pamh, LOG_ALERT, "could not identify user (from getpwnam(%s))", uname); - return PAM_USER_UNKNOWN; + return retval; } - if (!strcmp( pwent->pw_passwd, "*NP*" )) { /* NIS+ */ - uid_t save_euid, save_uid; - - save_euid = geteuid(); - save_uid = getuid(); - if (save_uid == pwent->pw_uid) - setreuid( save_euid, save_uid ); - else { - setreuid( 0, -1 ); - if (setreuid( -1, pwent->pw_uid ) == -1) { - setreuid( -1, 0 ); - setreuid( 0, -1 ); - if(setreuid( -1, pwent->pw_uid ) == -1) - return PAM_CRED_INSUFFICIENT; - } - } - spent = pam_modutil_getspnam (pamh, uname); - if (save_uid == pwent->pw_uid) - setreuid( save_uid, save_euid ); - else { - if (setreuid( -1, 0 ) == -1) - setreuid( save_uid, -1 ); - setreuid( -1, save_euid ); - } - - } else if (is_pwd_shadowed (pwent)) - spent = pam_modutil_getspnam (pamh, uname); - else + if (retval == PAM_SUCCESS && spent == NULL) return PAM_SUCCESS; -#ifdef WITH_SELINUX - if (!spent && SELINUX_ENABLED ) + if (retval == PAM_UNIX_RUN_HELPER) spent = _unix_run_verify_binary(pamh, ctrl, uname); -#endif - if (!spent) + if (retval != PAM_SUCCESS) { if (on(UNIX_BROKEN_SHADOW,ctrl)) return PAM_SUCCESS; + else + return retval; + } - if (!spent) - return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from shadow */ + retval = check_shadow_expiry(pamh, spent, &daysleft); - curdays = 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)) { - pam_syslog(pamh, LOG_NOTICE, - "account %s has expired (account expired)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); - D(("account expired")); - return PAM_ACCT_EXPIRED; - } - if (spent->sp_lstchg == 0) { + switch (retval) { + case PAM_ACCT_EXPIRED: pam_syslog(pamh, LOG_NOTICE, - "expired password for user %s (root enforced)", - uname); + "account %s has expired (account expired)", + uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (root enforced)")); - D(("need a new password")); - return PAM_NEW_AUTHTOK_REQD; - } - if (curdays < spent->sp_lstchg) { - pam_syslog(pamh, LOG_DEBUG, - "account %s has password changed in future", - uname); - 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)) { + _("Your account has expired; please contact your system administrator")); + break; + case PAM_NEW_AUTHTOK_REQD: + if (daysleft == 0) { + pam_syslog(pamh, LOG_NOTICE, + "expired password for user %s (root enforced)", + uname); + _make_remark(pamh, ctrl, PAM_ERROR_MSG, + _("You are required to change your password immediately (root enforced)")); + } else { + pam_syslog(pamh, LOG_DEBUG, + "expired password for user %s (password aged)", + uname); + _make_remark(pamh, ctrl, PAM_ERROR_MSG, + _("You are required to change your password immediately (password aged)")); + } + break; + case PAM_AUTHTOK_EXPIRED: pam_syslog(pamh, LOG_NOTICE, - "account %s has expired (failed to change password)", - uname); + "account %s has expired (failed to change password)", + uname); _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("Your account has expired; please contact your system administrator")); - D(("account expired 2")); - return PAM_ACCT_EXPIRED; - } - if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) { - pam_syslog(pamh, LOG_DEBUG, - "expired password for user %s (password aged)", - uname); - _make_remark(pamh, ctrl, PAM_ERROR_MSG, - _("You are required to change your password immediately (password aged)")); - 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 = (spent->sp_lstchg + spent->sp_max) - curdays; - pam_syslog(pamh, LOG_DEBUG, - "password for user %s will expire in %d days", - uname, daysleft); + _("Your account has expired; please contact your system administrator")); + break; + case PAM_SUCCESS: + if (daysleft >= 0) { + pam_syslog(pamh, LOG_DEBUG, + "password for user %s will expire in %d days", + uname, daysleft); #if defined HAVE_DNGETTEXT && defined ENABLE_NLS - snprintf (buf, sizeof (buf), - dngettext(PACKAGE, - "Warning: your password will expire in %d day", - "Warning: your password will expire in %d days", - daysleft), - daysleft); + snprintf (buf, sizeof (buf), + dngettext(PACKAGE, + "Warning: your password will expire in %d day", + "Warning: your password will expire in %d days", + daysleft), + daysleft); #else - if (daysleft == 1) - snprintf(buf, sizeof (buf), - _("Warning: your password will expire in %d day"), - daysleft); - else - snprintf(buf, sizeof (buf), - /* TRANSLATORS: only used if dngettext is not support -ed */ - _("Warning: your password will expire in %d days"), - daysleft); + if (daysleft == 1) + snprintf(buf, sizeof (buf), + _("Warning: your password will expire in %d day"), + daysleft); + else + snprintf(buf, sizeof (buf), + /* TRANSLATORS: only used if dngettext is not supported */ + _("Warning: your password will expire in %d days"), + daysleft); #endif - _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf); + _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf); + } } D(("all done")); - return PAM_SUCCESS; + return retval; } 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) diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index a1a372b9..6b8c0c3e 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -21,14 +21,27 @@ int helper_verify_password(const char *name, const char *p, int nullok); int +get_account_info(const char *name, + struct passwd **pwd, struct spwd **spwdent); + +int get_pwd_hash(const char *name, struct passwd **pwd, char **hash); +int +check_shadow_expiry(struct spwd *spent, int *daysleft); + #else +int +get_account_info(pam_handle_t *pamh, const char *name, + struct passwd **pwd, struct spwd **spwdent); int get_pwd_hash(pam_handle_t *pamh, const char *name, struct passwd **pwd, char **hash); + +int +check_shadow_expiry(pam_handle_t *pamh, struct spwd *spent, int *daysleft); #endif /* ****************************************************************** * |
