]> arthur.barton.de Git - netatalk.git/blob - etc/uams/uams_passwd.c
another Tru64 patch from Burkhard Schmidt
[netatalk.git] / etc / uams / uams_passwd.c
1 /*
2  * $Id: uams_passwd.c,v 1.10 2001-05-25 13:23:56 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( ibuf, pr->ufld.fd_encrypt,
102             pr->ufld.fd_oldcrypt ), pr->ufld.fd_encrypt ) == 0 ) {
103             return AFP_OK;
104         }
105     } else {
106         p = crypt( ibuf, pwd->pw_passwd );
107         if ( strcmp( p, pwd->pw_passwd ) == 0 )
108             return AFP_OK;
109     }
110 #else /* TRU64 */
111     p = crypt( ibuf, pwd->pw_passwd );
112     if ( strcmp( p, pwd->pw_passwd ) == 0 ) 
113       return AFP_OK;
114 #endif /* TRU64 */
115
116     return AFPERR_NOTAUTH;
117 }
118
119
120 #if 0
121 /* change passwd */
122 static int passwd_changepw(void *obj, char *username,
123                            struct passwd *pwd, char *ibuf,
124                            int ibuflen, char *rbuf, int *rbuflen)
125 {
126 #ifdef SHADOWPW
127     struct spwd *sp;
128 #endif
129     char pw[PASSWDLEN + 1], *p;
130     uid_t uid = geteuid();
131
132     if (uam_checkuser(pwd) < 0)
133       return AFPERR_ACCESS;
134
135     /* old password */
136     memcpy(pw, ibuf, PASSWDLEN);
137     memset(ibuf, 0, PASSWDLEN);
138     pw[PASSWDLEN] = '\0';
139
140 #ifdef SHADOWPW
141     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
142         syslog( LOG_INFO, "no shadow passwd entry for %s", username);
143         return AFPERR_PARAM;
144     }
145     pwd->pw_passwd = sp->sp_pwdp;
146 #endif SHADOWPW
147
148     p = crypt(pw, pwd->pw_passwd );
149     if (strcmp( p, pwd->pw_passwd )) {
150       memset(pw, 0, sizeof(pw));
151       return AFPERR_NOTAUTH;
152     }
153
154     /* new password */
155     ibuf += PASSWDLEN;
156     ibuf[PASSWDLEN] = '\0';
157     
158 #ifdef SHADOWPW
159 #else
160 #endif
161     return AFP_OK;
162 }
163 #endif
164
165
166 /* Printer ClearTxtUAM login */
167 static int passwd_printer(start, stop, username, out)
168         char    *start, *stop, *username;
169         struct papfile  *out;
170 {
171     struct passwd *pwd;
172 #ifdef SHADOWPW
173     struct spwd *sp;
174 #endif
175     char *data, *p, *q;
176     char        password[PASSWDLEN + 1] = "\0";
177     static const char *loginok = "0\r";
178     int ulen;
179
180     data = (char *)malloc(stop - start + 1);
181     strncpy(data, start, stop - start + 1);
182
183     /* We are looking for the following format in data:
184      * (username) (password)
185      *
186      * Let's hope username doesn't contain ") ("!
187      */
188
189     /* Parse input for username in () */
190     if ((p = strchr(data, '(' )) == NULL) {
191         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
192         free(data);
193         return(-1);
194     }
195     p++;
196     if ((q = strstr(data, ") (" )) == NULL) {
197         syslog(LOG_INFO,"Bad Login ClearTxtUAM: username not found in string");
198         free(data);
199         return(-1);
200     }
201     strncpy(username, p, q - p);
202
203     /* Parse input for password in next () */
204     p = q + 3;
205     if ((q = strrchr(data, ')' )) == NULL) {
206         syslog(LOG_INFO,"Bad Login ClearTxtUAM: password not found in string");
207         free(data);
208         return(-1);
209     }
210     strncpy(password, p, q - p);
211
212     /* Done copying username and password, clean up */
213     free(data);
214
215     ulen = strlen(username);
216
217     if (( pwd = uam_getname(username, ulen)) == NULL ) {
218         syslog(LOG_INFO, "Bad Login ClearTxtUAM: ( %s ) not found ",
219                         username);
220         return(-1);
221     }
222
223     if (uam_checkuser(pwd) < 0) {
224         /* syslog of error happens in uam_checkuser */
225         return(-1);
226     }
227
228 #ifdef SHADOWPW
229     if (( sp = getspnam( pwd->pw_name )) == NULL ) {
230         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no shadow passwd entry for %s", 
231                         username);
232         return(-1);
233     }
234     pwd->pw_passwd = sp->sp_pwdp;
235 #endif SHADOWPW
236
237     if (!pwd->pw_passwd) {
238         syslog(LOG_INFO, "Bad Login ClearTxtUAM: no password for %s",
239                         username);
240         return(-1);
241     }
242
243 #ifdef AFS
244     if ( kcheckuser( pwd, password) == 0) 
245       return(0);
246 #endif AFS
247
248     p = crypt(password, pwd->pw_passwd);
249     if (strcmp(p, pwd->pw_passwd) != 0) {
250         syslog(LOG_INFO, "Bad Login ClearTxtUAM: %s: bad password", username);
251         return(-1);
252     }
253
254     /* Login successful */
255     append(out, loginok, strlen(loginok));
256     syslog(LOG_INFO, "Login ClearTxtUAM: %s", username);
257     return(0);
258 }
259
260
261 static int uam_setup(const char *path)
262 {
263 #ifdef TRU64
264     FILE *f;
265     char buf[256];
266     char siad[] = "siad_ses_init=";
267
268     if ( access( SIAIGOODFILE, F_OK ) == -1 ) {
269         syslog( LOG_ERR, "clrtxt uam_setup: %s does not exist",
270             SIAIGOODFILE);
271         return -1;
272     }
273
274     if ( ( f = fopen(MATRIX_CONF, "r" ) ) == NULL ) {
275         syslog( LOG_ERR, "clrtxt uam_setup: %s is unreadable",
276             MATRIX_CONF );
277         return -1;
278     }
279
280     while ( fgets( buf, sizeof(buf), f ) != NULL ) {
281         if ( strncmp( buf, siad, sizeof(siad) - 1 ) == 0 ) {
282             if ( strstr( buf, "OSFC2" ) != NULL )
283                 c2security = 1;
284             break;
285         }
286     }
287
288     fclose(f);
289
290     syslog( LOG_INFO, "clrtxt uam_setup: security level %s",
291         c2security == 0 ? "BSD" : "OSFC2" );
292 #endif /* TRU64 */
293
294   if (uam_register(UAM_SERVER_LOGIN, path, "Cleartxt Passwrd", 
295                 passwd_login, NULL, NULL) < 0)
296         return -1;
297   if (uam_register(UAM_SERVER_PRINTAUTH, path, "ClearTxtUAM",
298                 passwd_printer) < 0)
299         return -1;
300
301   return 0;
302 }
303
304 static void uam_cleanup(void)
305 {
306   uam_unregister(UAM_SERVER_LOGIN, "Cleartxt Passwrd");
307   uam_unregister(UAM_SERVER_PRINTAUTH, "ClearTxtUAM");
308 }
309
310 UAM_MODULE_EXPORT struct uam_export uams_clrtxt = {
311   UAM_MODULE_SERVER,
312   UAM_MODULE_VERSION,
313   uam_setup, uam_cleanup
314 };