static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg, apr_array_header_t *groups) { /* SELECT group FROM authz WHERE user = %s */ int rv; const char *message; ap_dbd_t *dbd; apr_dbd_prepared_t *query; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; if (cfg->query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01649) "No query configured for dbd-group!"); return HTTP_INTERNAL_SERVER_ERROR; } dbd = dbd_handle(r); if (dbd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02903) "No db handle available for dbd-query! " "Check your database access"); return HTTP_INTERNAL_SERVER_ERROR; } query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); if (query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650) "Error retrieving query for dbd-group!"); return HTTP_INTERNAL_SERVER_ERROR; } rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, query, 0, r->user, NULL); if (rv == 0) { for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv == 0) { APR_ARRAY_PUSH(groups, const char *) = apr_pstrdup(r->pool, apr_dbd_get_entry(dbd->driver, row, 0)); } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01651) "authz_dbd in get_row; group query for user=%s [%s]", r->user, message?message:noerror); return HTTP_INTERNAL_SERVER_ERROR; } } } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01652) "authz_dbd, in groups query for %s [%s]", r->user, message?message:noerror); return HTTP_INTERNAL_SERVER_ERROR; } return OK; }
static int test_pselect(apr_pool_t* pool, apr_dbd_t* handle, const apr_dbd_driver_t* driver) { int rv = 0; int i, n; const char *query = "SELECT * FROM apr_dbd_test WHERE col3 <= %s or col1 = 'bar'" ; const char *label = "lowvalues"; apr_dbd_prepared_t *statement = NULL; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; const char *entry = NULL; rv = apr_dbd_prepare(driver, pool, handle, query, label, &statement); if (rv) { printf("Prepare statement failed!\n%s\n", apr_dbd_error(driver, handle, rv)); return rv; } rv = apr_dbd_pvselect(driver, pool, handle, &res, statement, 0, "3", NULL); if (rv) { printf("Exec of prepared statement failed!\n%s\n", apr_dbd_error(driver, handle, rv)); return rv; } i = 0; printf("Selecting rows where col3 <= 3 and bar row where it's unset.\nShould show four rows.\n"); for (rv = apr_dbd_get_row(driver, pool, res, &row, -1); rv == 0; rv = apr_dbd_get_row(driver, pool, res, &row, -1)) { printf("ROW %d: ", ++i) ; for (n = 0; n < apr_dbd_num_cols(driver, res); ++n) { entry = apr_dbd_get_entry(driver, row, n); if (entry == NULL) { printf("(null) ") ; } else { printf("%s ", entry); } } fputs("\n", stdout); } return (rv == -1) ? 0 : 1; }
static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, const char *action) { int rv; const char *newuri = NULL; int nrows; const char *message; ap_dbd_t *dbd; apr_dbd_prepared_t *query; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; if (cfg->query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642) "No query configured for %s!", action); return HTTP_INTERNAL_SERVER_ERROR; } dbd = dbd_handle(r); if (dbd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02902) "No db handle available for %s! " "Check your database access", action); return HTTP_INTERNAL_SERVER_ERROR; } query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); if (query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643) "Error retrieving Query for %s!", action); return HTTP_INTERNAL_SERVER_ERROR; } rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows, query, r->user, NULL); if (rv == 0) { if (nrows != 1) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644) "authz_dbd: %s of user %s updated %d rows", action, r->user, nrows); } } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01645) "authz_dbd: query for %s failed; user %s [%s]", action, r->user, message?message:noerror); return HTTP_INTERNAL_SERVER_ERROR; } if (cfg->redirect == 1) { newuri = apr_table_get(r->headers_in, "Referer"); } if (!newuri && cfg->redir_query) { query = apr_hash_get(dbd->prepared, cfg->redir_query, APR_HASH_KEY_STRING); if (query == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01646) "authz_dbd: no redirect query!"); /* OK, this is non-critical; we can just not-redirect */ } else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, query, 0, r->user, NULL)) == 0) { for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv != 0) { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01647) "authz_dbd in get_row; action=%s user=%s [%s]", action, r->user, message?message:noerror); } else if (newuri == NULL) { newuri = apr_pstrdup(r->pool, apr_dbd_get_entry(dbd->driver, row, 0)); } /* we can't break out here or row won't get cleaned up */ } } else { message = apr_dbd_error(dbd->driver, dbd->handle, rv); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01648) "authz_dbd/redirect for %s of %s [%s]", action, r->user, message?message:noerror); } } if (newuri != NULL) { r->status = HTTP_MOVED_TEMPORARILY; apr_table_set(r->err_headers_out, "Location", newuri); } authz_dbd_run_client_login(r, OK, action); return OK; }
static authn_status authn_dbd_password(request_rec *r, const char *user, const char *password) { apr_status_t rv; const char *dbd_password = NULL; apr_dbd_prepared_t *statement; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config, &authn_dbd_module); ap_dbd_t *dbd = authn_dbd_acquire_fn(r); char *digest_colon = NULL; if (dbd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Failed to acquire database connection to look up " "user '%s'", user); return AUTH_GENERAL_ERROR; } if (conf->user == 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); if (statement == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "A prepared statement could not be found for " "AuthDBDUserPWQuery with the key '%s'", conf->user); return AUTH_GENERAL_ERROR; } if (apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement, 0, user, NULL) != 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Query execution error looking up '%s' " "in database", user); return AUTH_GENERAL_ERROR; } for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv != 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "Error retrieving results while looking up '%s' " "in database", user); return AUTH_GENERAL_ERROR; } if (dbd_password == NULL) { #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) /* add the rest of the columns to the environment */ int i = 1; const char *name; for (name = apr_dbd_get_name(dbd->driver, res, i); name != NULL; name = apr_dbd_get_name(dbd->driver, res, i)) { char *str = apr_pstrcat(r->pool, AUTHN_PREFIX, name, NULL); int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */ while (str[j]) { if (!apr_isalnum(str[j])) { str[j] = '_'; } else { str[j] = apr_toupper(str[j]); } j++; } apr_table_set(r->subprocess_env, str, apr_dbd_get_entry(dbd->driver, row, i)); i++; } #endif dbd_password = apr_dbd_get_entry(dbd->driver, row, 0); } /* we can't break out here or row won't get cleaned up */ } if (!dbd_password) { return AUTH_USER_NOT_FOUND; } if ((digest_colon = ap_strchr(dbd_password, ':'))) { const char *realm = NULL, *exp_hash = NULL; const char *act_hash = NULL; realm = apr_pstrndup(r->pool, dbd_password, digest_colon - dbd_password); exp_hash = digest_colon + 1; act_hash = ap_md5(r->pool, (unsigned char*) apr_pstrcat(r->pool, user, ":", realm, ":", password, NULL)); if (strcmp(act_hash, exp_hash)) { return AUTH_DENIED; } else { return AUTH_GRANTED; } } rv = apr_password_validate(password, dbd_password); if (rv != APR_SUCCESS) { return AUTH_DENIED; } return AUTH_GRANTED; }
static authn_status authn_dbd_realm(request_rec *r, const char *user, const char *realm, char **rethash) { apr_status_t rv; const char *dbd_hash = NULL; apr_dbd_prepared_t *statement; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; int ret; authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config, &authn_dbd_module); ap_dbd_t *dbd = authn_dbd_acquire_fn(r); if (dbd == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01658) "Failed to acquire database connection to look up " "user '%s:%s'", user, realm); return AUTH_GENERAL_ERROR; } if (conf->realm == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01659) "No AuthDBDUserRealmQuery has been specified"); return AUTH_GENERAL_ERROR; } statement = apr_hash_get(dbd->prepared, conf->realm, APR_HASH_KEY_STRING); if (statement == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01660) "A prepared statement could not be found for " "AuthDBDUserRealmQuery with the key '%s'", conf->realm); return AUTH_GENERAL_ERROR; } if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res, statement, 0, user, realm, NULL) != 0)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01661) "Query execution error looking up '%s:%s' " "in database [%s]", user, realm, apr_dbd_error(dbd->driver, dbd->handle, ret)); return AUTH_GENERAL_ERROR; } for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); rv != -1; rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { if (rv != 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01662) "Error retrieving results while looking up '%s:%s' " "in database", user, realm); return AUTH_GENERAL_ERROR; } if (dbd_hash == NULL) { #if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3) /* add the rest of the columns to the environment */ int i = 1; const char *name; for (name = apr_dbd_get_name(dbd->driver, res, i); name != NULL; name = apr_dbd_get_name(dbd->driver, res, i)) { char *str = apr_pstrcat(r->pool, AUTHN_PREFIX, name, NULL); int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */ while (str[j]) { if (!apr_isalnum(str[j])) { str[j] = '_'; } else { str[j] = apr_toupper(str[j]); } j++; } apr_table_set(r->subprocess_env, str, apr_dbd_get_entry(dbd->driver, row, i)); i++; } #endif dbd_hash = apr_dbd_get_entry(dbd->driver, row, 0); } /* we can't break out here or row won't get cleaned up */ } if (!dbd_hash) { return AUTH_USER_NOT_FOUND; } AUTHN_CACHE_STORE(r, user, realm, dbd_hash); *rethash = apr_pstrdup(r->pool, dbd_hash); return AUTH_USER_FOUND; }