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