Beispiel #1
0
static int select_random(apr_pool_t* pool, apr_dbd_t* handle,
                         const apr_dbd_driver_t* driver)
{
    int rv = 0;
    int n;
    const char* entry;
    const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2";
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    rv = apr_dbd_select(driver,pool,handle,&res,statement,1);
    if (rv) {
        printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
        return rv;
    }
    rv = apr_dbd_get_row(driver, pool, res, &row, 5) ;
    if (rv) {
        printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
        return rv;
    }
    printf("ROW 5:	");
    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);
    rv = apr_dbd_get_row(driver, pool, res, &row, 1) ;
    if (rv) {
        printf("get_row failed: %s", apr_dbd_error(driver, handle, rv));
        return rv;
    }
    printf("ROW 1:	");
    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);
    rv = apr_dbd_get_row(driver, pool, res, &row, 11) ;
    if (rv != -1) {
        printf("Oops!  get_row out of range but thinks it succeeded!\n%s\n",
                apr_dbd_error(driver, handle, rv));
        return -1;
    }
    rv = 0;

    return rv;
}
Beispiel #2
0
/*
   =============================================================================
     resultset(N): Fetches one or more rows from a result set.
   =============================================================================
 */
int lua_db_get_row(lua_State *L) 
{
    int row_no,x;
    const char      *entry;
    apr_dbd_row_t   *row = 0;
    lua_db_result_set *res = lua_get_result_set(L);
    
    row_no = luaL_optinteger(L, 2, 0);
    lua_settop(L,0);
    
    /* Fetch all rows at once? */
    if (row_no == 0) {
        row_no = 1;
        lua_newtable(L);
        while (apr_dbd_get_row(res->driver, res->pool, res->results,
                            &row, -1) != -1)
         {
            lua_pushinteger(L, row_no);
            lua_newtable(L);
            for (x = 0; x < res->cols; x++) {
                entry = apr_dbd_get_entry(res->driver, row, x);
                if (entry) {
                    lua_pushinteger(L, x + 1);
                    lua_pushstring(L, entry);
                    lua_rawset(L, -3);
                }
            }
            lua_rawset(L, -3);
            row_no++;
        }
        return 1;
    }
    
    /* Just fetch a single row */
    if (apr_dbd_get_row(res->driver, res->pool, res->results,
                            &row, row_no) != -1)
         {
        
        lua_newtable(L);
        for (x = 0; x < res->cols; x++) {
            entry = apr_dbd_get_entry(res->driver, row, x);
            if (entry) {
                lua_pushinteger(L, x + 1);
                lua_pushstring(L, entry);
                lua_rawset(L, -3);
            }
        }
        return 1;
    }
    return 0;
}
Beispiel #3
0
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;
}
Beispiel #4
0
static int select_sequential(apr_pool_t* pool, apr_dbd_t* handle,
                             const apr_dbd_driver_t* driver)
{
    int rv = 0;
    int i = 0;
    int n;
    const char* entry;
    const char* statement = "SELECT * FROM apr_dbd_test ORDER BY col1, col2";
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    rv = apr_dbd_select(driver,pool,handle,&res,statement,0);
    if (rv) {
        printf("Select failed: %s", apr_dbd_error(driver, handle, rv));
        return rv;
    }
    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;
}
Beispiel #5
0
std::vector<MetadataStorage::UntypedTuple> MetadataStorage::select_query(const char* query) const {
    std::vector<UntypedTuple> tuples;
    apr_dbd_results_t *results = nullptr;
    int status = apr_dbd_select(driver_, pool_.get(), handle_.get(), &results, query, 0);
    if (status != 0) {
        (*logger_)(AKU_LOG_ERROR, "Error executing query");
        throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status));
    }
    // get rows
    int ntuples = apr_dbd_num_tuples(driver_, results);
    int ncolumns = apr_dbd_num_cols(driver_, results);
    for (int i = ntuples; i --> 0;) {
        apr_dbd_row_t *row = nullptr;
        status = apr_dbd_get_row(driver_, pool_.get(), results, &row, -1);
        if (status != 0) {
            (*logger_)(AKU_LOG_ERROR, "Error getting row from resultset");
            throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status));
        }
        UntypedTuple tup;
        for (int col = 0; col < ncolumns; col++) {
            const char* entry = apr_dbd_get_entry(driver_, row, col);
            if (entry) {
                tup.emplace_back(entry);
            } else {
                tup.emplace_back();
            }
        }
        tuples.push_back(std::move(tup));
    }
    return tuples;
}
Beispiel #6
0
/**
 * Load the session by the key specified.
 */
static apr_status_t dbd_load(request_rec * r, const char *key, const char **val)
{

    apr_status_t rv;
    ap_dbd_t *dbd = NULL;
    apr_dbd_prepared_t *statement = NULL;
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    apr_int64_t expiry = (apr_int64_t) apr_time_now();

    session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_dbd_module);

    if (conf->selectlabel == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01853)
                      "no SessionDBDselectlabel has been specified");
        return APR_EGENERAL;
    }

    rv = dbd_init(r, conf->selectlabel, &dbd, &statement);
    if (rv) {
        return rv;
    }
    rv = apr_dbd_pvbselect(dbd->driver, r->pool, dbd->handle, &res, statement,
                          0, key, &expiry, NULL);
    if (rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01854)
                      "query execution error saving session '%s' "
                      "in database using query '%s': %s", key, conf->selectlabel,
                      apr_dbd_error(dbd->driver, dbd->handle, rv));
        return APR_EGENERAL;
    }
    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(01855)
                          "error retrieving results while saving '%s' "
                          "in database using query '%s': %s", key, conf->selectlabel,
                           apr_dbd_error(dbd->driver, dbd->handle, rv));
            return APR_EGENERAL;
        }
        if (*val == NULL) {
            *val = apr_dbd_get_entry(dbd->driver, row, 0);
        }
        /* we can't break out here or row won't get cleaned up */
    }

    return APR_SUCCESS;

}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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 int authz_dbd_query(request_rec *r, authz_dbd_cfg *cfg,
			   const apr_array_header_t *query_parameters,
			   apr_array_header_t *query_result_rows)
{
    /* SELECT group FROM authz WHERE col = %s, col = %s, ... */
    int rv;
    const char *message;
    ap_dbd_t *dbd = dbd_handle(r);
    apr_dbd_prepared_t *query;
    apr_dbd_results_t *res = NULL;
    apr_dbd_row_t *row = NULL;
    const char **query_result_row;

    if (cfg->query == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "No query configured for dbd-query!");
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    if (dbd == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
                      "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()
                      "Error retrieving query for dbd-query!");
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    rv = apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res,
			 query, 0, 
			 query_parameters->nelts,
			 (const char **)query_parameters->elts);

    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) {
                query_result_row = apr_array_push(query_result_rows);
                *query_result_row = 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()
                              "authz_dbd dbd_query in get_row; 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()
                      "authz_dbd, in dbd_query query for %s [%s]",
                      r->user, message?message:noerror);
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    return OK;
}
Beispiel #11
0
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;
}