/* yet more plagiarizing...this one raided from mod_auth's _auth_resolve_user() * function [in case you haven't noticed yet, I'm quite the hack, in the * _true_ sense of the world]. =) hmmm...I wonder if it'd be feasible * to make some of mod_auth's functions visible from src/auth.c? */ static config_rec *wrap_resolve_user(pool *pool, char **user) { config_rec *conf = NULL, *top_conf; char *ourname = NULL, *anonname = NULL; unsigned char is_alias = FALSE, force_anon = FALSE; /* Precendence rules: * 1. Search for UserAlias directive. * 2. Search for Anonymous directive. * 3. Normal user login */ ourname = (char*) get_param_ptr(main_server->conf, "UserName", FALSE); conf = find_config(main_server->conf, CONF_PARAM, "UserAlias", TRUE); if (conf) do { if (!strcmp(conf->argv[0], "*") || !strcmp(conf->argv[0], *user)) { is_alias = TRUE; break; } } while ((conf = find_config_next(conf, conf->next, CONF_PARAM, "UserAlias", TRUE)) != NULL); /* if AuthAliasOnly is set, ignore this one and continue */ top_conf = conf; while (conf && conf->parent && find_config(conf->parent->set, CONF_PARAM, "AuthAliasOnly", FALSE)) { is_alias = FALSE; find_config_set_top(top_conf); conf = find_config_next(conf, conf->next, CONF_PARAM, "UserAlias", TRUE); if (conf && (!strcmp(conf->argv[0], "*") || !strcmp(conf->argv[0], *user))) is_alias = TRUE; } if (conf) { *user = conf->argv[1]; /* If the alias is applied inside an <Anonymous> context, we have found * our anon block */ if (conf->parent && conf->parent->config_type == CONF_ANON) conf = conf->parent; else conf = NULL; } /* Next, search for an anonymous entry */ if (!conf) conf = find_config(main_server->conf, CONF_ANON, NULL, FALSE); else find_config_set_top(conf); if (conf) do { anonname = (char*) get_param_ptr(conf->subset, "UserName", FALSE); if (!anonname) anonname = ourname; if (anonname && !strcmp(anonname, *user)) { break; } } while ((conf = find_config_next(conf, conf->next, CONF_ANON, NULL, FALSE)) != NULL); if (!is_alias && !force_anon) { if (find_config((conf ? conf->subset : main_server->conf), CONF_PARAM, "AuthAliasOnly", FALSE)) { if (conf && conf->config_type == CONF_ANON) conf = NULL; else *user = NULL; if (*user && find_config(main_server->conf, CONF_PARAM, "AuthAliasOnly", FALSE)) *user = NULL; } } return conf; }
/* This is one messy function. Yuck. Yay legacy code. */ config_rec *pr_auth_get_anon_config(pool *p, char **login_name, char **user_name, char **anon_name) { config_rec *c = NULL, *topc = NULL, *anon_c = NULL; char *config_user_name, *config_anon_name = NULL; unsigned char is_alias = FALSE, *auth_alias_only = NULL; /* Precendence rules: * 1. Search for UserAlias directive. * 2. Search for Anonymous directive. * 3. Normal user login */ config_user_name = get_param_ptr(main_server->conf, "UserName", FALSE); if (config_user_name && user_name) { *user_name = config_user_name; } /* If the main_server->conf->set list is large (e.g. there are many * config_recs in the list, as can happen if MANY <Directory> sections are * configured), the login can timeout because this find_config() call takes * a long time. The reason this issue strikes HERE first in the login * process is that this appears to the first find_config() call which has * a TRUE recurse flag. * * The find_config() call below is looking for a UserAlias directive * anywhere in the configuration, no matter how deeply buried in nested * config contexts it might be. */ c = find_config(main_server->conf, CONF_PARAM, "UserAlias", TRUE); if (c) { do { pr_signals_handle(); if (strncmp(c->argv[0], "*", 2) == 0 || strcmp(c->argv[0], *login_name) == 0) { is_alias = TRUE; break; } } while ((c = find_config_next(c, c->next, CONF_PARAM, "UserAlias", TRUE)) != NULL); } /* This is where things get messy, rapidly. */ topc = c; while (c && c->parent && (auth_alias_only = get_param_ptr(c->parent->set, "AuthAliasOnly", FALSE))) { /* while() loops should always handle signals. */ pr_signals_handle(); if (auth_alias_only) { /* If AuthAliasOnly is on, ignore this one and continue. */ if (*auth_alias_only == TRUE) { c = find_config_next(c, c->next, CONF_PARAM, "UserAlias", TRUE); continue; } } /* At this point, we have found an "AuthAliasOnly off" config in * c->parent->set. See if there's a UserAlias in the same config set. */ is_alias = FALSE; find_config_set_top(topc); c = find_config_next(c, c->next, CONF_PARAM, "UserAlias", TRUE); if (c && (strncmp(c->argv[0], "*", 2) == 0 || strcmp(c->argv[0], *login_name) == 0)) { is_alias = TRUE; } } if (c) { *login_name = c->argv[1]; /* If the alias is applied inside an <Anonymous> context, we have found * our anon block. */ if (c->parent && c->parent->config_type == CONF_ANON) { c = c->parent; } else { c = NULL; } } /* Next, search for an anonymous entry. */ if (c == NULL) { c = find_config(main_server->conf, CONF_ANON, NULL, FALSE); } else { find_config_set_top(c); anon_c = c; } if (c) { do { pr_signals_handle(); config_anon_name = get_param_ptr(c->subset, "UserName", FALSE); if (!config_anon_name) config_anon_name = config_user_name; if (config_anon_name && strcmp(config_anon_name, *login_name) == 0) { if (anon_name) *anon_name = config_anon_name; break; } } while ((c = find_config_next(c, c->next, CONF_ANON, NULL, FALSE)) != NULL); } if (!is_alias) { /* Yes, we do want to be using c, not anon_c, here. Otherwise, we * risk a regression of Bug#3501. */ auth_alias_only = get_param_ptr(c ? c->subset : main_server->conf, "AuthAliasOnly", FALSE); if (auth_alias_only && *auth_alias_only == TRUE) { if (c && c->config_type == CONF_ANON) { c = NULL; } else { *login_name = NULL; } auth_alias_only = get_param_ptr(main_server->conf, "AuthAliasOnly", FALSE); if (*login_name && auth_alias_only && *auth_alias_only == TRUE) *login_name = NULL; if ((!login_name || !c) && anon_name) { *anon_name = NULL; } } } return c; }