Index: modules/aaa/mod_authn_dbd.c =================================================================== --- modules/aaa/mod_authn_dbd.c (revision 628393) +++ modules/aaa/mod_authn_dbd.c (working copy) @@ -29,13 +29,10 @@ module AP_MODULE_DECLARE_DATA authn_dbd_module; typedef struct { - const char *user; + const char *label; const char *realm; + int validate; } authn_dbd_conf; -typedef struct { - const char *label; - const char *query; -} authn_dbd_rec; /* optional function - look it up once in post_config */ static ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL; @@ -51,14 +48,15 @@ authn_dbd_conf *add = ADD; authn_dbd_conf *base = BASE; authn_dbd_conf *ret = apr_palloc(pool, sizeof(authn_dbd_conf)); - ret->user = (add->user == NULL) ? base->user : add->user; - ret->realm = (add->realm == NULL) ? base->realm : add->realm; + ret->label = (add->label == NULL) ? base->label : add->label; + ret->validate = (add->label == NULL) ? base->validate : add->validate; + ret->realm = (add->realm == NULL) ? base->realm : add->realm; return ret; } -static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query) +static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query, char *validate) { static unsigned int label_num = 0; - char *label; + authn_dbd_conf *conf = (authn_dbd_conf *)cfg; if (authn_dbd_prepare_fn == NULL) { authn_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare); @@ -67,17 +65,19 @@ } authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire); } - label = apr_psprintf(cmd->pool, "authn_dbd_%d", ++label_num); - - authn_dbd_prepare_fn(cmd->server, query, label); + if (validate && apr_strnatcasecmp(validate, "VALIDATE")) + return apr_pstrcat(cmd->pool, "unrecognized AuthDBDUserPWQuery option: ", validate, NULL); + conf->validate = (validate != NULL); /* save the label here for our own use */ - return ap_set_string_slot(cmd, cfg, label); + conf->label = apr_psprintf(cmd->pool, "authn_dbd_%d", ++label_num); + authn_dbd_prepare_fn(cmd->server, query, conf->label); + return NULL; } static const command_rec authn_dbd_cmds[] = { - AP_INIT_TAKE1("AuthDBDUserPWQuery", authn_dbd_prepare, - (void *)APR_OFFSETOF(authn_dbd_conf, user), ACCESS_CONF, + AP_INIT_TAKE12("AuthDBDUserPWQuery", authn_dbd_prepare, + NULL, ACCESS_CONF, "Query used to fetch password for user"), AP_INIT_TAKE1("AuthDBDUserRealmQuery", authn_dbd_prepare, (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF, @@ -92,6 +92,8 @@ apr_dbd_prepared_t *statement; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; + char const *args[2]; + int nargs; authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config, &authn_dbd_module); @@ -102,18 +104,28 @@ return AUTH_GENERAL_ERROR; } - if (conf->user == NULL) { + if (conf->label == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "No AuthDBDUserPWQuery has been specified."); return AUTH_GENERAL_ERROR; } - statement = apr_hash_get(dbd->prepared, conf->user, APR_HASH_KEY_STRING); + statement = apr_hash_get(dbd->prepared, conf->label, APR_HASH_KEY_STRING); if (statement == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "A prepared statement could not be found for AuthDBDUserPWQuery, key '%s'.", conf->user); + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "A prepared statement could not be found for AuthDBDUserPWQuery, key '%s'.", conf->label); return AUTH_GENERAL_ERROR; } - if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement, - 0, user, NULL) != 0) { + + if (conf->validate) { + args[0] = password; + args[1] = user; + nargs = 2; + } + else { + args[0] = user; + nargs = 1; + } + if (apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res, statement, + 0, nargs, args) != 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Error looking up %s in database", user); return AUTH_GENERAL_ERROR; @@ -161,6 +173,12 @@ if (!dbd_password) { return AUTH_USER_NOT_FOUND; } + if (conf->validate) + /* any non-zero number or "T" or "TRUE" (case-insensitive) for OK */ + return ( *dbd_password == 't' || *dbd_password == 'T' + || atoi(dbd_password) + || !apr_strnatcasecmp(dbd_password, "TRUE") + ) ? AUTH_GRANTED : AUTH_DENIED; rv = apr_password_validate(password, dbd_password);