1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/*
Written by Beau Kuiper <support@muddleftpd.cx>
Use, modification and distribution is allowed without limitation,
warranty, or liability of any kind.
*/
#include "config.h"
#include "auth.h"
#include <sys/time.h>
#include <pwd.h>
#include <time.h>
#ifdef HAVE_GETSPNAM
#include <shadow.h>
#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));
}
|