]> andersk Git - mod-vhost-ldap.git/blame - mod_vhost_ldap.c
Hard-code ~username for LDAP vhosts.
[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
553be6af 52const char USERDIR[] = "web_scripts";
7f9875bb
OS
53
54module AP_MODULE_DECLARE_DATA vhost_ldap_module;
55
8196fae3
OS
56typedef enum {
57 MVL_UNSET, MVL_DISABLED, MVL_ENABLED
58} mod_vhost_ldap_status_e;
59
7f9875bb 60typedef struct mod_vhost_ldap_config_t {
8196fae3 61 mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */
7f9875bb
OS
62
63 /* These parameters are all derived from the VhostLDAPURL directive */
64 char *url; /* String representation of LDAP URL */
65
66 char *host; /* Name of the LDAP server (or space separated list) */
67 int port; /* Port of the LDAP server */
68 char *basedn; /* Base DN to do all searches from */
69 int scope; /* Scope of the search */
70 char *filter; /* Filter to further limit the search */
71 deref_options deref; /* how to handle alias dereferening */
72
73 char *binddn; /* DN to bind to server (can be NULL) */
74 char *bindpw; /* Password to bind to server (can be NULL) */
75
8196fae3 76 int have_deref; /* Set if we have found an Deref option */
7f9875bb
OS
77 int have_ldap_url; /* Set if we have found an LDAP url */
78
79 int secure; /* True if SSL connections are requested */
6056cddb
OS
80
81 char *fallback; /* Fallback virtual host */
82
7f9875bb
OS
83} mod_vhost_ldap_config_t;
84
85typedef struct mod_vhost_ldap_request_t {
86 char *dn; /* The saved dn from a successful search */
87 char *name; /* ServerName */
88 char *admin; /* ServerAdmin */
89 char *docroot; /* DocumentRoot */
9ee2dda1 90 char *cgiroot; /* ScriptAlias */
7f9875bb
OS
91 char *uid; /* Suexec Uid */
92 char *gid; /* Suexec Gid */
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);
9ee2dda1
OS
433 core_server_config * core =
434 (core_server_config *) ap_get_module_config(r->server->module_config, &core_module);
7f9875bb
OS
435 util_ldap_connection_t *ldc = NULL;
436 int result = 0;
437 const char *dn = NULL;
438 char *cgi;
6056cddb
OS
439 const char *hostname = NULL;
440 int is_fallback = 0;
7f9875bb 441
b5043ccb 442 reqc =
7f9875bb 443 (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
8503d00b 444 memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
b5043ccb
OS
445
446 ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
7f9875bb 447
8196fae3
OS
448 // mod_vhost_ldap is disabled or we don't have LDAP Url
449 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
7f9875bb
OS
450 return DECLINED;
451 }
452
453start_over:
454
8196fae3
OS
455 if (conf->host) {
456 ldc = util_ldap_connection_find(r, conf->host, conf->port,
457 conf->binddn, conf->bindpw, conf->deref,
458 conf->secure);
7f9875bb
OS
459 }
460 else {
461 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
fb323462 462 "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
7f9875bb
OS
463 return DECLINED;
464 }
465
6056cddb
OS
466 hostname = r->hostname;
467
468fallback:
469
fb323462 470 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
6f705808 471 "[mod_vhost_ldap.c]: translating %s", r->uri);
7f9875bb 472
6056cddb 473 apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname);
7f9875bb 474
8196fae3 475 result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
7f9875bb
OS
476 attributes, filtbuf, &dn, &vals);
477
478 util_ldap_connection_close(ldc);
479
480 /* sanity check - if server is down, retry it up to 5 times */
481 if (result == LDAP_SERVER_DOWN) {
482 if (failures++ <= 5) {
483 goto start_over;
484 }
485 }
486
6056cddb
OS
487 if ((result == LDAP_NO_SUCH_OBJECT)) {
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
502 return DECLINED;
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));
7f9875bb
OS
511 return DECLINED;
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");
558 return DECLINED;
559 }
560
561 cgi = NULL;
562
553be6af 563#if 0
b5043ccb 564 if (reqc->cgiroot) {
6f705808
OS
565 cgi = strstr(r->uri, "cgi-bin/");
566 if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
7f9875bb
OS
567 cgi = NULL;
568 }
9ee2dda1 569 }
9ee2dda1 570 if (cgi) {
b5043ccb 571 r->filename = apr_pstrcat (r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
9ee2dda1
OS
572 r->handler = "cgi-script";
573 apr_table_setn(r->notes, "alias-forced-type", r->handler);
553be6af
AK
574#endif
575 /* This is a quick, dirty hack. I should be shot for taking 6.170
576 * this term and being willing to write a quick, dirty hack. */
577
578 if (strncmp(r->uri, "/~", 2) == 0) {
579 char *username;
580 uid_t uid = (uid_t)atoll(reqc->uid);
581 if (apr_uid_name_get(&username, uid, r->pool) != APR_SUCCESS) {
582 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
583 "could not get username for uid %d", uid);
584 return DECLINED;
585 }
586 if (strncmp(r->uri + 2, username, strlen(username)) == 0 &&
587 r->uri[2 + strlen(username)] == '/') {
588 char *homedir;
589 if (apr_uid_homepath_get(&homedir, username, r->pool) != APR_SUCCESS) {
590 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
591 "could not get home directory for user %s", username);
592 return DECLINED;
593 }
594 r->filename = apr_pstrcat(r->pool, homedir, "/", USERDIR, r->uri + 2 + strlen(username), NULL);
595 }
6f705808 596 } else if (r->uri[0] == '/') {
b5043ccb 597 r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL);
9ee2dda1 598 } else {
6f705808 599 return DECLINED;
7f9875bb
OS
600 }
601
19d58500 602 top->server->server_hostname = apr_pstrdup (top->pool, reqc->name);
7f9875bb 603
b5043ccb 604 if (reqc->admin) {
19d58500 605 top->server->server_admin = apr_pstrdup (top->pool, reqc->admin);
7f9875bb
OS
606 }
607
608 // set environment variables
b5043ccb
OS
609 e = top->subprocess_env;
610 apr_table_addn (e, "SERVER_ROOT", reqc->docroot);
7f9875bb 611
b5043ccb 612 core->ap_document_root = apr_pstrdup(top->pool, reqc->docroot);
9ee2dda1 613
7f9875bb
OS
614 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
615 "[mod_vhost_ldap.c]: translated to %s", r->filename);
616
617 return OK;
618}
619
620#ifdef HAVE_UNIX_SUEXEC
621static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
622{
623 ap_unix_identity_t *ugid = NULL;
8196fae3 624 mod_vhost_ldap_config_t *conf =
7f9875bb
OS
625 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config,
626 &vhost_ldap_module);
627 mod_vhost_ldap_request_t *req =
628 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
629 &vhost_ldap_module);
630
631 uid_t uid = -1;
632 gid_t gid = -1;
633
8196fae3
OS
634 // mod_vhost_ldap is disabled or we don't have LDAP Url
635 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
7f9875bb
OS
636 return NULL;
637 }
638
639 if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) {
640 return NULL;
641 }
642
643 if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) {
644 return NULL;
645 }
646
647 uid = (uid_t)atoll(req->uid);
648 gid = (gid_t)atoll(req->gid);
649
eea38f6d 650 if ((uid < MIN_UID)||(gid < MIN_GID)) {
7f9875bb
OS
651 return NULL;
652 }
653
654 ugid->uid = uid;
655 ugid->gid = gid;
656 ugid->userdir = 0;
657
658 return ugid;
659}
660#endif
661
662static void
663mod_vhost_ldap_register_hooks (apr_pool_t * p)
664{
665 ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE);
666 ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
667#ifdef HAVE_UNIX_SUEXEC
668 ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
669#endif
8503d00b 670#if (APR_MAJOR_VERSION >= 1)
3b8a47e0
OS
671 ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
672#endif
7f9875bb
OS
673}
674
675module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
676 STANDARD20_MODULE_STUFF,
677 NULL,
678 NULL,
679 mod_vhost_ldap_create_server_config,
8196fae3 680 mod_vhost_ldap_merge_server_config,
7f9875bb
OS
681 mod_vhost_ldap_cmds,
682 mod_vhost_ldap_register_hooks,
683};
This page took 2.241579 seconds and 5 git commands to generate.