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