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