1 |
|
|
2 |
/* |
/* |
3 |
|
|
4 |
Written by Beau Kuiper <support@muddleftpd.cx> |
Written by Beau Kuiper <support@muddleftpd.cx> |
20 |
|
|
21 |
/* This file contains code to autheticate against unix password files */ |
/* This file contains code to autheticate against unix password files */ |
22 |
|
|
23 |
typedef struct |
typedef struct |
24 |
{ |
{ |
25 |
struct passwd *passent; |
struct passwd *passent; |
26 |
#ifdef HAVE_GETSPNAM |
#ifdef HAVE_GETSPNAM |
27 |
struct spwd *sppassent; |
struct spwd *sppassent; |
28 |
#endif |
#endif |
29 |
} PASSWDSTRUCT; |
} |
30 |
|
PASSWDSTRUCT; |
31 |
|
|
32 |
int getday(void) |
int getday(void) |
33 |
{ |
{ |
35 |
struct tm *currenttm = localtime(¤ttime); |
struct tm *currenttm = localtime(¤ttime); |
36 |
int yeardif = currenttm->tm_year - 70; |
int yeardif = currenttm->tm_year - 70; |
37 |
int days; |
int days; |
38 |
|
|
39 |
days = yeardif * 365 + currenttm->tm_yday; |
days = yeardif * 365 + currenttm->tm_yday; |
40 |
|
|
41 |
/* THIS STUFF IS Y2K COMPLIANT */ |
/* |
42 |
|
* THIS STUFF IS Y2K COMPLIANT |
43 |
|
*/ |
44 |
days += (yeardif + 1) / 4; |
days += (yeardif + 1) / 4; |
45 |
|
|
46 |
/* I don't ever expect this code to be used beyond 2100, but so did |
/* |
47 |
too many cobol programmers in the 1970's !! */ |
* I don't ever expect this code to be used beyond 2100, but so did |
48 |
if (currenttm->tm_year > 200) /* simple algorithm */ |
* too many cobol programmers in the 1970's !! |
49 |
|
*/ |
50 |
|
if (currenttm->tm_year > 200) /* simple algorithm */ |
51 |
{ |
{ |
52 |
yeardif -= 31; |
yeardif -= 31; |
53 |
days -= (yeardif) / 100; /* take centaries off */ |
days -= (yeardif) / 100; /* take centaries off */ |
54 |
days += (yeardif) / 400; /* add on 400 year leapyears */ |
days += (yeardif) / 400; /* add on 400 year leapyears */ |
55 |
} |
} |
56 |
return(days); |
return (days); |
57 |
} |
} |
58 |
|
|
59 |
void *gethandle(void *peer, void *tset, char *username, int *err) |
void *gethandle(void *peer, |
60 |
|
void *tset, |
61 |
|
char *username, |
62 |
|
int *err) |
63 |
{ |
{ |
64 |
PASSWDSTRUCT *newhandle; |
PASSWDSTRUCT *newhandle; |
65 |
char *passwdmode; |
char *passwdmode; |
66 |
|
|
67 |
newhandle = mallocwrapper(sizeof(PASSWDSTRUCT)); |
newhandle = mallocwrapper(sizeof(PASSWDSTRUCT)); |
68 |
passwdmode = mktokconfstr(tset, auth_getcursectionid(peer), "passwdmode", ""); |
passwdmode = |
69 |
|
mktokconfstr(tset, auth_getcursectionid(peer), "passwdmode", ""); |
70 |
|
|
71 |
newhandle->passent = getpwnam(username); |
newhandle->passent = getpwnam(username); |
72 |
if (newhandle->passent == NULL) |
if (newhandle->passent == NULL) |
73 |
goto error; |
goto error; |
74 |
|
|
75 |
#ifdef HAVE_GETSPNAM |
#ifdef HAVE_GETSPNAM |
76 |
|
|
77 |
/* this will try to autodetect shadow passwordness */ |
/* |
78 |
if ((strcasecmp(passwdmode, "shadow") == 0) || |
* this will try to autodetect shadow passwordness |
79 |
(strcmp(newhandle->passent->pw_passwd, "x") == 0)) |
*/ |
80 |
|
if ((strcasecmp(passwdmode, "shadow") == 0) || |
81 |
|
(strcmp(newhandle->passent->pw_passwd, "x") == 0)) |
82 |
{ |
{ |
83 |
if (strcasecmp(passwdmode, "normal") == 0) |
if (strcasecmp(passwdmode, "normal") == 0) |
84 |
newhandle->sppassent = NULL; |
newhandle->sppassent = NULL; |
95 |
#endif |
#endif |
96 |
freewrapper(passwdmode); |
freewrapper(passwdmode); |
97 |
*err = AUTH_OK; |
*err = AUTH_OK; |
98 |
return(newhandle); |
return (newhandle); |
99 |
|
|
100 |
error: |
error: |
101 |
freewrapper(passwdmode); |
freewrapper(passwdmode); |
102 |
*err = AUTH_USERNKNOW; |
*err = AUTH_USERNKNOW; |
103 |
freewrapper(newhandle); |
freewrapper(newhandle); |
104 |
return(NULL); |
return (NULL); |
105 |
} |
} |
106 |
|
|
107 |
void freehandle(void *handle) |
void freehandle(void *handle) |
109 |
freewrapper(handle); |
freewrapper(handle); |
110 |
} |
} |
111 |
|
|
112 |
int chkpasswd(void *h, char *password, char **errmsg) |
int chkpasswd(void *h, |
113 |
|
char *password, |
114 |
|
char **errmsg) |
115 |
{ |
{ |
116 |
PASSWDSTRUCT *handle = (PASSWDSTRUCT *)h; |
PASSWDSTRUCT *handle = (PASSWDSTRUCT *) h; |
117 |
|
|
118 |
#ifdef HAVE_GETSPNAM |
#ifdef HAVE_GETSPNAM |
119 |
if (handle->sppassent) |
if (handle->sppassent) |
120 |
{ |
{ |
121 |
int days = getday(); |
int days = getday(); |
122 |
int expiredate = handle->sppassent->sp_max + handle->sppassent->sp_lstchg + |
int expiredate = |
123 |
+ handle->sppassent->sp_inact; |
handle->sppassent->sp_max + handle->sppassent->sp_lstchg + |
124 |
|
+handle->sppassent->sp_inact; |
125 |
/* do the account expiration checking! */ |
|
126 |
if ((days > handle->sppassent->sp_expire) && |
/* |
127 |
(handle->sppassent->sp_expire != -1)) |
* do the account expiration checking! |
128 |
|
*/ |
129 |
|
if ((days > handle->sppassent->sp_expire) && |
130 |
|
(handle->sppassent->sp_expire != -1)) |
131 |
{ |
{ |
132 |
*errmsg = safe_snprintf("Account has expired"); |
*errmsg = safe_snprintf("Account has expired"); |
133 |
return(FALSE); |
return (FALSE); |
134 |
} |
} |
135 |
|
|
136 |
if ((handle->sppassent->sp_inact != -1) && (handle->sppassent->sp_max != -1) |
if ((handle->sppassent->sp_inact != -1) |
137 |
&& (handle->sppassent->sp_lstchg != -1) && (days > expiredate)) |
&& (handle->sppassent->sp_max != -1) |
138 |
|
&& (handle->sppassent->sp_lstchg != -1) && (days > expiredate)) |
139 |
{ |
{ |
140 |
*errmsg = safe_snprintf("Account disabled, needs new password"); |
*errmsg = safe_snprintf("Account disabled, needs new password"); |
141 |
return(FALSE); |
return (FALSE); |
142 |
} |
} |
143 |
|
|
144 |
return(chkpassword(handle->sppassent->sp_pwdp, password)); |
return (chkpassword(handle->sppassent->sp_pwdp, password)); |
145 |
} |
} |
146 |
#endif |
#endif |
147 |
return(chkpassword(handle->passent->pw_passwd, password)); |
return (chkpassword(handle->passent->pw_passwd, password)); |
148 |
} |
} |
149 |
|
|
150 |
char *gethomedir(void *h) |
char *gethomedir(void *h) |
151 |
{ |
{ |
152 |
return(((PASSWDSTRUCT *)h)->passent->pw_dir); |
return (((PASSWDSTRUCT *) h)->passent->pw_dir); |
153 |
} |
} |
154 |
|
|
155 |
char *getrootdir(void *h) |
char *getrootdir(void *h) |
156 |
{ |
{ |
157 |
return("/"); |
return ("/"); |
158 |
} |
} |
159 |
|
|
160 |
uid_t getuseruid(void *h) |
uid_t getuseruid(void *h) |
161 |
{ |
{ |
162 |
return(((PASSWDSTRUCT *)h)->passent->pw_uid); |
return (((PASSWDSTRUCT *) h)->passent->pw_uid); |
163 |
} |
} |
164 |
|
|
165 |
gid_t getusergid(void *h) |
gid_t getusergid(void *h) |
166 |
{ |
{ |
167 |
return(((PASSWDSTRUCT *)h)->passent->pw_gid); |
return (((PASSWDSTRUCT *) h)->passent->pw_gid); |
168 |
} |
} |
169 |
|
|
170 |
gid_t *getusersupgid(void *h) |
gid_t *getusersupgid(void *h) |
171 |
{ |
{ |
172 |
return(getusergrouplist(((PASSWDSTRUCT *)h)->passent->pw_name)); |
return (getusergrouplist(((PASSWDSTRUCT *) h)->passent->pw_name)); |
173 |
} |
} |