• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/netatalk-3.0.5/etc/uams/
1/*
2 * Copyright (c) 1990,1993 Regents of The University of Michigan.
3 * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
4 * All Rights Reserved.  See COPYRIGHT.
5 */
6
7#ifdef HAVE_CONFIG_H
8#include <config.h>
9#endif /* HAVE_CONFIG_H */
10
11#include <atalk/standards.h>
12
13#include <sys/types.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <unistd.h>
18#ifdef HAVE_CRYPT_H
19#include <crypt.h>
20#endif /* ! HAVE_CRYPT_H */
21#include <pwd.h>
22#include <sys/time.h>
23#include <time.h>
24#ifdef SHADOWPW
25#include <shadow.h>
26#endif /* SHADOWPW */
27#include <arpa/inet.h>
28
29#include <atalk/afp.h>
30#include <atalk/logger.h>
31#include <atalk/uam.h>
32#include <atalk/util.h>
33#include <atalk/compat.h>
34
35#define PASSWDLEN 8
36
37#ifndef MIN
38#define MIN(a,b) ((a) < (b) ? (a) : (b))
39#endif /* MIN */
40
41
42#ifdef TRU64
43#include <sia.h>
44#include <siad.h>
45
46static const char *clientname;
47#endif /* TRU64 */
48
49/*XXX in etc/papd/file.h */
50struct papfile;
51extern UAM_MODULE_EXPORT void append(struct papfile *, const char *, int);
52
53static int pwd_login(void *obj, char *username, int ulen, struct passwd **uam_pwd,
54                        char *ibuf, size_t ibuflen,
55                        char *rbuf _U_, size_t *rbuflen _U_)
56{
57    char  *p;
58    struct passwd *pwd;
59    int err = AFP_OK;
60#ifdef SHADOWPW
61    struct spwd *sp;
62#endif /* SHADOWPW */
63
64#ifdef TRU64
65    if( uam_afpserver_option( obj, UAM_OPTION_CLIENTNAME,
66                              (void *) &clientname, NULL ) < 0 )
67        return AFPERR_MISC;
68#endif /* TRU64 */
69
70    if (ibuflen < PASSWDLEN) {
71        return( AFPERR_PARAM );
72    }
73    ibuf[ PASSWDLEN ] = '\0';
74
75    if (( pwd = uam_getname(obj, username, ulen)) == NULL ) {
76        return AFPERR_NOTAUTH;
77    }
78
79    LOG(log_info, logtype_uams, "cleartext login: %s", username);
80
81    if (uam_checkuser(pwd) < 0) {
82        LOG(log_info, logtype_uams, "not a valid user");
83        return AFPERR_NOTAUTH;
84    }
85
86#ifdef SHADOWPW
87    if (( sp = getspnam( pwd->pw_name )) == NULL ) {
88        LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username);
89        return AFPERR_NOTAUTH;
90    }
91    pwd->pw_passwd = sp->sp_pwdp;
92
93    if (sp->sp_max != -1 && sp->sp_lstchg) {
94        time_t now = time(NULL) / (60*60*24);
95        int32_t expire_days = sp->sp_lstchg - now + sp->sp_max;
96        if ( expire_days < 0 ) {
97                LOG(log_info, logtype_uams, "Password for user %s expired", username);
98		err = AFPERR_PWDEXPR;
99        }
100    }
101#endif /* SHADOWPW */
102
103    if (!pwd->pw_passwd) {
104        return AFPERR_NOTAUTH;
105    }
106
107    *uam_pwd = pwd;
108
109#ifdef TRU64
110    {
111        int ac;
112        char **av;
113        char hostname[256];
114
115        uam_afp_getcmdline( &ac, &av );
116        sprintf( hostname, "%s@%s", username, clientname );
117
118        if( uam_sia_validate_user( NULL, ac, av, hostname, username,
119                                   NULL, FALSE, NULL, ibuf ) != SIASUCCESS )
120            return AFPERR_NOTAUTH;
121
122        return err;
123    }
124#else /* TRU64 */
125    p = crypt( ibuf, pwd->pw_passwd );
126    if ( strcmp( p, pwd->pw_passwd ) == 0 )
127        return err;
128#endif /* TRU64 */
129
130    return AFPERR_NOTAUTH;
131
132}
133
134/* cleartxt login */
135static int passwd_login(void *obj, struct passwd **uam_pwd,
136                        char *ibuf, size_t ibuflen,
137                        char *rbuf, size_t *rbuflen)
138{
139    char *username;
140    size_t len, ulen;
141
142    *rbuflen = 0;
143
144    if (uam_afpserver_option(obj, UAM_OPTION_USERNAME,
145                             (void *) &username, &ulen) < 0)
146        return AFPERR_MISC;
147
148    if (ibuflen < 2) {
149        return( AFPERR_PARAM );
150    }
151
152    len = (unsigned char) *ibuf++;
153    ibuflen--;
154    if (!len || len > ibuflen || len > ulen ) {
155        return( AFPERR_PARAM );
156    }
157    memcpy(username, ibuf, len );
158    ibuf += len;
159    ibuflen -=len;
160    username[ len ] = '\0';
161
162    if ((unsigned long) ibuf & 1) { /* pad character */
163        ++ibuf;
164        ibuflen--;
165    }
166    return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen));
167
168}
169
170/* cleartxt login ext
171 * uname format :
172    byte      3
173    2 bytes   len (network order)
174    len bytes unicode name
175*/
176static int passwd_login_ext(void *obj, char *uname, struct passwd **uam_pwd,
177                        char *ibuf, size_t ibuflen,
178                        char *rbuf, size_t *rbuflen)
179{
180    char       *username;
181    size_t     len, ulen;
182    uint16_t  temp16;
183
184    *rbuflen = 0;
185
186    if (uam_afpserver_option(obj, UAM_OPTION_USERNAME,
187                             (void *) &username, &ulen) < 0)
188        return AFPERR_MISC;
189
190    if (*uname != 3)
191        return AFPERR_PARAM;
192    uname++;
193    memcpy(&temp16, uname, sizeof(temp16));
194    len = ntohs(temp16);
195    if (!len || len > ulen ) {
196        return( AFPERR_PARAM );
197    }
198    memcpy(username, uname +2, len );
199    username[ len ] = '\0';
200    return (pwd_login(obj, username, ulen, uam_pwd, ibuf, ibuflen, rbuf, rbuflen));
201}
202
203
204#if 0
205/* change passwd */
206static int passwd_changepw(void *obj, char *username,
207                           struct passwd *pwd, char *ibuf,
208                           size_t ibuflen, char *rbuf, size_t *rbuflen)
209{
210#ifdef SHADOWPW
211    struct spwd *sp;
212#endif /* SHADOWPW */
213    char pw[PASSWDLEN + 1], *p;
214    uid_t uid = geteuid();
215
216    if (uam_checkuser(pwd) < 0)
217        return AFPERR_ACCESS;
218
219    /* old password */
220    memcpy(pw, ibuf, PASSWDLEN);
221    memset(ibuf, 0, PASSWDLEN);
222    pw[PASSWDLEN] = '\0';
223
224#ifdef SHADOWPW
225    if (( sp = getspnam( pwd->pw_name )) == NULL ) {
226        LOG(log_info, logtype_uams, "no shadow passwd entry for %s", username);
227        return AFPERR_PARAM;
228    }
229    pwd->pw_passwd = sp->sp_pwdp;
230#endif /* SHADOWPW */
231
232    p = crypt(pw, pwd->pw_passwd );
233    if (strcmp( p, pwd->pw_passwd )) {
234        memset(pw, 0, sizeof(pw));
235        return AFPERR_NOTAUTH;
236    }
237
238    /* new password */
239    ibuf += PASSWDLEN;
240    ibuf[PASSWDLEN] = '\0';
241
242#ifdef SHADOWPW
243#else /* SHADOWPW */
244#endif /* SHADOWPW */
245    return AFP_OK;
246}
247#endif /* 0 */
248
249
250/* Printer ClearTxtUAM login */
251static int passwd_printer(char	*start, char *stop, char *username, struct papfile *out)
252{
253    struct passwd *pwd;
254#ifdef SHADOWPW
255    struct spwd *sp;
256#endif /* SHADOWPW */
257    char *data, *p, *q;
258    char	password[PASSWDLEN + 1] = "\0";
259    static const char *loginok = "0\r";
260    int ulen;
261
262    data = (char *)malloc(stop - start + 1);
263    if (!data) {
264	LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: malloc");
265	return(-1);
266    }
267    strlcpy(data, start, stop - start + 1);
268
269    /* We are looking for the following format in data:
270     * (username) (password)
271     *
272     * Let's hope username doesn't contain ") ("!
273     */
274
275    /* Parse input for username in () */
276    if ((p = strchr(data, '(' )) == NULL) {
277        LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: username not found in string");
278        free(data);
279        return(-1);
280    }
281    p++;
282    if ((q = strstr(p, ") (" )) == NULL) {
283        LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: username not found in string");
284        free(data);
285        return(-1);
286    }
287    memcpy(username, p,  MIN( UAM_USERNAMELEN, q - p ));
288
289    /* Parse input for password in next () */
290    p = q + 3;
291    if ((q = strrchr(p , ')' )) == NULL) {
292        LOG(log_info, logtype_uams,"Bad Login ClearTxtUAM: password not found in string");
293        free(data);
294        return(-1);
295    }
296    memcpy(password, p, MIN(PASSWDLEN, q - p) );
297
298    /* Done copying username and password, clean up */
299    free(data);
300
301    ulen = strlen(username);
302
303    if (( pwd = uam_getname(NULL, username, ulen)) == NULL ) {
304        LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: ( %s ) not found ",
305            username);
306        return(-1);
307    }
308
309    if (uam_checkuser(pwd) < 0) {
310        /* syslog of error happens in uam_checkuser */
311        return(-1);
312    }
313
314#ifdef SHADOWPW
315    if (( sp = getspnam( pwd->pw_name )) == NULL ) {
316        LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: no shadow passwd entry for %s",
317            username);
318        return(-1);
319    }
320    pwd->pw_passwd = sp->sp_pwdp;
321
322    if (sp->sp_max != -1 && sp->sp_lstchg) {
323        time_t now = time(NULL) / (60*60*24);
324        int32_t expire_days = sp->sp_lstchg - now + sp->sp_max;
325        if ( expire_days < 0 ) {
326                LOG(log_info, logtype_uams, "Password for user %s expired", username);
327		return (-1);
328        }
329    }
330
331#endif /* SHADOWPW */
332
333    if (!pwd->pw_passwd) {
334        LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: no password for %s",
335            username);
336        return(-1);
337    }
338
339#ifdef AFS
340    if ( kcheckuser( pwd, password) == 0)
341        return(0);
342#endif /* AFS */
343
344    p = crypt(password, pwd->pw_passwd);
345    if (strcmp(p, pwd->pw_passwd) != 0) {
346        LOG(log_info, logtype_uams, "Bad Login ClearTxtUAM: %s: bad password", username);
347        return(-1);
348    }
349
350    /* Login successful */
351    append(out, loginok, strlen(loginok));
352    LOG(log_info, logtype_uams, "Login ClearTxtUAM: %s", username);
353    return(0);
354}
355
356static int uam_setup(const char *path)
357{
358    if (uam_register(UAM_SERVER_LOGIN_EXT, path, "Cleartxt Passwrd",
359                     passwd_login, NULL, NULL, passwd_login_ext) < 0)
360        return -1;
361    if (uam_register(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM",
362                     passwd_printer) < 0)
363        return -1;
364
365    return 0;
366}
367
368static void uam_cleanup(void)
369{
370    uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd");
371    uam_unregister(UAM_SERVER_PRINTAUTH, "ClearTxtUAM");
372}
373
374UAM_MODULE_EXPORT struct uam_export uams_clrtxt = {
375            UAM_MODULE_SERVER,
376            UAM_MODULE_VERSION,
377            uam_setup, uam_cleanup
378        };
379
380UAM_MODULE_EXPORT struct uam_export uams_passwd = {
381            UAM_MODULE_SERVER,
382            UAM_MODULE_VERSION,
383            uam_setup, uam_cleanup
384        };
385