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