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