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