]> arthur.barton.de Git - netatalk.git/blob - etc/uams/uams_passwd.c
more Tru64 fixes from Burkhard Schmidt <bs@cpfs.mpg.de>
[netatalk.git] / etc / uams / uams_passwd.c
1 /*
2  * $Id: uams_passwd.c,v 1.9 2001-05-22 19:13:36 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
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #ifndef NO_CRYPT_H
18 #include <crypt.h>
19 #endif
20 #include <pwd.h>
21 #include <syslog.h>
22
23 #ifdef SOLARIS
24 #define SHADOWPW
25 #endif SOLARIS
26
27 #ifdef SHADOWPW
28 #include <shadow.h>
29 #endif SHADOWPW
30
31 #include <atalk/afp.h>
32 #include <atalk/uam.h>
33
34 #define PASSWDLEN 8
35
36 #ifdef TRU64
37 #include <sys/types.h>
38 #include <sys/security.h>
39 #include <prot.h>
40 #include <sia.h>
41
42 static int c2security = 0;
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     len = (unsigned char) *ibuf++;
64     if ( len > ulen ) {
65         return( AFPERR_PARAM );
66     }
67
68     memcpy(username, ibuf, len );
69     ibuf += len;
70     username[ len ] = '\0';
71     if ((unsigned long) ibuf & 1) /* pad character */
72       ++ibuf;
73     ibuf[ PASSWDLEN ] = '\0';
74
75     if (( pwd = uam_getname(username, ulen)) == NULL ) {
76         return AFPERR_PARAM;
77     }
78
79     syslog(LOG_INFO, "cleartext login: %s", username);
80     if (uam_checkuser(pwd) < 0)
81       return AFPERR_NOTAUTH;
82
83 #ifdef SHADOWPW
84     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
85         syslog( LOG_INFO, "no shadow passwd entry for %s", username);
86         return AFPERR_NOTAUTH;
87     }
88     pwd->pw_passwd = sp->sp_pwdp;
89 #endif SHADOWPW
90
91     if (!pwd->pw_passwd)
92       return AFPERR_NOTAUTH;
93
94     *uam_pwd = pwd;
95
96 #ifdef TRU64
97     if ( c2security == 1 ) {
98         struct pr_passwd *pr = getprpwnam( pwd->pw_name );
99         if ( pr == NULL )
100             return AFPERR_NOTAUTH;
101         if ( strcmp( dispcrypt( rbuf, pr->ufld.fd_encrypt,
102             pr->ufld.fd_oldcrypt ), pr->ufld.fd_encrypt ) == 0 ) {
103             return AFP_OK;
104         }
105     } else {
106         p = crypt( rbuf, pwd->pw_passwd );
107         memset(rbuf, 0, PASSWDLEN);
108         if ( strcmp( p, pwd->pw_passwd ) == 0 ) {
109             return AFP_OK;
110         }
111     }
112 #else /* TRU64 */
113     p = crypt( ibuf, pwd->pw_passwd );
114     if ( strcmp( p, pwd->pw_passwd ) == 0 ) 
115       return AFP_OK;
116 #endif /* TRU64 */
117
118     return AFPERR_NOTAUTH;
119 }
120
121
122 #if 0
123 /* change passwd */
124 static int passwd_changepw(void *obj, char *username,
125                            struct passwd *pwd, char *ibuf,
126                            int ibuflen, char *rbuf, int *rbuflen)
127 {
128 #ifdef SHADOWPW
129     struct spwd *sp;
130 #endif
131     char pw[PASSWDLEN + 1], *p;
132     uid_t uid = geteuid();
133
134     if (uam_checkuser(pwd) < 0)
135       return AFPERR_ACCESS;
136
137     /* old password */
138     memcpy(pw, ibuf, PASSWDLEN);
139     memset(ibuf, 0, PASSWDLEN);
140     pw[PASSWDLEN] = '\0';
141
142 #ifdef SHADOWPW
143     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
144         syslog( LOG_INFO, "no shadow passwd entry for %s", username);
145         return AFPERR_PARAM;
146     }
147     pwd->pw_passwd = sp->sp_pwdp;
148 #endif SHADOWPW
149
150     p = crypt(pw, pwd->pw_passwd );
151     if (strcmp( p, pwd->pw_passwd )) {
152       memset(pw, 0, sizeof(pw));
153       return AFPERR_NOTAUTH;
154     }
155
156     /* new password */
157     ibuf += PASSWDLEN;
158     ibuf[PASSWDLEN] = '\0';
159     
160 #ifdef SHADOWPW
161 #else
162 #endif
163     return AFP_OK;
164 }
165 #endif
166
167
168 /* Printer ClearTxtUAM login */
169 static int passwd_printer(start, stop, username, out)
170         char    *start, *stop, *username;
171         struct papfile  *out;
172 {
173     struct passwd *pwd;
174 #ifdef SHADOWPW
175     struct spwd *sp;
176 #endif
177     char *data, *p, *q;
178     char        password[PASSWDLEN + 1] = "\0";
179     static const char *loginok = "0\r";
180     int ulen;
181
182     data = (char *)malloc(stop - start + 1);
183     strncpy(data, start, stop - start + 1);
184
185     /* We are looking for the following format in data:
186      * (username) (password)
187      *
188      * Let's hope username doesn't contain ") ("!
189      */
190
191     /* Parse input for username in () */
192     if ((p = strchr(data, '(' )) == NULL) {
193         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
194         free(data);
195         return(-1);
196     }
197     p++;
198     if ((q = strstr(data, ") (" )) == NULL) {
199         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
200         free(data);
201         return(-1);
202     }
203     strncpy(username, p, q - p);
204
205     /* Parse input for password in next () */
206     p = q + 3;
207     if ((q = strrchr(data, ')' )) == NULL) {
208         syslog(LOG_INFO,"Bad Login ClearTxtUAM: password not found in string");
209         free(data);
210         return(-1);
211     }
212     strncpy(password, p, q - p);
213
214     /* Done copying username and password, clean up */
215     free(data);
216
217     ulen = strlen(username);
218
219     if (( pwd = uam_getname(username, ulen)) == NULL ) {
220         syslog(LOG_INFO, "Bad Login ClearTxtUAM: ( %s ) not found ",
221                         username);
222         return(-1);
223     }
224
225     if (uam_checkuser(pwd) < 0) {
226         /* syslog of error happens in uam_checkuser */
227         return(-1);
228     }
229
230 #ifdef SHADOWPW
231     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
232         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no shadow passwd entry for %s", 
233                         username);
234         return(-1);
235     }
236     pwd->pw_passwd = sp->sp_pwdp;
237 #endif SHADOWPW
238
239     if (!pwd->pw_passwd) {
240         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no password for %s",
241                         username);
242         return(-1);
243     }
244
245 #ifdef AFS
246     if ( kcheckuser( pwd, password) == 0) 
247       return(0);
248 #endif AFS
249
250     p = crypt(password, pwd->pw_passwd);
251     if (strcmp(p, pwd->pw_passwd) != 0) {
252         syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: bad password", username);
253         return(-1);
254     }
255
256     /* Login successful */
257     append(out, loginok, strlen(loginok));
258     syslog(LOG_INFO, "Login ClearTxtUAM: %s", username);
259     return(0);
260 }
261
262
263 static int uam_setup(const char *path)
264 {
265 #ifdef TRU64
266     FILE *f;
267     char buf[256];
268     char siad[] = "siad_ses_init=";
269
270     if ( access( SIAIGOODFILE, F_OK ) == -1 ) {
271         syslog( LOG_ERR, "clrtxt uam_setup: %s does not exist",
272             SIAIGOODFILE);
273         return -1;
274     }
275
276     if ( ( f = fopen(MATRIX_CONF, "r" ) ) == NULL ) {
277         syslog( LOG_ERR, "clrtxt uam_setup: %s is unreadable",
278             MATRIX_CONF );
279         return -1;
280     }
281
282     while ( fgets( buf, sizeof(buf), f ) != NULL ) {
283         if ( strncmp( buf, siad, sizeof(siad) - 1 ) == 0 ) {
284             if ( strstr( buf, "OSFC2" ) != NULL )
285                 c2security = 1;
286             break;
287         }
288     }
289
290     fclose(f);
291
292     syslog( LOG_INFO, "clrtxt uam_setup: security level %s",
293         c2security == 0 ? "BSD" : "OSFC2" );
294 #endif /* TRU64 */
295
296   if (uam_register(UAM_SERVER_LOGIN, path, "Cleartxt Passwrd", 
297                 passwd_login, NULL, NULL) < 0)
298         return -1;
299   if (uam_register(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM",
300                 passwd_printer) < 0)
301         return -1;
302
303   return 0;
304 }
305
306 static void uam_cleanup(void)
307 {
308   uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd");
309   uam_unregister(UAM_SERVER_PRINTAUTH, "ClearTxtUAM");
310 }
311
312 UAM_MODULE_EXPORT struct uam_export uams_clrtxt = {
313   UAM_MODULE_SERVER,
314   UAM_MODULE_VERSION,
315   uam_setup, uam_cleanup
316 };