source: server/common/oursrc/httpdmods/mod_vhost_ldap.c @ 479

Last change on this file since 479 was 479, checked in by andersk, 15 years ago
Import mod_vhost_ldap 1.2.0.
  • Property svn:eol-style set to native
File size: 21.7 KB
Line 
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
53module AP_MODULE_DECLARE_DATA vhost_ldap_module;
54
55typedef enum {
56    MVL_UNSET, MVL_DISABLED, MVL_ENABLED
57} mod_vhost_ldap_status_e;
58
59typedef 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
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 */
89    char *cgiroot;                      /* ScriptAlias */
90    char *uid;                          /* Suexec Uid */
91    char *gid;                          /* Suexec Gid */
92} mod_vhost_ldap_request_t;
93
94char *attributes[] =
95  { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
96
97#if (APR_MAJOR_VERSION >= 1)
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
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
129    ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
130
131    return OK;
132}
133
134static void *
135mod_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
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));
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 */
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;
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
319static 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
330static 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
340static 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
350static 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
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
388command_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
422static 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
452start_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
467fallback:
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
597static 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
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
646#if (APR_MAJOR_VERSION >= 1)
647    ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
648#endif
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,
656  mod_vhost_ldap_merge_server_config,
657  mod_vhost_ldap_cmds,
658  mod_vhost_ldap_register_hooks,
659};
Note: See TracBrowser for help on using the repository browser.