]> arthur.barton.de Git - netatalk.git/blob - etc/uams/uams_passwd.c
AC_HEADER_STDC autoconf change
[netatalk.git] / etc / uams / uams_passwd.c
1 /*
2  * $Id: uams_passwd.c,v 1.13 2001-09-06 20:00:59 rufustfirefly 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 <syslog.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 /* cleartxt login */
61 static int passwd_login(void *obj, struct passwd **uam_pwd,
62                         char *ibuf, int ibuflen,
63                         char *rbuf, int *rbuflen)
64 {
65     struct passwd *pwd;
66 #ifdef SHADOWPW
67     struct spwd *sp;
68 #endif /* SHADOWPW */
69     char *username, *p;
70     int len, ulen;
71
72     *rbuflen = 0;
73
74     if (uam_afpserver_option(obj, UAM_OPTION_USERNAME,
75                              (void *) &username, &ulen) < 0)
76       return AFPERR_MISC;
77
78 #ifdef TRU64
79     if( uam_afpserver_option( obj, UAM_OPTION_CLIENTNAME,
80                               (void *) &clientname, NULL ) < 0 )
81         return AFPERR_MISC;
82 #endif /* TRU64 */
83
84     len = (unsigned char) *ibuf++;
85     if ( len > ulen ) {
86         return( AFPERR_PARAM );
87     }
88
89     memcpy(username, ibuf, len );
90     ibuf += len;
91     username[ len ] = '\0';
92     if ((unsigned long) ibuf & 1) /* pad character */
93       ++ibuf;
94     ibuf[ PASSWDLEN ] = '\0';
95
96     if (( pwd = uam_getname(username, ulen)) == NULL ) {
97         return AFPERR_PARAM;
98     }
99
100     syslog(LOG_INFO, "cleartext login: %s", username);
101     if (uam_checkuser(pwd) < 0)
102       return AFPERR_NOTAUTH;
103
104 #ifdef SHADOWPW
105     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
106         syslog( LOG_INFO, "no shadow passwd entry for %s", username);
107         return AFPERR_NOTAUTH;
108     }
109     pwd->pw_passwd = sp->sp_pwdp;
110 #endif /* SHADOWPW */
111
112     if (!pwd->pw_passwd)
113       return AFPERR_NOTAUTH;
114
115     *uam_pwd = pwd;
116
117 #ifdef TRU64
118     {
119         int ac;
120         char **av;
121         char hostname[256];
122
123         uam_afp_getcmdline( &ac, &av );
124         sprintf( hostname, "%s@%s", username, clientname );
125
126         if( sia_validate_user( NULL, ac, av, hostname, username,
127                                NULL, FALSE, NULL, ibuf ) != SIASUCCESS )
128             return AFPERR_NOTAUTH;
129
130         return AFP_OK;
131     }
132 #else /* TRU64 */
133     p = crypt( ibuf, pwd->pw_passwd );
134     if ( strcmp( p, pwd->pw_passwd ) == 0 ) 
135       return AFP_OK;
136 #endif /* TRU64 */
137
138     return AFPERR_NOTAUTH;
139 }
140
141
142 #if 0
143 /* change passwd */
144 static int passwd_changepw(void *obj, char *username,
145                            struct passwd *pwd, char *ibuf,
146                            int ibuflen, char *rbuf, int *rbuflen)
147 {
148 #ifdef SHADOWPW
149     struct spwd *sp;
150 #endif /* SHADOWPW */
151     char pw[PASSWDLEN + 1], *p;
152     uid_t uid = geteuid();
153
154     if (uam_checkuser(pwd) < 0)
155       return AFPERR_ACCESS;
156
157     /* old password */
158     memcpy(pw, ibuf, PASSWDLEN);
159     memset(ibuf, 0, PASSWDLEN);
160     pw[PASSWDLEN] = '\0';
161
162 #ifdef SHADOWPW
163     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
164         syslog( LOG_INFO, "no shadow passwd entry for %s", username);
165         return AFPERR_PARAM;
166     }
167     pwd->pw_passwd = sp->sp_pwdp;
168 #endif /* SHADOWPW */
169
170     p = crypt(pw, pwd->pw_passwd );
171     if (strcmp( p, pwd->pw_passwd )) {
172       memset(pw, 0, sizeof(pw));
173       return AFPERR_NOTAUTH;
174     }
175
176     /* new password */
177     ibuf += PASSWDLEN;
178     ibuf[PASSWDLEN] = '\0';
179     
180 #ifdef SHADOWPW
181 #else /* SHADOWPW */
182 #endif /* SHADOWPW */
183     return AFP_OK;
184
185 #endif /* 0 */
186
187
188 /* Printer ClearTxtUAM login */
189 static int passwd_printer(start, stop, username, out)
190         char    *start, *stop, *username;
191         struct papfile  *out;
192 {
193     struct passwd *pwd;
194 #ifdef SHADOWPW
195     struct spwd *sp;
196 #endif /* SHADOWPW */
197     char *data, *p, *q;
198     char        password[PASSWDLEN + 1] = "\0";
199     static const char *loginok = "0\r";
200     int ulen;
201
202     data = (char *)malloc(stop - start + 1);
203     strncpy(data, start, stop - start + 1);
204
205     /* We are looking for the following format in data:
206      * (username) (password)
207      *
208      * Let's hope username doesn't contain ") ("!
209      */
210
211     /* Parse input for username in () */
212     if ((p = strchr(data, '(' )) == NULL) {
213         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
214         free(data);
215         return(-1);
216     }
217     p++;
218     if ((q = strstr(data, ") (" )) == NULL) {
219         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
220         free(data);
221         return(-1);
222     }
223     strncpy(username, p, q - p);
224
225     /* Parse input for password in next () */
226     p = q + 3;
227     if ((q = strrchr(data, ')' )) == NULL) {
228         syslog(LOG_INFO,"Bad Login ClearTxtUAM: password not found in string");
229         free(data);
230         return(-1);
231     }
232     strncpy(password, p, q - p);
233
234     /* Done copying username and password, clean up */
235     free(data);
236
237     ulen = strlen(username);
238
239     if (( pwd = uam_getname(username, ulen)) == NULL ) {
240         syslog(LOG_INFO, "Bad Login ClearTxtUAM: ( %s ) not found ",
241                         username);
242         return(-1);
243     }
244
245     if (uam_checkuser(pwd) < 0) {
246         /* syslog of error happens in uam_checkuser */
247         return(-1);
248     }
249
250 #ifdef SHADOWPW
251     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
252         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no shadow passwd entry for %s", 
253                         username);
254         return(-1);
255     }
256     pwd->pw_passwd = sp->sp_pwdp;
257 #endif /* SHADOWPW */
258
259     if (!pwd->pw_passwd) {
260         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no password for %s",
261                         username);
262         return(-1);
263     }
264
265 #ifdef AFS
266     if ( kcheckuser( pwd, password) == 0) 
267       return(0);
268 #endif /* AFS */
269
270     p = crypt(password, pwd->pw_passwd);
271     if (strcmp(p, pwd->pw_passwd) != 0) {
272         syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: bad password", username);
273         return(-1);
274     }
275
276     /* Login successful */
277     append(out, loginok, strlen(loginok));
278     syslog(LOG_INFO, "Login ClearTxtUAM: %s", username);
279     return(0);
280 }
281
282
283 static int uam_setup(const char *path)
284 {
285   if (uam_register(UAM_SERVER_LOGIN, path, "Cleartxt Passwrd", 
286                 passwd_login, NULL, NULL) < 0)
287         return -1;
288   if (uam_register(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM",
289                 passwd_printer) < 0)
290         return -1;
291
292   return 0;
293 }
294
295 static void uam_cleanup(void)
296 {
297   uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd");
298   uam_unregister(UAM_SERVER_PRINTAUTH, "ClearTxtUAM");
299 }
300
301 UAM_MODULE_EXPORT struct uam_export uams_clrtxt = {
302   UAM_MODULE_SERVER,
303   UAM_MODULE_VERSION,
304   uam_setup, uam_cleanup
305 };