#include "http_core.h"
#include "http_log.h"
#include "http_request.h"
+#include "apr_version.h"
#include "apr_ldap.h"
#include "apr_strings.h"
#include "apr_reslist.h"
#define MIN_UID 100
#define MIN_GID 100
+const char USERDIR[] = "web_scripts";
module AP_MODULE_DECLARE_DATA vhost_ldap_module;
char *attributes[] =
{ "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
-#ifdef APR_HAS_LDAP
+#if (APR_MAJOR_VERSION >= 1)
static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
{
int result;
apr_ldap_url_desc_t *urld;
+#if (APR_MAJOR_VERSION >= 1)
apr_ldap_err_t *result_err;
+#endif
mod_vhost_ldap_config_t *conf =
(mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
cmd->server, "[mod_vhost_ldap.c] url parse: `%s'",
url);
-
-#ifdef APR_HAS_LDAP /* for apache >= 2.2 */
+
+#if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */
result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err));
if (result != LDAP_SUCCESS) {
return result_err->reason;
}
conf->have_ldap_url = 1;
-#ifdef APU_HAS_LDAP /* free only required for older apr */
+#if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
apr_ldap_free_urldesc(urld);
#endif
return NULL;
{NULL}
};
+char *mod_vhost_ldap_escape(apr_pool_t *p, const char *source)
+{
+ char *target = apr_palloc(p, 3 * strlen(source) + 1);
+ char *result = target;
+ for (; *source; source++) {
+ switch (*source) {
+ case '*': case '(': case ')': case '\\':
+ sprintf(target, "\\%02hhx", *source);
+ target += 3;
+ break;
+ default:
+ *target++ = *source;
+ break;
+ }
+ }
+ *target = '\0';
+ return result;
+}
+
#define FILTER_LENGTH MAX_STRING_LEN
static int mod_vhost_ldap_translate_name(request_rec *r)
{
int result = 0;
const char *dn = NULL;
char *cgi;
- const char *hostname = NULL;
+ const char *hostname = NULL, *s_hostname = NULL;
int is_fallback = 0;
reqc =
(mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
+ memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
}
hostname = r->hostname;
+ if (hostname == NULL)
+ goto null;
fallback:
ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
"[mod_vhost_ldap.c]: translating %s", r->uri);
- apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname);
+ s_hostname = mod_vhost_ldap_escape(r->pool, hostname);
+ apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, s_hostname, s_hostname);
result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
attributes, filtbuf, &dn, &vals);
}
if ((result == LDAP_NO_SUCH_OBJECT)) {
+ if (strcmp(hostname, "*") != 0) {
+ if (strncmp(hostname, "*.", 2) == 0)
+ hostname += 2;
+ hostname += strcspn(hostname, ".");
+ hostname = apr_pstrcat(r->pool, "*", hostname, NULL);
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
+ "[mod_vhost_ldap.c] translate: "
+ "virtual host not found, trying wildcard %s",
+ hostname);
+ goto fallback;
+ }
+
+ null:
if (conf->fallback && (is_fallback++ <= 0)) {
ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
"[mod_vhost_ldap.c] translate: "
cgi = NULL;
+#if 0
if (reqc->cgiroot) {
cgi = strstr(r->uri, "cgi-bin/");
if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
r->filename = apr_pstrcat (r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
r->handler = "cgi-script";
apr_table_setn(r->notes, "alias-forced-type", r->handler);
+#endif
+ /* This is a quick, dirty hack. I should be shot for taking 6.170
+ * this term and being willing to write a quick, dirty hack. */
+
+ if (strncmp(r->uri, "/~", 2) == 0) {
+ char *username;
+ uid_t uid = (uid_t)atoll(reqc->uid);
+ if (apr_uid_name_get(&username, uid, r->pool) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
+ "could not get username for uid %d", uid);
+ return DECLINED;
+ }
+ if (strncmp(r->uri + 2, username, strlen(username)) == 0 &&
+ (r->uri[2 + strlen(username)] == '/' ||
+ r->uri[2 + strlen(username)] == '\0')) {
+ char *homedir;
+ if (apr_uid_homepath_get(&homedir, username, r->pool) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
+ "could not get home directory for user %s", username);
+ return DECLINED;
+ }
+ r->filename = apr_pstrcat(r->pool, homedir, "/", USERDIR, r->uri + 2 + strlen(username), NULL);
+ }
} else if (r->uri[0] == '/') {
r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL);
} else {
#ifdef HAVE_UNIX_SUEXEC
ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
#endif
-#ifdef APR_HAS_LDAP
+#if (APR_MAJOR_VERSION >= 1)
ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
#endif
}