]> andersk Git - mod-vhost-ldap.git/blob - mod_vhost_ldap.c
fix archive target in Makefile
[mod-vhost-ldap.git] / mod_vhost_ldap.c
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
23 #define CORE_PRIVATE
24
25 #include <unistd.h>
26
27 #include "httpd.h"
28 #include "http_config.h"
29 #include "http_core.h"
30 #include "http_log.h"
31 #include "http_request.h"
32 #include "apr_version.h"
33 #include "apr_ldap.h"
34 #include "apr_strings.h"
35 #include "apr_reslist.h"
36 #include "util_ldap.h"
37
38 #if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP)
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
50 #define MIN_UID 100
51 #define MIN_GID 100
52
53 module AP_MODULE_DECLARE_DATA vhost_ldap_module;
54
55 typedef enum {
56     MVL_UNSET, MVL_DISABLED, MVL_ENABLED
57 } mod_vhost_ldap_status_e;
58
59 typedef struct mod_vhost_ldap_config_t {
60     mod_vhost_ldap_status_e enabled;                    /* Is vhost_ldap enabled? */
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
75     int have_deref;                     /* Set if we have found an Deref option */
76     int have_ldap_url;                  /* Set if we have found an LDAP url */
77
78     int secure;                         /* True if SSL connections are requested */
79
80     char *fallback;                     /* Fallback virtual host */
81
82 } mod_vhost_ldap_config_t;
83
84 typedef 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 */
89     char *cgiroot;                      /* ScriptAlias */
90     char *uid;                          /* Suexec Uid */
91     char *gid;                          /* Suexec Gid */
92 } mod_vhost_ldap_request_t;
93
94 char *attributes[] =
95   { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
96
97 #if (APR_MAJOR_VERSION >= 1)
98 static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
99 static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
100 static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
101 static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
102 static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
103 static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
104 static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
105
106 static 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
118 static 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
129     ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
130
131     return OK;
132 }
133
134 static void *
135 mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s)
136 {
137     mod_vhost_ldap_config_t *conf =
138         (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t));
139
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;
146     conf->fallback = NULL;
147
148     return conf;
149 }
150
151 static void *
152 mod_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));
158
159     if (child->enabled == MVL_UNSET) {
160         conf->enabled = parent->enabled;
161     } else {
162         conf->enabled = child->enabled;
163     }
164
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
195     conf->fallback = (child->fallback ? child->fallback : parent->fallback);
196
197     return conf;
198 }
199
200 /* 
201  * Use the ldap url parsing routines to break up the ldap url into
202  * host and port.
203  */
204 static 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;
210 #if (APR_MAJOR_VERSION >= 1)
211     apr_ldap_err_t *result_err;
212 #endif
213
214     mod_vhost_ldap_config_t *conf =
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);
221     
222 #if (APR_MAJOR_VERSION >= 1)    /* for apache >= 2.2 */
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
228     result = apr_ldap_url_parse(url, &(urld));
229     if (result != LDAP_SUCCESS) {
230         switch (result) {
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";
241         }
242     }
243 #endif
244     conf->url = apr_pstrdup(cmd->pool, url);
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 */
263     if (conf->host) {
264         char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2);
265         strcpy(p, urld->lud_host);
266         strcat(p, " ");
267         strcat(p, conf->host);
268         conf->host = p;
269     }
270     else {
271         conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost";
272     }
273     conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
274
275     conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ?
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              */
284             conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1);
285             conf->filter[strlen(conf->filter)-1] = '\0';
286         }
287         else {
288             conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
289         }
290     }
291     else {
292         conf->filter = "objectClass=apacheConfig";
293     }
294
295       /* "ldaps" indicates secure ldap connections desired
296       */
297     if (strncasecmp(url, "ldaps", 5) == 0)
298     {
299         conf->secure = 1;
300         conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
301         ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
302                      "LDAP: vhost_ldap using SSL connections");
303     }
304     else
305     {
306         conf->secure = 0;
307         conf->port = urld->lud_port? urld->lud_port : LDAP_PORT;
308         ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, 
309                      "LDAP: vhost_ldap not using SSL connections");
310     }
311
312     conf->have_ldap_url = 1;
313 #if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
314     apr_ldap_free_urldesc(urld);
315 #endif
316     return NULL;
317 }
318
319 static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled)
320 {
321     mod_vhost_ldap_config_t *conf =
322         (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
323                                                         &vhost_ldap_module);
324
325     conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED;
326
327     return NULL;
328 }
329
330 static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn)
331 {
332     mod_vhost_ldap_config_t *conf =
333         (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
334                                                         &vhost_ldap_module);
335
336     conf->binddn = apr_pstrdup(cmd->pool, binddn);
337     return NULL;
338 }
339
340 static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw)
341 {
342     mod_vhost_ldap_config_t *conf =
343         (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
344                                                         &vhost_ldap_module);
345
346     conf->bindpw = apr_pstrdup(cmd->pool, bindpw);
347     return NULL;
348 }
349
350 static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref)
351 {
352     mod_vhost_ldap_config_t *conf = 
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) {
357         conf->deref = never;
358         conf->have_deref = 1;
359     }
360     else if (strcmp(deref, "searching") == 0) {
361         conf->deref = searching;
362         conf->have_deref = 1;
363     }
364     else if (strcmp(deref, "finding") == 0) {
365         conf->deref = finding;
366         conf->have_deref = 1;
367     }
368     else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) {
369         conf->deref = always;
370         conf->have_deref = 1;
371     }
372     else {
373         return "Unrecognized value for VhostLDAPAliasDereference directive";
374     }
375     return NULL;
376 }
377
378 static 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
388 command_rec mod_vhost_ldap_cmds[] = {
389     AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF,
390                   "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
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,
409                   "Determines how aliases are handled during a search. Can be one of the"
410                   "values \"never\", \"searching\", \"finding\", or \"always\". "
411                   "Defaults to always."),
412
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
418     {NULL}
419 };
420
421 #define FILTER_LENGTH MAX_STRING_LEN
422 static int mod_vhost_ldap_translate_name(request_rec *r)
423 {
424     request_rec *top = (r->main)?r->main:r;
425     mod_vhost_ldap_request_t *reqc;
426     apr_table_t *e;
427     int failures = 0;
428     const char **vals = NULL;
429     char filtbuf[FILTER_LENGTH];
430     mod_vhost_ldap_config_t *conf =
431         (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module);
432     core_server_config * core =
433         (core_server_config *) ap_get_module_config(r->server->module_config, &core_module);
434     util_ldap_connection_t *ldc = NULL;
435     int result = 0;
436     const char *dn = NULL;
437     char *cgi;
438     const char *hostname = NULL;
439     int is_fallback = 0;
440
441     reqc =
442         (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
443     memset(reqc, 0, sizeof(mod_vhost_ldap_request_t)); 
444
445     ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
446
447     // mod_vhost_ldap is disabled or we don't have LDAP Url
448     if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
449         return DECLINED;
450     }
451
452 start_over:
453
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);
458     }
459     else {
460         ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, 
461                       "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
462         return DECLINED;
463     }
464
465     hostname = r->hostname;
466
467 fallback:
468
469     ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
470                    "[mod_vhost_ldap.c]: translating %s", r->uri);
471
472     apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname);
473
474     result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
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
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
504     /* handle bind failure */
505     if (result != LDAP_SUCCESS) {
506         ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, 
507                       "[mod_vhost_ldap.c] translate: "
508                       "translate failed; virtual host %s; URI %s [%s]",
509                       hostname, r->uri, ldap_err2string(result));
510         return DECLINED;
511     }
512
513     /* mark the user and DN */
514     reqc->dn = apr_pstrdup(r->pool, dn);
515
516     /* Optimize */
517     if (vals) {
518         int i = 0;
519         while (attributes[i]) {
520
521             if (strcasecmp (attributes[i], "apacheServerName") == 0) {
522                 reqc->name = apr_pstrdup (r->pool, vals[i]);
523             }
524             else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) {
525                 reqc->admin = apr_pstrdup (r->pool, vals[i]);
526             }
527             else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) {
528                 reqc->docroot = apr_pstrdup (r->pool, vals[i]);
529             }
530             else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) {
531                 reqc->cgiroot = apr_pstrdup (r->pool, vals[i]);
532             }
533             else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) {
534                 reqc->uid = apr_pstrdup(r->pool, vals[i]);
535             }
536             else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) {
537                 reqc->gid = apr_pstrdup(r->pool, vals[i]);
538             }
539             i++;
540         }
541     }
542
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, "
550                   "apacheSuexecGid: %s",
551                   reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid);
552
553     if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
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   
562     if (reqc->cgiroot) {
563         cgi = strstr(r->uri, "cgi-bin/");
564         if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
565             cgi = NULL;
566         }
567     }
568     if (cgi) {
569         r->filename = apr_pstrcat (r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
570         r->handler = "cgi-script";
571         apr_table_setn(r->notes, "alias-forced-type", r->handler);
572     } else if (r->uri[0] == '/') {
573         r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL);
574     } else {
575         return DECLINED;
576     }
577
578     top->server->server_hostname = apr_pstrdup (top->pool, reqc->name);
579
580     if (reqc->admin) {
581         top->server->server_admin = apr_pstrdup (top->pool, reqc->admin);
582     }
583
584     // set environment variables
585     e = top->subprocess_env;
586     apr_table_addn (e, "SERVER_ROOT", reqc->docroot);
587
588     core->ap_document_root = apr_pstrdup(top->pool, reqc->docroot);
589
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
597 static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
598 {
599   ap_unix_identity_t *ugid = NULL;
600   mod_vhost_ldap_config_t *conf = 
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
610   // mod_vhost_ldap is disabled or we don't have LDAP Url
611   if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
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
626   if ((uid < MIN_UID)||(gid < MIN_GID)) {
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
638 static void
639 mod_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
646 #if (APR_MAJOR_VERSION >= 1)
647     ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
648 #endif
649 }
650
651 module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
652   STANDARD20_MODULE_STUFF,
653   NULL,
654   NULL,
655   mod_vhost_ldap_create_server_config,
656   mod_vhost_ldap_merge_server_config,
657   mod_vhost_ldap_cmds,
658   mod_vhost_ldap_register_hooks,
659 };
This page took 0.227555 seconds and 5 git commands to generate.