]> andersk Git - mod-vhost-ldap.git/blame_incremental - mod_vhost_ldap.c
Add more debug info on what we are translating
[mod-vhost-ldap.git] / mod_vhost_ldap.c
... / ...
CommitLineData
1/* ============================================================
2 * Copyright (c) 2003-2004, Ondrej Sury
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19/*
20 * mod_vhost_ldap.c --- read virtual host config from LDAP directory
21 */
22
23#define CORE_PRIVATE
24
25#include <unistd.h>
26
27#include "httpd.h"
28#include "http_config.h"
29#include "http_core.h"
30#include "http_log.h"
31#include "http_request.h"
32#include "apr_version.h"
33#include "apr_ldap.h"
34#include "apr_strings.h"
35#include "apr_reslist.h"
36#include "util_ldap.h"
37
38#if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP)
39#error mod_vhost_ldap requires APR-util to have LDAP support built in
40#endif
41
42#if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE)
43#define HAVE_UNIX_SUEXEC
44#endif
45
46#ifdef HAVE_UNIX_SUEXEC
47#include "unixd.h" /* Contains the suexec_identity hook used on Unix */
48#endif
49
50#define MIN_UID 100
51#define MIN_GID 100
52
53module AP_MODULE_DECLARE_DATA vhost_ldap_module;
54
55typedef enum {
56 MVL_UNSET, MVL_DISABLED, MVL_ENABLED
57} mod_vhost_ldap_status_e;
58
59typedef struct mod_vhost_ldap_config_t {
60 mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */
61
62 /* These parameters are all derived from the VhostLDAPURL directive */
63 char *url; /* String representation of LDAP URL */
64
65 char *host; /* Name of the LDAP server (or space separated list) */
66 int port; /* Port of the LDAP server */
67 char *basedn; /* Base DN to do all searches from */
68 int scope; /* Scope of the search */
69 char *filter; /* Filter to further limit the search */
70 deref_options deref; /* how to handle alias dereferening */
71
72 char *binddn; /* DN to bind to server (can be NULL) */
73 char *bindpw; /* Password to bind to server (can be NULL) */
74
75 int have_deref; /* Set if we have found an Deref option */
76 int have_ldap_url; /* Set if we have found an LDAP url */
77
78 int secure; /* True if SSL connections are requested */
79
80 char *fallback; /* Fallback virtual host */
81
82} mod_vhost_ldap_config_t;
83
84typedef struct mod_vhost_ldap_request_t {
85 char *dn; /* The saved dn from a successful search */
86 char *name; /* ServerName */
87 char *admin; /* ServerAdmin */
88 char *docroot; /* DocumentRoot */
89 char *cgiroot; /* ScriptAlias */
90 char *uid; /* Suexec Uid */
91 char *gid; /* Suexec Gid */
92 char *saved_docroot; /* Saved DocumentRoot */
93} mod_vhost_ldap_request_t;
94
95char *attributes[] =
96 { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
97
98#if (APR_MAJOR_VERSION >= 1)
99static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
100static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
101static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
102static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
103static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
104static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
105static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
106
107static void ImportULDAPOptFn(void)
108{
109 util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
110 util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
111 util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
112 util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
113 util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
114 util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
115 util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
116}
117#endif
118
119/* Taken from server/core.c */
120static int set_document_root(request_rec *r, const char *arg)
121{
122 void *sconf = r->server->module_config;
123 core_server_config *conf = ap_get_module_config(sconf, &core_module);
124
125 /* Make it absolute, relative to ServerRoot */
126 arg = ap_server_root_relative(r->pool, arg);
127
128 if (arg == NULL) {
129 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
130 "[mod_vhost_ldap.c] set_document_root: DocumentRoot [%s] must be a directory",
131 arg);
132
133 return HTTP_INTERNAL_SERVER_ERROR;
134 }
135
136 /* TODO: ap_configtestonly && ap_docrootcheck && */
137 if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg,
138 APR_FILEPATH_TRUENAME, r->pool) != APR_SUCCESS
139 || !ap_is_directory(r->pool, arg)) {
140
141 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0,
142 r,
143 "[mod_vhost_ldap.c] set_document_root: Warning: DocumentRoot [%s] does not exist",
144 arg);
145 conf->ap_document_root = arg;
146 }
147 return OK;
148}
149
150
151static int mod_vhost_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
152{
153 /* make sure that mod_ldap (util_ldap) is loaded */
154 if (ap_find_linked_module("util_ldap.c") == NULL) {
155 ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
156 "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
157 "must be loaded in order for mod_vhost_ldap to function properly");
158 return HTTP_INTERNAL_SERVER_ERROR;
159
160 }
161
162 ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
163
164 return OK;
165}
166
167static void *
168mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s)
169{
170 mod_vhost_ldap_config_t *conf =
171 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t));
172
173 conf->enabled = MVL_UNSET;
174 conf->have_ldap_url = 0;
175 conf->have_deref = 0;
176 conf->binddn = NULL;
177 conf->bindpw = NULL;
178 conf->deref = always;
179 conf->fallback = NULL;
180
181 return conf;
182}
183
184static void *
185mod_vhost_ldap_merge_server_config(apr_pool_t *p, void *parentv, void *childv)
186{
187 mod_vhost_ldap_config_t *parent = (mod_vhost_ldap_config_t *) parentv;
188 mod_vhost_ldap_config_t *child = (mod_vhost_ldap_config_t *) childv;
189 mod_vhost_ldap_config_t *conf =
190 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof(mod_vhost_ldap_config_t));
191
192 if (child->enabled == MVL_UNSET) {
193 conf->enabled = parent->enabled;
194 } else {
195 conf->enabled = child->enabled;
196 }
197
198 if (child->have_ldap_url) {
199 conf->have_ldap_url = child->have_ldap_url;
200 conf->url = child->url;
201 conf->host = child->host;
202 conf->port = child->port;
203 conf->basedn = child->basedn;
204 conf->scope = child->scope;
205 conf->filter = child->filter;
206 conf->secure = child->secure;
207 } else {
208 conf->have_ldap_url = parent->have_ldap_url;
209 conf->url = parent->url;
210 conf->host = parent->host;
211 conf->port = parent->port;
212 conf->basedn = parent->basedn;
213 conf->scope = parent->scope;
214 conf->filter = parent->filter;
215 conf->secure = parent->secure;
216 }
217 if (child->have_deref) {
218 conf->have_deref = child->have_deref;
219 conf->deref = child->deref;
220 } else {
221 conf->have_deref = parent->have_deref;
222 conf->deref = parent->deref;
223 }
224
225 conf->binddn = (child->binddn ? child->binddn : parent->binddn);
226 conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw);
227
228 conf->fallback = (child->fallback ? child->fallback : parent->fallback);
229
230 return conf;
231}
232
233/*
234 * Use the ldap url parsing routines to break up the ldap url into
235 * host and port.
236 */
237static const char *mod_vhost_ldap_parse_url(cmd_parms *cmd,
238 void *dummy,
239 const char *url)
240{
241 int result;
242 apr_ldap_url_desc_t *urld;
243#if (APR_MAJOR_VERSION >= 1)
244 apr_ldap_err_t *result_err;
245#endif
246
247 mod_vhost_ldap_config_t *conf =
248 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
249 &vhost_ldap_module);
250
251 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
252 cmd->server, "[mod_vhost_ldap.c] url parse: `%s'",
253 url);
254
255#if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */
256 result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err));
257 if (result != LDAP_SUCCESS) {
258 return result_err->reason;
259 }
260#else
261 result = apr_ldap_url_parse(url, &(urld));
262 if (result != LDAP_SUCCESS) {
263 switch (result) {
264 case LDAP_URL_ERR_NOTLDAP:
265 return "LDAP URL does not begin with ldap://";
266 case LDAP_URL_ERR_NODN:
267 return "LDAP URL does not have a DN";
268 case LDAP_URL_ERR_BADSCOPE:
269 return "LDAP URL has an invalid scope";
270 case LDAP_URL_ERR_MEM:
271 return "Out of memory parsing LDAP URL";
272 default:
273 return "Could not parse LDAP URL";
274 }
275 }
276#endif
277 conf->url = apr_pstrdup(cmd->pool, url);
278
279 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
280 cmd->server, "[mod_vhost_ldap.c] url parse: Host: %s", urld->lud_host);
281 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
282 cmd->server, "[mod_vhost_ldap.c] url parse: Port: %d", urld->lud_port);
283 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
284 cmd->server, "[mod_vhost_ldap.c] url parse: DN: %s", urld->lud_dn);
285 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
286 cmd->server, "[mod_vhost_ldap.c] url parse: attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)");
287 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
288 cmd->server, "[mod_vhost_ldap.c] url parse: scope: %s",
289 (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
290 urld->lud_scope == LDAP_SCOPE_BASE? "base" :
291 urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"));
292 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
293 cmd->server, "[mod_vhost_ldap.c] url parse: filter: %s", urld->lud_filter);
294
295 /* Set all the values, or at least some sane defaults */
296 if (conf->host) {
297 char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2);
298 strcpy(p, urld->lud_host);
299 strcat(p, " ");
300 strcat(p, conf->host);
301 conf->host = p;
302 }
303 else {
304 conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost";
305 }
306 conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
307
308 conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ?
309 LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE;
310
311 if (urld->lud_filter) {
312 if (urld->lud_filter[0] == '(') {
313 /*
314 * Get rid of the surrounding parens; later on when generating the
315 * filter, they'll be put back.
316 */
317 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1);
318 conf->filter[strlen(conf->filter)-1] = '\0';
319 }
320 else {
321 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
322 }
323 }
324 else {
325 conf->filter = "objectClass=apacheConfig";
326 }
327
328 /* "ldaps" indicates secure ldap connections desired
329 */
330 if (strncasecmp(url, "ldaps", 5) == 0)
331 {
332 conf->secure = 1;
333 conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
334 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
335 "LDAP: vhost_ldap using SSL connections");
336 }
337 else
338 {
339 conf->secure = 0;
340 conf->port = urld->lud_port? urld->lud_port : LDAP_PORT;
341 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
342 "LDAP: vhost_ldap not using SSL connections");
343 }
344
345 conf->have_ldap_url = 1;
346#if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
347 apr_ldap_free_urldesc(urld);
348#endif
349 return NULL;
350}
351
352static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled)
353{
354 mod_vhost_ldap_config_t *conf =
355 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
356 &vhost_ldap_module);
357
358 conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED;
359
360 return NULL;
361}
362
363static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn)
364{
365 mod_vhost_ldap_config_t *conf =
366 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
367 &vhost_ldap_module);
368
369 conf->binddn = apr_pstrdup(cmd->pool, binddn);
370 return NULL;
371}
372
373static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw)
374{
375 mod_vhost_ldap_config_t *conf =
376 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
377 &vhost_ldap_module);
378
379 conf->bindpw = apr_pstrdup(cmd->pool, bindpw);
380 return NULL;
381}
382
383static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref)
384{
385 mod_vhost_ldap_config_t *conf =
386 (mod_vhost_ldap_config_t *)ap_get_module_config (cmd->server->module_config,
387 &vhost_ldap_module);
388
389 if (strcmp(deref, "never") == 0 || strcasecmp(deref, "off") == 0) {
390 conf->deref = never;
391 conf->have_deref = 1;
392 }
393 else if (strcmp(deref, "searching") == 0) {
394 conf->deref = searching;
395 conf->have_deref = 1;
396 }
397 else if (strcmp(deref, "finding") == 0) {
398 conf->deref = finding;
399 conf->have_deref = 1;
400 }
401 else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) {
402 conf->deref = always;
403 conf->have_deref = 1;
404 }
405 else {
406 return "Unrecognized value for VhostLDAPAliasDereference directive";
407 }
408 return NULL;
409}
410
411static const char *mod_vhost_ldap_set_fallback(cmd_parms *cmd, void *dummy, const char *fallback)
412{
413 mod_vhost_ldap_config_t *conf =
414 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
415 &vhost_ldap_module);
416
417 conf->fallback = apr_pstrdup(cmd->pool, fallback);
418 return NULL;
419}
420
421command_rec mod_vhost_ldap_cmds[] = {
422 AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF,
423 "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
424 "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
425 "<ul>\n"
426 "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
427 "to specify redundant servers.\n"
428 "<li>Port is optional, and specifies the port to connect to.\n"
429 "<li>basedn specifies the base DN to start searches from\n"
430 "</ul>\n"),
431
432 AP_INIT_TAKE1 ("VhostLDAPBindDN", mod_vhost_ldap_set_binddn, NULL, RSRC_CONF,
433 "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."),
434
435 AP_INIT_TAKE1("VhostLDAPBindPassword", mod_vhost_ldap_set_bindpw, NULL, RSRC_CONF,
436 "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
437
438 AP_INIT_FLAG("VhostLDAPEnabled", mod_vhost_ldap_set_enabled, NULL, RSRC_CONF,
439 "Set to off to disable vhost_ldap, even if it's been enabled in a higher tree"),
440
441 AP_INIT_TAKE1("VhostLDAPDereferenceAliases", mod_vhost_ldap_set_deref, NULL, RSRC_CONF,
442 "Determines how aliases are handled during a search. Can be one of the"
443 "values \"never\", \"searching\", \"finding\", or \"always\". "
444 "Defaults to always."),
445
446 AP_INIT_TAKE1("VhostLDAPFallback", mod_vhost_ldap_set_fallback, NULL, RSRC_CONF,
447 "Set default virtual host which will be used when requested hostname"
448 "is not found in LDAP database. This option can be used to display"
449 "\"virtual host not found\" type of page."),
450
451 {NULL}
452};
453
454#define FILTER_LENGTH MAX_STRING_LEN
455static int mod_vhost_ldap_translate_name(request_rec *r)
456{
457 request_rec *top = (r->main)?r->main:r;
458 mod_vhost_ldap_request_t *reqc;
459 apr_table_t *e;
460 int failures = 0;
461 const char **vals = NULL;
462 char filtbuf[FILTER_LENGTH];
463 mod_vhost_ldap_config_t *conf =
464 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module);
465 util_ldap_connection_t *ldc = NULL;
466 int result = 0;
467 const char *dn = NULL;
468 char *cgi;
469 const char *hostname = NULL;
470 int is_fallback = 0;
471 int sleep = 1;
472
473 reqc =
474 (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
475 memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
476
477 ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
478
479 // mod_vhost_ldap is disabled or we don't have LDAP Url
480 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
481 return DECLINED;
482 }
483
484start_over:
485
486 if (conf->host) {
487 ldc = util_ldap_connection_find(r, conf->host, conf->port,
488 conf->binddn, conf->bindpw, conf->deref,
489 conf->secure);
490 }
491 else {
492 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
493 "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
494 return HTTP_INTERNAL_SERVER_ERROR;
495 }
496
497 hostname = r->hostname;
498
499fallback:
500
501 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
502 "[mod_vhost_ldap.c]: translating hostname [%s], uri [%s]", hostname, r->uri);
503
504 apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname);
505
506 result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
507 attributes, filtbuf, &dn, &vals);
508
509 util_ldap_connection_close(ldc);
510
511 /* sanity check - if server is down, retry it up to 5 times */
512 if (AP_LDAP_IS_SERVER_DOWN(result) ||
513 (result == LDAP_TIMEOUT) ||
514 (result == LDAP_CONNECT_ERROR)) {
515 if (failures++ <= 5) {
516 /* Back-off exponentially */
517 apr_sleep(apr_time_from_sec(sleep));
518 sleep = sleep*2;
519 goto start_over;
520 } else {
521 return HTTP_GATEWAY_TIME_OUT;
522 }
523 }
524
525 if (result == LDAP_NO_SUCH_OBJECT) {
526 if (conf->fallback && (is_fallback++ <= 0)) {
527 ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
528 "[mod_vhost_ldap.c] translate: "
529 "virtual host %s not found, trying fallback %s",
530 hostname, conf->fallback);
531 hostname = conf->fallback;
532 goto fallback;
533 }
534
535 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
536 "[mod_vhost_ldap.c] translate: "
537 "virtual host %s not found",
538 hostname);
539
540 return HTTP_BAD_REQUEST;
541 }
542
543 /* handle bind failure */
544 if (result != LDAP_SUCCESS) {
545 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
546 "[mod_vhost_ldap.c] translate: "
547 "translate failed; virtual host %s; URI %s [%s]",
548 hostname, r->uri, ldap_err2string(result));
549 return HTTP_INTERNAL_SERVER_ERROR;
550 }
551
552 /* mark the user and DN */
553 reqc->dn = apr_pstrdup(r->pool, dn);
554
555 /* Optimize */
556 if (vals) {
557 int i = 0;
558 while (attributes[i]) {
559
560 if (strcasecmp (attributes[i], "apacheServerName") == 0) {
561 reqc->name = apr_pstrdup (r->pool, vals[i]);
562 }
563 else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) {
564 reqc->admin = apr_pstrdup (r->pool, vals[i]);
565 }
566 else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) {
567 reqc->docroot = apr_pstrdup (r->pool, vals[i]);
568 }
569 else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) {
570 reqc->cgiroot = apr_pstrdup (r->pool, vals[i]);
571 }
572 else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) {
573 reqc->uid = apr_pstrdup(r->pool, vals[i]);
574 }
575 else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) {
576 reqc->gid = apr_pstrdup(r->pool, vals[i]);
577 }
578 i++;
579 }
580 }
581
582 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
583 "[mod_vhost_ldap.c]: loaded from ldap: "
584 "apacheServerName: %s, "
585 "apacheServerAdmin: %s, "
586 "apacheDocumentRoot: %s, "
587 "apacheScriptAlias: %s, "
588 "apacheSuexecUid: %s, "
589 "apacheSuexecGid: %s",
590 reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid);
591
592 if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
593 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
594 "[mod_vhost_ldap.c] translate: "
595 "translate failed; ServerName or DocumentRoot not defined");
596 return HTTP_INTERNAL_SERVER_ERROR;
597 }
598
599 cgi = NULL;
600
601 if (reqc->cgiroot) {
602 cgi = strstr(r->uri, "cgi-bin/");
603 if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
604 cgi = NULL;
605 }
606 }
607 if (cgi) {
608 /* Set exact filename for CGI script */
609 cgi = apr_pstrcat(r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
610 if ((cgi = ap_server_root_relative(r->pool, cgi))) {
611 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
612 "[mod_vhost_ldap.c]: ap_document_root is: %s", ap_document_root(r));
613 r->filename = cgi;
614 r->handler = "cgi-script";
615 apr_table_setn(r->notes, "alias-forced-type", r->handler);
616 }
617 } else if (r->uri[0] == '/') {
618 /* we don't set r->filename here, and let other modules do it
619 * this allows other modules (mod_rewrite.c) to work as usual
620 */
621 /* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */
622 } else {
623 /* We don't handle non-file requests here */
624 return DECLINED;
625 }
626
627 top->server->server_hostname = apr_pstrdup (top->pool, reqc->name);
628
629 if (reqc->admin) {
630 top->server->server_admin = apr_pstrdup (top->pool, reqc->admin);
631 }
632
633 reqc->saved_docroot = apr_pstrdup(top->pool, ap_document_root(r));
634
635 result = set_document_root(r, reqc->docroot);
636 if (result != OK) {
637 return HTTP_INTERNAL_SERVER_ERROR;
638 }
639
640 // set environment variables
641 e = top->subprocess_env;
642 apr_table_addn(e, "DOCUMENT_ROOT", reqc->docroot);
643
644 /* Hack to allow post-processing by other modules (mod_rewrite, mod_alias) */
645 return DECLINED;
646}
647
648static int mod_vhost_ldap_cleanup(request_rec * r)
649{
650 mod_vhost_ldap_request_t *reqc =
651 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
652 &vhost_ldap_module);
653
654 /* Set ap_document_root back to saved value */
655 return set_document_root(r, reqc->saved_docroot);
656}
657
658#ifdef HAVE_UNIX_SUEXEC
659static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
660{
661 ap_unix_identity_t *ugid = NULL;
662 mod_vhost_ldap_config_t *conf =
663 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config,
664 &vhost_ldap_module);
665 mod_vhost_ldap_request_t *req =
666 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
667 &vhost_ldap_module);
668
669 uid_t uid = -1;
670 gid_t gid = -1;
671
672 // mod_vhost_ldap is disabled or we don't have LDAP Url
673 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
674 return NULL;
675 }
676
677 if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) {
678 return NULL;
679 }
680
681 if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) {
682 return NULL;
683 }
684
685 uid = (uid_t)atoll(req->uid);
686 gid = (gid_t)atoll(req->gid);
687
688 if ((uid < MIN_UID)||(gid < MIN_GID)) {
689 return NULL;
690 }
691
692 ugid->uid = uid;
693 ugid->gid = gid;
694 ugid->userdir = 0;
695
696 return ugid;
697}
698#endif
699
700static void
701mod_vhost_ldap_register_hooks (apr_pool_t * p)
702{
703
704 /*
705 * Run before mod_rewrite
706 */
707 static const char * const aszRewrite[]={ "mod_rewrite.c", NULL };
708
709 ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE);
710 ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, aszRewrite, APR_HOOK_FIRST);
711 ap_hook_fixups(mod_vhost_ldap_cleanup, aszRewrite, NULL, APR_HOOK_MIDDLE);
712#ifdef HAVE_UNIX_SUEXEC
713 ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
714#endif
715#if (APR_MAJOR_VERSION >= 1)
716 ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
717#endif
718}
719
720module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
721 STANDARD20_MODULE_STUFF,
722 NULL,
723 NULL,
724 mod_vhost_ldap_create_server_config,
725 mod_vhost_ldap_merge_server_config,
726 mod_vhost_ldap_cmds,
727 mod_vhost_ldap_register_hooks,
728};
This page took 0.076789 seconds and 5 git commands to generate.