]> git.pld-linux.org Git - packages/apache1-mod_auth_yp.git/blame - mod_auth_yp.c
- apxs1 in apache1-devel now
[packages/apache1-mod_auth_yp.git] / mod_auth_yp.c
CommitLineData
a0c37c88 1/*
2 * Authenticates user names/passwords and
3 * user names/groups through NIS (Yellow Pages).
4 *
5 * July 1999
6 * Ian Prideaux
7 */
8
9/*
10 * http_auth: authentication
11 *
12 * Rob McCool
13 *
14 * Adapted to Apache by rst.
15 *
16 * dirkx - Added Authoritative control to allow passing on to lower
17 * modules if and only if the user-id is not known to this
18 * module. A known user with a faulty or absent password still
19 * causes an AuthRequired. The default is 'Authoritative', i.e.
20 * no control is passed along.
21 */
22
23#include <rpc/rpc.h>
24#include <rpcsvc/ypclnt.h>
25#include <rpcsvc/yp_prot.h>
26
27#include "httpd.h"
28#include "http_config.h"
29#include "http_core.h"
30#include "http_log.h"
31#include "http_protocol.h"
32#include "ap_md5.h"
33
34typedef struct auth_yp_config_struct {
35 char *auth_yp_domain;
36 char *auth_yp_pwtable;
37 char *auth_yp_grptable;
38 int auth_yp_authoritative;
39 int auth_yp;
40} auth_yp_config_rec;
41
42static void *create_auth_yp_dir_config(pool *p, char *d)
43{
44 auth_yp_config_rec *sec =
45 (auth_yp_config_rec *) ap_pcalloc(p, sizeof(auth_yp_config_rec));
46 sec->auth_yp_domain = NULL;
47 sec->auth_yp_pwtable = NULL; /* just to illustrate the default really */
48 sec->auth_yp_grptable = NULL; /* unless you have a broken HP cc */
49 sec->auth_yp_authoritative = 1; /* keep the fortress secure by default */
50 sec->auth_yp = NULL;
51 return sec;
52}
53
54static const char *set_auth_yp_slot(cmd_parms *cmd, void *offset, char *f, char *t)
55{
56if (t && strcmp(t, "standard"))
57 return ap_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
58
59return ap_set_file_slot(cmd, offset, f);
60}
61
62static const command_rec auth_yp_cmds[] =
63{
64 {"AuthYPDomain", set_auth_yp_slot,
65 (void *) XtOffsetOf(auth_yp_config_rec, auth_yp_domain), OR_AUTHCFG, TAKE1,
66 "NIS domain name"},
67 {"AuthYPUserTable", set_auth_yp_slot,
68 (void *) XtOffsetOf(auth_yp_config_rec, auth_yp_pwtable), OR_AUTHCFG, TAKE1,
69 "NIS table containing user IDs and passwords"},
70 {"AuthYPGroupTable", set_auth_yp_slot,
71 (void *) XtOffsetOf(auth_yp_config_rec, auth_yp_grptable), OR_AUTHCFG, TAKE1,
72 "NIS table containing group names and member user IDs"},
73 {"AuthYPAuthoritative", ap_set_flag_slot,
74 (void *) XtOffsetOf(auth_yp_config_rec, auth_yp_authoritative),
75 OR_AUTHCFG, FLAG,
76 "Set to 'no' to allow access control to be passed along to lower modules if the UserID is not known to this module"},
77 {"AuthYP", ap_set_flag_slot,
78 (void*)XtOffsetOf(auth_yp_config_rec, auth_yp), OR_AUTHCFG, FLAG,
79 "Authenticate user using yp (nis)"},
80 {NULL}
81};
82
83module MODULE_VAR_EXPORT auth_yp_module;
84
85static char *get_yp_domain(request_rec *r, char *auth_yp_domain)
86{
87char *domainname;
88int err;
89
90if(auth_yp_domain) return(auth_yp_domain);
91
92err=yp_get_default_domain(&domainname);
93if(err == 0)
94 {
95 return(domainname);
96 }
97else
98 {
99 ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "%s", yperr_string(err) );
100 return NULL;
101 }
102}
103
104static char *user_in_yp_group(request_rec *r, const char *group_to_check, char *auth_yp_grptable, char *auth_yp_domain)
105{
106char *user=r->connection->user;
107char *domainname, *value, *groups;
108char groupline[MAX_STRING_LEN], uname[MAX_STRING_LEN];
109int err, valuelen, unameidx, colons;
110
111domainname=get_yp_domain(r, auth_yp_domain);
112if(!domainname) return NULL;
113
114if(!auth_yp_grptable) auth_yp_grptable="group.byname";
115
116err=yp_match(domainname, auth_yp_grptable, group_to_check, strlen(group_to_check), &value, &valuelen);
117if(err != 0)
118 {
119 ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "%s", yperr_string(err) );
120 return NULL;
121 }
122
123strncpy(groupline, value, valuelen);
124groupline[valuelen]=(char)NULL;
125for(colons=3, groups=groupline; colons; groups++)
126 if(*groups == ':') colons--;
127
128while(isprint((int)*groups))
129 {
130 unameidx=0;
131 while(isprint((int)*groups) && *groups != ',')
132 {
133 uname[unameidx++]=*groups++;
134 }
135 groups++;
136 uname[unameidx++]=(char)NULL;
137 printf("%s\n", uname);
138
139 if(!strcmp(user, uname))
140 {
141 /* printf("Found %s\n", argv[2]); */
142 return group_to_check;
143 }
144 }
145/* printf("Unable to find %s\n", argv[2]); */
146return NULL;
147}
148
149static char *get_pw(request_rec *r, char *user, char *auth_yp_pwtable, char *auth_yp_domain)
150{
151char *domainname, *value, *passwd, *passwdend;
152char passwdline[MAX_STRING_LEN];
153int err, valuelen;
154
155domainname=get_yp_domain(r, auth_yp_domain);
156if(!domainname) return NULL;
157
158if(!auth_yp_pwtable) auth_yp_pwtable="passwd.byname";
159err=yp_match(domainname, auth_yp_pwtable, user, strlen(user), &value, &valuelen);
160if(err != 0)
161 {
162 ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "%s", yperr_string(err) );
163 return NULL;
164 }
165
166strcpy(passwdline, value);
167
168for(passwd=passwdline; *passwd!=':'; passwd++);
169passwd++;
170
171for(passwdend=passwd; *passwdend!=':'; passwdend++);
172*passwdend=(char)NULL;
173
174return ap_pstrdup (r->pool, passwd);
175}
176
177/* These functions return 0 if client is OK, and proper error status
178 * if not... either AUTH_REQUIRED, if we made a check, and it failed, or
179 * SERVER_ERROR, if things are so totally confused that we couldn't
180 * figure out how to tell if the client is authorized or not.
181 *
182 * If they return DECLINED, and all other modules also decline, that's
183 * treated by the server core as a configuration error, logged and
184 * reported as such.
185 */
186
187/* Determine user ID, and check if it really is that user, for HTTP
188 * basic authentication...
189 */
190
191static int authenticate_basic_user(request_rec *r)
192{
193 auth_yp_config_rec *sec =
194 (auth_yp_config_rec *) ap_get_module_config(r->per_dir_config, &auth_yp_module);
195 conn_rec *c = r->connection;
196 const char *sent_pw;
197 char *real_pw;
198 char *invalid_pw;
199 int res;
200
201 if ((res = ap_get_basic_auth_pw(r, &sent_pw)))
202 return res;
203
204 /* If YP is not enabled - IanP */
205 if(!sec->auth_yp) return DECLINED;
206
207 if (!(real_pw = get_pw(r, c->user, sec->auth_yp_pwtable, sec->auth_yp_domain))) {
208 if (!(sec->auth_yp_authoritative))
209 return DECLINED;
210 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
211 "user %s not found: %s", c->user, r->uri);
212 ap_note_basic_auth_failure(r);
213 return AUTH_REQUIRED;
214 }
215 invalid_pw = ap_validate_password(sent_pw, real_pw);
216 if (invalid_pw != NULL) {
217 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
218 "user %s: authentication failure for \"%s\": %s",
219 c->user, r->uri, invalid_pw);
220 ap_note_basic_auth_failure(r);
221 return AUTH_REQUIRED;
222 }
223 return OK;
224}
225
226/* Checking ID */
227
228static int check_user_access(request_rec *r)
229{
230 auth_yp_config_rec *sec =
231 (auth_yp_config_rec *) ap_get_module_config(r->per_dir_config, &auth_yp_module);
232 char *user = r->connection->user;
233 int m = r->method_number;
234 int method_restricted = 0;
235 register int x;
236 const char *t, *w;
237 table *grpstatus;
238 const array_header *reqs_arr = ap_requires(r);
239 require_line *reqs;
240
241 /* If YP is not enabled - IanP */
242 if(!sec->auth_yp) return DECLINED;
243
244 /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive,
245 * then any user will do.
246 */
247 if (!reqs_arr) return (OK);
248
249 reqs = (require_line *) reqs_arr->elts;
250
251 for (x = 0; x < reqs_arr->nelts; x++) {
252
253 if (!(reqs[x].method_mask & (1 << m)))
254 continue;
255
256 method_restricted = 1;
257
258 t = reqs[x].requirement;
259 w = ap_getword_white(r->pool, &t);
260 if (!strcmp(w, "valid-user"))
261 return OK;
262 if (!strcmp(w, "user")) {
263 while (t[0]) {
264 w = ap_getword_conf(r->pool, &t);
265 if (!strcmp(user, w))
266 return OK;
267 }
268 }
269 else if (!strcmp(w, "group")) {
270 /* if (!grpstatus)
271 return DECLINED; /* DBM group? Something else? */
272
273 while (t[0]) {
274 w = ap_getword_conf(r->pool, &t); /* w=group name - IanP */
275 /* New Function - IanP */
276 if(user_in_yp_group(r, w, sec->auth_yp_grptable, sec->auth_yp_domain))
277 return OK;
278 }
279 } else if (sec->auth_yp_authoritative) {
280 /* if we aren't authoritative, any require directive could be
281 * valid even if we don't grok it. However, if we are
282 * authoritative, we can warn the user they did something wrong.
283 * That something could be a missing "AuthAuthoritative off", but
284 * more likely is a typo in the require directive.
285 */
286 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
287 "access to %s failed, reason: unknown require directive:"
288 "\"%s\"", r->uri, reqs[x].requirement);
289 }
290 }
291
292 if (!method_restricted)
293 return OK;
294
295 if (!(sec->auth_yp_authoritative))
296 return DECLINED;
297
298 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
299 "access to %s failed, reason: user %s not allowed access",
300 r->uri, user);
301
302 ap_note_basic_auth_failure(r);
303 return AUTH_REQUIRED;
304}
305
306module MODULE_VAR_EXPORT auth_yp_module =
307{
308 STANDARD_MODULE_STUFF,
309 NULL, /* initializer */
310 create_auth_yp_dir_config, /* dir config creater */
311 NULL, /* dir merger --- default is to override */
312 NULL, /* server config */
313 NULL, /* merge server config */
314 auth_yp_cmds, /* command table */
315 NULL, /* handlers */
316 NULL, /* filename translation */
317 authenticate_basic_user, /* check_user_id */
318 check_user_access, /* check auth */
319 NULL, /* check access */
320 NULL, /* type_checker */
321 NULL, /* fixups */
322 NULL, /* logger */
323 NULL, /* header parser */
324 NULL, /* child_init */
325 NULL, /* child_exit */
326 NULL /* post read-request */
327};
This page took 0.13683 seconds and 4 git commands to generate.