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