mod_authz_dbd.c revision f6098228fada9d4d6dcdc0cd321f4f5904040d1e
97a9a944b5887e91042b019776c41d5dd74557aferikabele/* Licensed to the Apache Software Foundation (ASF) under one or more
97a9a944b5887e91042b019776c41d5dd74557aferikabele * contributor license agreements. See the NOTICE file distributed with
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * this work for additional information regarding copyright ownership.
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * The ASF licenses this file to You under the Apache License, Version 2.0
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * (the "License"); you may not use this file except in compliance with
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * the License. You may obtain a copy of the License at
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive *
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * http://www.apache.org/licenses/LICENSE-2.0
b686b6a420bde7f78c416b90be11db94cb789979nd *
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * Unless required by applicable law or agreed to in writing, software
b686b6a420bde7f78c416b90be11db94cb789979nd * distributed under the License is distributed on an "AS IS" BASIS,
b686b6a420bde7f78c416b90be11db94cb789979nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
2e545ce2450a9953665f701bb05350f0d3f26275nd * limitations under the License.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
b686b6a420bde7f78c416b90be11db94cb789979nd#include "httpd.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "http_log.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "http_config.h"
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen#include "ap_provider.h"
3f08db06526d6901aa08c110b5bc7dde6bc39905nd#include "http_request.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "http_protocol.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "http_core.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "apr_dbd.h"
3f08db06526d6901aa08c110b5bc7dde6bc39905nd#include "mod_dbd.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "apr_strings.h"
b686b6a420bde7f78c416b90be11db94cb789979nd#include "mod_authz_dbd.h"
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "mod_auth.h"
07dc96d063d49299da433f84b5c5681da9bbdf68rbowen
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung
3b3b7fc78d1f5bfc2769903375050048ff41ff26ndmodule AP_MODULE_DECLARE_DATA authz_dbd_module;
b686b6a420bde7f78c416b90be11db94cb789979nd
b686b6a420bde7f78c416b90be11db94cb789979nd/* Export a hook for modules that manage clientside sessions
b686b6a420bde7f78c416b90be11db94cb789979nd * (e.g. mod_auth_cookie)
b686b6a420bde7f78c416b90be11db94cb789979nd * to deal with those when we successfully login/logout at the server
b686b6a420bde7f78c416b90be11db94cb789979nd *
b686b6a420bde7f78c416b90be11db94cb789979nd * XXX: WHY would this be specific to dbd_authz? Why wouldn't we track
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * this across all authz user providers in a lower level mod, such as
b0f39810a93af064583df3741ae61d5351934b62nd * mod_auth_basic/digest?
b0f39810a93af064583df3741ae61d5351934b62nd */
b0f39810a93af064583df3741ae61d5351934b62ndAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(authz_dbd, AUTHZ_DBD, int, client_login,
b0f39810a93af064583df3741ae61d5351934b62nd (request_rec *r, int code, const char *action),
b0f39810a93af064583df3741ae61d5351934b62nd (r, code, action), OK, DECLINED)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslivetypedef struct {
b0f39810a93af064583df3741ae61d5351934b62nd const char *query;
b0f39810a93af064583df3741ae61d5351934b62nd const char *redir_query;
b0f39810a93af064583df3741ae61d5351934b62nd int redirect;
b0f39810a93af064583df3741ae61d5351934b62nd} authz_dbd_cfg ;
b0f39810a93af064583df3741ae61d5351934b62nd
b0f39810a93af064583df3741ae61d5351934b62ndstatic ap_dbd_t *(*dbd_handle)(request_rec*) = NULL;
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic const char *const noerror = "???";
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic void *authz_dbd_cr_cfg(apr_pool_t *pool, char *dummy)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive{
06ba4a61654b3763ad65f52283832ebf058fdf1cslive authz_dbd_cfg *ret = apr_pcalloc(pool, sizeof(authz_dbd_cfg));
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ret->redirect = -1;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive return ret;
b0f39810a93af064583df3741ae61d5351934b62nd}
b686b6a420bde7f78c416b90be11db94cb789979ndstatic void *authz_dbd_merge_cfg(apr_pool_t *pool, void *BASE, void *ADD)
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri{
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri authz_dbd_cfg *base = BASE;
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri authz_dbd_cfg *add = ADD;
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri authz_dbd_cfg *ret = apr_palloc(pool, sizeof(authz_dbd_cfg));
b686b6a420bde7f78c416b90be11db94cb789979nd
b686b6a420bde7f78c416b90be11db94cb789979nd ret->query = (add->query == NULL) ? base->query : add->query;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd ret->redir_query = (add->redir_query == NULL)
b686b6a420bde7f78c416b90be11db94cb789979nd ? base->redir_query : add->redir_query;
c44eeebd065e2c8cd028016b45c58afb480aaf8fdruggeri ret->redirect = (add->redirect == -1) ? base->redirect : add->redirect;
b686b6a420bde7f78c416b90be11db94cb789979nd return ret;
b686b6a420bde7f78c416b90be11db94cb789979nd}
b686b6a420bde7f78c416b90be11db94cb789979ndstatic const char *authz_dbd_prepare(cmd_parms *cmd, void *cfg,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive const char *query)
97a9a944b5887e91042b019776c41d5dd74557aferikabele{
b0f39810a93af064583df3741ae61d5351934b62nd static unsigned int label_num = 0;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive char *label;
0cf3cdbaa1dad11cbf1ce32e48f1b4ec88cf779fnilgun const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (err)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive return err;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (dbd_prepare == NULL) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive dbd_prepare = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (dbd_prepare == NULL) {
b0f39810a93af064583df3741ae61d5351934b62nd return "You must load mod_dbd to enable AuthzDBD functions";
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd dbd_handle = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd label = apr_psprintf(cmd->pool, "authz_dbd_%d", ++label_num);
b0f39810a93af064583df3741ae61d5351934b62nd
f6066dc0a6ad0432b74774e290c04c3cc4aa2dafrbowen dbd_prepare(cmd->server, query, label);
b0f39810a93af064583df3741ae61d5351934b62nd
b0f39810a93af064583df3741ae61d5351934b62nd /* save the label here for our own use */
b0f39810a93af064583df3741ae61d5351934b62nd return ap_set_string_slot(cmd, cfg, label);
b0f39810a93af064583df3741ae61d5351934b62nd}
b0f39810a93af064583df3741ae61d5351934b62ndstatic const command_rec authz_dbd_cmds[] = {
b0f39810a93af064583df3741ae61d5351934b62nd AP_INIT_FLAG("AuthzDBDLoginToReferer", ap_set_flag_slot,
b0f39810a93af064583df3741ae61d5351934b62nd (void*)APR_OFFSETOF(authz_dbd_cfg, redirect), ACCESS_CONF,
b0f39810a93af064583df3741ae61d5351934b62nd "Whether to redirect to referer on successful login"),
b0f39810a93af064583df3741ae61d5351934b62nd AP_INIT_TAKE1("AuthzDBDQuery", authz_dbd_prepare,
b0f39810a93af064583df3741ae61d5351934b62nd (void*)APR_OFFSETOF(authz_dbd_cfg, query), ACCESS_CONF,
b0f39810a93af064583df3741ae61d5351934b62nd "SQL query for DBD Authz or login"),
b0f39810a93af064583df3741ae61d5351934b62nd AP_INIT_TAKE1("AuthzDBDRedirectQuery", authz_dbd_prepare,
b0f39810a93af064583df3741ae61d5351934b62nd (void*)APR_OFFSETOF(authz_dbd_cfg, redir_query), ACCESS_CONF,
b0f39810a93af064583df3741ae61d5351934b62nd "SQL query to get per-user redirect URL after login"),
b0f39810a93af064583df3741ae61d5351934b62nd {NULL}
b0f39810a93af064583df3741ae61d5351934b62nd};
b0f39810a93af064583df3741ae61d5351934b62nd
b0f39810a93af064583df3741ae61d5351934b62ndstatic int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg,
b0f39810a93af064583df3741ae61d5351934b62nd const char *action)
b0f39810a93af064583df3741ae61d5351934b62nd{
b0f39810a93af064583df3741ae61d5351934b62nd int rv;
b0f39810a93af064583df3741ae61d5351934b62nd const char *newuri = NULL;
b0f39810a93af064583df3741ae61d5351934b62nd int nrows;
b0f39810a93af064583df3741ae61d5351934b62nd const char *message;
b0f39810a93af064583df3741ae61d5351934b62nd ap_dbd_t *dbd = dbd_handle(r);
b0f39810a93af064583df3741ae61d5351934b62nd apr_dbd_prepared_t *query;
b0f39810a93af064583df3741ae61d5351934b62nd apr_dbd_results_t *res = NULL;
b0f39810a93af064583df3741ae61d5351934b62nd apr_dbd_row_t *row = NULL;
b0f39810a93af064583df3741ae61d5351934b62nd
b0f39810a93af064583df3741ae61d5351934b62nd if (cfg->query == NULL) {
b0f39810a93af064583df3741ae61d5351934b62nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642)
b0f39810a93af064583df3741ae61d5351934b62nd "No query configured for %s!", action);
b0f39810a93af064583df3741ae61d5351934b62nd return HTTP_INTERNAL_SERVER_ERROR;
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
b0f39810a93af064583df3741ae61d5351934b62nd if (query == NULL) {
b0f39810a93af064583df3741ae61d5351934b62nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643)
b0f39810a93af064583df3741ae61d5351934b62nd "Error retrieving Query for %s!", action);
b0f39810a93af064583df3741ae61d5351934b62nd return HTTP_INTERNAL_SERVER_ERROR;
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd
b0f39810a93af064583df3741ae61d5351934b62nd rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows,
b0f39810a93af064583df3741ae61d5351934b62nd query, r->user, NULL);
4db087c26379b76fb2cce36137cbdc112824777and if (rv == 0) {
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf if (nrows != 1) {
b0f39810a93af064583df3741ae61d5351934b62nd ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644)
b0f39810a93af064583df3741ae61d5351934b62nd "authz_dbd: %s of user %s updated %d rows",
b0f39810a93af064583df3741ae61d5351934b62nd action, r->user, nrows);
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd }
b0f39810a93af064583df3741ae61d5351934b62nd else {
b0f39810a93af064583df3741ae61d5351934b62nd message = apr_dbd_error(dbd->driver, dbd->handle, rv);
b0f39810a93af064583df3741ae61d5351934b62nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01645)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "authz_dbd: query for %s failed; user %s [%s]",
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar action, r->user, message?message:noerror);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar return HTTP_INTERNAL_SERVER_ERROR;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (cfg->redirect == 1) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar newuri = apr_table_get(r->headers_in, "Referer");
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (!newuri && cfg->redir_query) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar query = apr_hash_get(dbd->prepared, cfg->redir_query,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar APR_HASH_KEY_STRING);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (query == NULL) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01646)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "authz_dbd: no redirect query!");
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar /* OK, this is non-critical; we can just not-redirect */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar &res, query, 0, r->user, NULL)) == 0) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar rv != -1;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (rv != 0) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar message = apr_dbd_error(dbd->driver, dbd->handle, rv);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01647)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "authz_dbd in get_row; action=%s user=%s [%s]",
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar action, r->user, message?message:noerror);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar else if (newuri == NULL) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar newuri = apr_dbd_get_entry(dbd->driver, row, 0);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar /* we can't break out here or row won't get cleaned up */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar else {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar message = apr_dbd_error(dbd->driver, dbd->handle, rv);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01648)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar "authz_dbd/redirect for %s of %s [%s]",
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar action, r->user, message?message:noerror);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar if (newuri != NULL) {
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar r->status = HTTP_MOVED_TEMPORARILY;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_table_set(r->err_headers_out, "Location", newuri);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar }
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar authz_dbd_run_client_login(r, OK, action);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar return OK;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar}
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar
1f1b6bf13313fdd14a45e52e553d3ff28689b717coarstatic int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg,
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_array_header_t *groups)
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar{
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar /* SELECT group FROM authz WHERE user = %s */
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar int rv;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar const char *message;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar ap_dbd_t *dbd = dbd_handle(r);
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_dbd_prepared_t *query;
1f1b6bf13313fdd14a45e52e553d3ff28689b717coar apr_dbd_results_t *res = NULL;
b686b6a420bde7f78c416b90be11db94cb789979nd apr_dbd_row_t *row = NULL;
b686b6a420bde7f78c416b90be11db94cb789979nd const char **group;
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd if (cfg->query == NULL) {
07dc96d063d49299da433f84b5c5681da9bbdf68rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01649)
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung "No query configured for dbd-group!");
727872d18412fc021f03969b8641810d8896820bhumbedooh return HTTP_INTERNAL_SERVER_ERROR;
0d0ba3a410038e179b695446bb149cce6264e0abnd }
727872d18412fc021f03969b8641810d8896820bhumbedooh query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh if (query == NULL) {
0d0ba3a410038e179b695446bb149cce6264e0abnd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650)
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh "Error retrieving query for dbd-group!");
727872d18412fc021f03969b8641810d8896820bhumbedooh return HTTP_INTERNAL_SERVER_ERROR;
0d0ba3a410038e179b695446bb149cce6264e0abnd }
0d0ba3a410038e179b695446bb149cce6264e0abnd rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
0d0ba3a410038e179b695446bb149cce6264e0abnd query, 0, r->user, NULL);
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedooh if (rv == 0) {
0d0ba3a410038e179b695446bb149cce6264e0abnd for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
0d0ba3a410038e179b695446bb149cce6264e0abnd rv != -1;
0d0ba3a410038e179b695446bb149cce6264e0abnd rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
727872d18412fc021f03969b8641810d8896820bhumbedooh if (rv == 0) {
0d0ba3a410038e179b695446bb149cce6264e0abnd group = apr_array_push(groups);
0d0ba3a410038e179b695446bb149cce6264e0abnd *group = apr_dbd_get_entry(dbd->driver, row, 0);
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh }
205f749042ed530040a4f0080dbcb47ceae8a374rjung else {
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen message = apr_dbd_error(dbd->driver, dbd->handle, rv);
0d0ba3a410038e179b695446bb149cce6264e0abnd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01651)
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd "authz_dbd in get_row; group query for user=%s [%s]",
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd r->user, message?message:noerror);
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd return HTTP_INTERNAL_SERVER_ERROR;
b686b6a420bde7f78c416b90be11db94cb789979nd }
}
}
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 authz_status dbdgroup_check_authorization(request_rec *r,
const char *require_args,
const void *parsed_require_args)
{
int i, rv;
const char *w;
apr_array_header_t *groups = NULL;
const char *err = NULL;
const ap_expr_info_t *expr = parsed_require_args;
const char *require;
const char *t;
authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
&authz_dbd_module);
if (!r->user) {
return AUTHZ_DENIED_NO_USER;
}
if (groups == NULL) {
groups = apr_array_make(r->pool, 4, sizeof(const char*));
rv = authz_dbd_group_query(r, cfg, groups);
if (rv != OK) {
return AUTHZ_GENERAL_ERROR;
}
}
require = ap_expr_str_exec(r, expr, &err);
if (err) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02590)
"authz_dbd authorize: require dbd-group: Can't "
"evaluate require expression: %s", err);
return AUTHZ_DENIED;
}
t = require;
while (t[0]) {
w = ap_getword_white(r->pool, &t);
for (i=0; i < groups->nelts; ++i) {
if (!strcmp(w, ((const char**)groups->elts)[i])) {
return AUTHZ_GRANTED;
}
}
}
return AUTHZ_DENIED;
}
static authz_status dbdlogin_check_authorization(request_rec *r,
const char *require_args,
const void *parsed_require_args)
{
authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
&authz_dbd_module);
if (!r->user) {
return AUTHZ_DENIED_NO_USER;
}
return (authz_dbd_login(r, cfg, "login") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
}
static authz_status dbdlogout_check_authorization(request_rec *r,
const char *require_args,
const void *parsed_require_args)
{
authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
&authz_dbd_module);
if (!r->user) {
return AUTHZ_DENIED_NO_USER;
}
return (authz_dbd_login(r, cfg, "logout") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
}
static const char *dbd_parse_config(cmd_parms *cmd, const char *require_line,
const void **parsed_require_line)
{
const char *expr_err = NULL;
ap_expr_info_t *expr;
expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
&expr_err, NULL);
if (expr_err)
return apr_pstrcat(cmd->temp_pool,
"Cannot parse expression in require line: ",
expr_err, NULL);
*parsed_require_line = expr;
return NULL;
}
static const authz_provider authz_dbdgroup_provider =
{
&dbdgroup_check_authorization,
&dbd_parse_config,
};
static const authz_provider authz_dbdlogin_provider =
{
&dbdlogin_check_authorization,
NULL,
};
static const authz_provider authz_dbdlogout_provider =
{
&dbdlogout_check_authorization,
NULL,
};
static void authz_dbd_hooks(apr_pool_t *p)
{
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-group",
AUTHZ_PROVIDER_VERSION,
&authz_dbdgroup_provider,
AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-login",
AUTHZ_PROVIDER_VERSION,
&authz_dbdlogin_provider,
AP_AUTH_INTERNAL_PER_CONF);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-logout",
AUTHZ_PROVIDER_VERSION,
&authz_dbdlogout_provider,
AP_AUTH_INTERNAL_PER_CONF);
}
AP_DECLARE_MODULE(authz_dbd) =
{
STANDARD20_MODULE_STUFF,
authz_dbd_cr_cfg,
authz_dbd_merge_cfg,
NULL,
NULL,
authz_dbd_cmds,
authz_dbd_hooks
};