/* Written by Beau Kuiper Use, modification and distribution is allowed without limitation, warranty, or liability of any kind. */ #include "config.h" #include "auth.h" #include #include #include #ifdef HAVE_GETSPNAM #include #endif /* This file contains code to autheticate against unix password files */ typedef struct { struct passwd *passent; #ifdef HAVE_GETSPNAM struct spwd *sppassent; #endif } PASSWDSTRUCT; int getday(void) { time_t currenttime = time(NULL); struct tm *currenttm = localtime(¤ttime); int yeardif = currenttm->tm_year - 70; int days; days = yeardif * 365 + currenttm->tm_yday; /* THIS STUFF IS Y2K COMPLIANT */ days += (yeardif + 1) / 4; /* I don't ever expect this code to be used beyond 2100, but so did too many cobol programmers in the 1970's !! */ if (currenttm->tm_year > 200) /* simple algorithm */ { yeardif -= 31; days -= (yeardif) / 100; /* take centaries off */ days += (yeardif) / 400; /* add on 400 year leapyears */ } return(days); } void *gethandle(void *peer, void *tset, char *username, int *err) { PASSWDSTRUCT *newhandle; char *passwdmode; newhandle = mallocwrapper(sizeof(PASSWDSTRUCT)); passwdmode = mktokconfstr(tset, auth_getcursectionid(peer), "passwdmode", ""); newhandle->passent = getpwnam(username); if (newhandle->passent == NULL) goto error; #ifdef HAVE_GETSPNAM /* this will try to autodetect shadow passwordness */ if ((strcasecmp(passwdmode, "shadow") == 0) || (strcmp(newhandle->passent->pw_passwd, "x") == 0)) { if (strcasecmp(passwdmode, "normal") == 0) newhandle->sppassent = NULL; else { newhandle->sppassent = getspnam(username); if (newhandle->sppassent == NULL) goto error; } } else newhandle->sppassent = NULL; #endif freewrapper(passwdmode); *err = AUTH_OK; return(newhandle); error: freewrapper(passwdmode); *err = AUTH_USERNKNOW; freewrapper(newhandle); return(NULL); } void freehandle(void *handle) { freewrapper(handle); } int chkpasswd(void *h, char *password, char **errmsg) { PASSWDSTRUCT *handle = (PASSWDSTRUCT *)h; #ifdef HAVE_GETSPNAM if (handle->sppassent) { int days = getday(); int expiredate = handle->sppassent->sp_max + handle->sppassent->sp_lstchg + + handle->sppassent->sp_inact; /* do the account expiration checking! */ if ((days > handle->sppassent->sp_expire) && (handle->sppassent->sp_expire != -1)) { *errmsg = safe_snprintf("Account has expired"); return(FALSE); } if ((handle->sppassent->sp_inact != -1) && (handle->sppassent->sp_max != -1) && (handle->sppassent->sp_lstchg != -1) && (days > expiredate)) { *errmsg = safe_snprintf("Account disabled, needs new password"); return(FALSE); } return(chkpassword(handle->sppassent->sp_pwdp, password)); } #endif return(chkpassword(handle->passent->pw_passwd, password)); } char *gethomedir(void *h) { return(((PASSWDSTRUCT *)h)->passent->pw_dir); } char *getrootdir(void *h) { return("/"); } uid_t getuseruid(void *h) { return(((PASSWDSTRUCT *)h)->passent->pw_uid); } gid_t getusergid(void *h) { return(((PASSWDSTRUCT *)h)->passent->pw_gid); } gid_t *getusersupgid(void *h) { return(getusergrouplist(((PASSWDSTRUCT *)h)->passent->pw_name)); }