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