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