mod_session_dbd.c revision 185aa71728867671e105178b4c66fbc22b65ae26
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele/* Licensed to the Apache Software Foundation (ASF) under one or more
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele * contributor license agreements. See the NOTICE file distributed with
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele * this work for additional information regarding copyright ownership.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * The ASF licenses this file to You under the Apache License, Version 2.0
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * (the "License"); you may not use this file except in compliance with
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * the License. You may obtain a copy of the License at
5a58787efeb02a1c3f06569d019ad81fd2efa06end *
8a77625288bc7112717de423742309213a7d453erbowen * http://www.apache.org/licenses/LICENSE-2.0
5a58787efeb02a1c3f06569d019ad81fd2efa06end *
5a58787efeb02a1c3f06569d019ad81fd2efa06end * Unless required by applicable law or agreed to in writing, software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * distributed under the License is distributed on an "AS IS" BASIS,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * limitations under the License.
5a58787efeb02a1c3f06569d019ad81fd2efa06end */
5a58787efeb02a1c3f06569d019ad81fd2efa06end
d229f940abfb2490dee17979e9a5ff31b7012eb5rbowen#include "mod_session.h"
3f08db06526d6901aa08c110b5bc7dde6bc39905nd#include "apr_lib.h"
5a58787efeb02a1c3f06569d019ad81fd2efa06end#include "apr_strings.h"
5a58787efeb02a1c3f06569d019ad81fd2efa06end#include "http_log.h"
5a58787efeb02a1c3f06569d019ad81fd2efa06end#include "util_cookies.h"
8a77625288bc7112717de423742309213a7d453erbowen#include "apr_dbd.h"
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd#include "mod_dbd.h"
a0e183666b44ebb43fdfeffe78d36c6134a59d4dyoshiki#include "mpm_common.h"
980bee71ed017c72bfdd9861445f9495855508ccgryzor
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd#define MOD_SESSION_DBD "mod_session_dbd"
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjungmodule AP_MODULE_DECLARE_DATA session_dbd_module;
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd/**
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * Structure to carry the per-dir session config.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
5a58787efeb02a1c3f06569d019ad81fd2efa06endtypedef struct {
5a58787efeb02a1c3f06569d019ad81fd2efa06end const char *name;
5a58787efeb02a1c3f06569d019ad81fd2efa06end int name_set;
5a58787efeb02a1c3f06569d019ad81fd2efa06end const char *name_attrs;
5a58787efeb02a1c3f06569d019ad81fd2efa06end const char *name2;
5a58787efeb02a1c3f06569d019ad81fd2efa06end int name2_set;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd const char *name2_attrs;
5a58787efeb02a1c3f06569d019ad81fd2efa06end int peruser;
5a58787efeb02a1c3f06569d019ad81fd2efa06end int peruser_set;
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh int remove;
5a58787efeb02a1c3f06569d019ad81fd2efa06end int remove_set;
5a58787efeb02a1c3f06569d019ad81fd2efa06end const char *selectlabel;
5a58787efeb02a1c3f06569d019ad81fd2efa06end const char *insertlabel;
1470b0770377e1262eddde0b12acef1adb20229digalic const char *updatelabel;
1470b0770377e1262eddde0b12acef1adb20229digalic const char *deletelabel;
1bf55339918c7e8ebf57ab686ff459c3f2651fcagryzor} session_dbd_dir_conf;
8a77625288bc7112717de423742309213a7d453erbowen
1bf55339918c7e8ebf57ab686ff459c3f2651fcagryzor/* optional function - look it up once in post_config */
5a58787efeb02a1c3f06569d019ad81fd2efa06endstatic ap_dbd_t *(*session_dbd_acquire_fn) (request_rec *) = NULL;
5a58787efeb02a1c3f06569d019ad81fd2efa06endstatic void (*session_dbd_prepare_fn) (server_rec *, const char *, const char *) = NULL;
5a58787efeb02a1c3f06569d019ad81fd2efa06end
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen/**
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * Initialise the database.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * If the mod_dbd module is missing, this method will return APR_EGENERAL.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowenstatic apr_status_t dbd_init(request_rec *r, const char *query, ap_dbd_t **dbdp,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_dbd_prepared_t **statementp)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen{
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd ap_dbd_t *dbd;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd apr_dbd_prepared_t *statement;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd session_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen session_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh if (!session_dbd_prepare_fn || !session_dbd_acquire_fn) {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01850)
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd "You must load mod_dbd to enable AuthDBD functions");
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive }
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive }
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive dbd = session_dbd_acquire_fn(r);
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive if (!dbd) {
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01851)
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive "failed to acquire database connection");
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive }
c10e24e52c0f454df46a44e3ccc8ccb56abd9d2aslive
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen statement = apr_hash_get(dbd->prepared, query, APR_HASH_KEY_STRING);
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele if (!statement) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01852)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "failed to find the prepared statement called '%s'", query);
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd return APR_EGENERAL;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *dbdp = dbd;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd *statementp = statement;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_SUCCESS;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen}
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen/**
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * Load the session by the key specified.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowenstatic apr_status_t dbd_load(request_rec * r, const char *key, const char **val)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen{
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_status_t rv;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_dbd_t *dbd = NULL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_dbd_prepared_t *statement = NULL;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd apr_dbd_results_t *res = NULL;
5a58787efeb02a1c3f06569d019ad81fd2efa06end apr_dbd_row_t *row = NULL;
5a58787efeb02a1c3f06569d019ad81fd2efa06end apr_int64_t expiry = (apr_int64_t) apr_time_now();
5a58787efeb02a1c3f06569d019ad81fd2efa06end
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen &session_dbd_module);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen if (conf->selectlabel == NULL) {
1bf55339918c7e8ebf57ab686ff459c3f2651fcagryzor ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01853)
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen "no SessionDBDselectlabel has been specified");
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen rv = dbd_init(r, conf->selectlabel, &dbd, &statement);
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen if (rv) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return rv;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen rv = apr_dbd_pvbselect(dbd->driver, r->pool, dbd->handle, &res, statement,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen 0, key, &expiry, NULL);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (rv) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01854)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "query execution error saving session '%s' "
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "in database using query '%s': %s", key, conf->selectlabel,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_dbd_error(dbd->driver, dbd->handle, rv));
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen rv != -1;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
1bf55339918c7e8ebf57ab686ff459c3f2651fcagryzor if (rv != 0) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01855)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "error retrieving results while saving '%s' "
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "in database using query '%s': %s", key, conf->selectlabel,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_dbd_error(dbd->driver, dbd->handle, rv));
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele }
8a77625288bc7112717de423742309213a7d453erbowen if (*val == NULL) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *val = apr_dbd_get_entry(dbd->driver, row, 0);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* we can't break out here or row won't get cleaned up */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_SUCCESS;
8a77625288bc7112717de423742309213a7d453erbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen}
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen/**
8a77625288bc7112717de423742309213a7d453erbowen * Load the session by firing off a dbd query.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * If the session is anonymous, the session key will be extracted from
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd * the cookie specified. Failing that, the session key will be extracted
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele * from the GET parameters.
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele *
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele * If the session is keyed by the username, the session will be extracted
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * by that.
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd *
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * If no session is found, an empty session will be created.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * On success, this returns OK.
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd */
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5ndstatic apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd{
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen &session_dbd_module);
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen apr_status_t ret = APR_SUCCESS;
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen session_rec *zz = NULL;
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen const char *name = NULL;
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen const char *note = NULL;
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen const char *val = NULL;
bde4540877ce9bac98aec1d196a307b39c5c9775rbowen const char *key = NULL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen request_rec *m = r->main ? r->main : r;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* is our session in a cookie? */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (conf->name2_set) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen name = conf->name2;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen else if (conf->name_set) {
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd name = conf->name;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd else if (conf->peruser_set && r->user) {
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd name = r->user;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd else {
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd return DECLINED;
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* first look in the notes */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen note = apr_pstrcat(r->pool, MOD_SESSION_DBD, name, NULL);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz = (session_rec *)apr_table_get(m->notes, note);
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele if (zz) {
e487d6c09669296f94a5190cc34586a98e624a00nd *z = zz;
e487d6c09669296f94a5190cc34586a98e624a00nd return OK;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele
e487d6c09669296f94a5190cc34586a98e624a00nd /* load anonymous sessions */
a720273cbea5177f46ba0550044a31f6363d3e4chumbedooh if (conf->name_set || conf->name2_set) {
a720273cbea5177f46ba0550044a31f6363d3e4chumbedooh
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh /* load an RFC2109 or RFC2965 compliant cookie */
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh ap_cookie_read(r, name, &key, conf->remove);
e487d6c09669296f94a5190cc34586a98e624a00nd if (key) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ret = dbd_load(r, key, &val);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (ret != APR_SUCCESS) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return ret;
8a77625288bc7112717de423742309213a7d453erbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd /* load named session */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen else if (conf->peruser) {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh if (r->user) {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh ret = dbd_load(r, r->user, &val);
5a58787efeb02a1c3f06569d019ad81fd2efa06end if (ret != APR_SUCCESS) {
5a58787efeb02a1c3f06569d019ad81fd2efa06end return ret;
5a58787efeb02a1c3f06569d019ad81fd2efa06end }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* otherwise not for us */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen else {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return DECLINED;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* create a new session and return it */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec));
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz->pool = r->pool;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz->entries = apr_table_make(zz->pool, 10);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz->uuid = (apr_uuid_t *) apr_pcalloc(zz->pool, sizeof(apr_uuid_t));
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (key) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_uuid_parse(zz->uuid, key);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen else {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh apr_uuid_get(zz->uuid);
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen zz->encoded = val;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen *z = zz;
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /* put the session in the notes so we don't have to parse it again */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_table_setn(m->notes, note, (char *)zz);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return OK;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh}
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen/**
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * Save the session by the key specified.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowenstatic apr_status_t dbd_save(request_rec * r, const char *key, const char *val,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_int64_t expiry)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen{
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive apr_status_t rv;
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive ap_dbd_t *dbd = NULL;
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive apr_dbd_prepared_t *statement;
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive int rows = 0;
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen &session_dbd_module);
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen if (conf->updatelabel == NULL) {
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01856)
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive "no SessionDBDupdatelabel has been specified");
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive return APR_EGENERAL;
419d55842022e9e257941bfe226549661fb2c6c7humbedooh }
419d55842022e9e257941bfe226549661fb2c6c7humbedooh
a720273cbea5177f46ba0550044a31f6363d3e4chumbedooh rv = dbd_init(r, conf->updatelabel, &dbd, &statement);
419d55842022e9e257941bfe226549661fb2c6c7humbedooh if (rv) {
419d55842022e9e257941bfe226549661fb2c6c7humbedooh return rv;
419d55842022e9e257941bfe226549661fb2c6c7humbedooh }
419d55842022e9e257941bfe226549661fb2c6c7humbedooh rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive val, &expiry, key, NULL);
419d55842022e9e257941bfe226549661fb2c6c7humbedooh if (rv) {
419d55842022e9e257941bfe226549661fb2c6c7humbedooh ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01857)
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive "query execution error updating session '%s' "
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen "using database query '%s': %s", key, conf->updatelabel,
bcd392b291251e23c63d0cc4d11c9121e9627c24rbowen apr_dbd_error(dbd->driver, dbd->handle, rv));
2a80f5f5b2b28a9b603fc41d3e2b37128f5f1e00slive return APR_EGENERAL;
5a58787efeb02a1c3f06569d019ad81fd2efa06end }
5a58787efeb02a1c3f06569d019ad81fd2efa06end
5a58787efeb02a1c3f06569d019ad81fd2efa06end /*
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * if some rows were updated it means a session existed and was updated,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * so we are done.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (rows != 0) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_SUCCESS;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd if (conf->insertlabel == NULL) {
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01858)
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd "no SessionDBDinsertlabel has been specified");
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen rv = dbd_init(r, conf->insertlabel, &dbd, &statement);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (rv) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return rv;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
419d55842022e9e257941bfe226549661fb2c6c7humbedooh val, &expiry, key, NULL);
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh if (rv) {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01859)
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh "query execution error inserting session '%s' "
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh "in database with '%s': %s", key, conf->insertlabel,
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh apr_dbd_error(dbd->driver, dbd->handle, rv));
419d55842022e9e257941bfe226549661fb2c6c7humbedooh return APR_EGENERAL;
419d55842022e9e257941bfe226549661fb2c6c7humbedooh }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen /*
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * if some rows were inserted it means a session was inserted, so we are
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * done.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (rows != 0) {
5a58787efeb02a1c3f06569d019ad81fd2efa06end return APR_SUCCESS;
5a58787efeb02a1c3f06569d019ad81fd2efa06end }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01860)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "the session insert query did not cause any rows to be added "
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "to the database for session '%s', session not inserted", key);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
419d55842022e9e257941bfe226549661fb2c6c7humbedooh}
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh/**
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh * Remove the session by the key specified.
419d55842022e9e257941bfe226549661fb2c6c7humbedooh */
419d55842022e9e257941bfe226549661fb2c6c7humbedoohstatic apr_status_t dbd_remove(request_rec * r, const char *key)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen{
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_status_t rv;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen apr_dbd_prepared_t *statement;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen int rows = 0;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
5a58787efeb02a1c3f06569d019ad81fd2efa06end &session_dbd_module);
5a58787efeb02a1c3f06569d019ad81fd2efa06end ap_dbd_t *dbd = session_dbd_acquire_fn(r);
5a58787efeb02a1c3f06569d019ad81fd2efa06end if (dbd == NULL) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01861)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "failed to acquire database connection to remove "
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "session with key '%s'", key);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
419d55842022e9e257941bfe226549661fb2c6c7humbedooh
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh if (conf->deletelabel == NULL) {
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01862)
419d55842022e9e257941bfe226549661fb2c6c7humbedooh "no SessionDBDdeletelabel has been specified");
419d55842022e9e257941bfe226549661fb2c6c7humbedooh return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen statement = apr_hash_get(dbd->prepared, conf->deletelabel,
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen APR_HASH_KEY_STRING);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen if (statement == NULL) {
419d55842022e9e257941bfe226549661fb2c6c7humbedooh ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01863)
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh "prepared statement could not be found for "
15292da5451dea4ad10c12d35d9addc88be302c5humbedooh "SessionDBDdeletelabel with the label '%s'",
419d55842022e9e257941bfe226549661fb2c6c7humbedooh conf->deletelabel);
419d55842022e9e257941bfe226549661fb2c6c7humbedooh return APR_EGENERAL;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen }
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd rv = apr_dbd_pvbquery(dbd->driver, r->pool, dbd->handle, &rows, statement,
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd key, NULL);
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd if (rv != APR_SUCCESS) {
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01864)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "query execution error removing session '%s' "
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen "from database", key);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return rv;
5a58787efeb02a1c3f06569d019ad81fd2efa06end }
5a58787efeb02a1c3f06569d019ad81fd2efa06end
5a58787efeb02a1c3f06569d019ad81fd2efa06end return APR_SUCCESS;
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen}
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen/**
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * Clean out expired sessions.
d5082de325fb6351c6bd34d28df0b43ec5a8ac90erikabele *
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * TODO: We need to figure out a way to clean out expired sessions from the database.
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * The monitor hook doesn't help us that much, as we have no handle into the
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen * server, and so we need to come up with a way to do this safely.
f6066dc0a6ad0432b74774e290c04c3cc4aa2dafrbowen */
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowenstatic apr_status_t dbd_clean(apr_pool_t *p, server_rec *s)
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen{
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen return APR_ENOTIMPL;
8a77625288bc7112717de423742309213a7d453erbowen
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd}
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen/**
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * Save the session by firing off a dbd query.
91716c84e413f2c0385f902456df8c27fa45712brbowen *
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * If the session is anonymous, save the session and write a cookie
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * containing the uuid.
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen *
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * If the session is keyed to the username, save the session using
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * the username as a key.
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen *
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * On success, this method will return APR_SUCCESS.
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen *
1bf55339918c7e8ebf57ab686ff459c3f2651fcagryzor * @param r The request pointer.
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen * @param z A pointer to where the session will be written.
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen */
1baec6e12c9c698202c8cd880b8013431f7542c9rbowenstatic apr_status_t session_dbd_save(request_rec * r, session_rec * z)
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen{
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen char *buffer;
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen apr_status_t ret = APR_SUCCESS;
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen session_dbd_dir_conf *conf = ap_get_module_config(r->per_dir_config,
1baec6e12c9c698202c8cd880b8013431f7542c9rbowen &session_dbd_module);
47bbfaa3a2ea0afb775a3aa3e7dbf8a71ea1b966rbowen
6f227ca67f7a591c2b1dbfd0f7ac31cc341061a5nd /* support anonymous sessions */
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd if (conf->name_set || conf->name2_set) {
a0e183666b44ebb43fdfeffe78d36c6134a59d4dyoshiki
980bee71ed017c72bfdd9861445f9495855508ccgryzor /* don't cache pages with a session */
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung /* must we create a uuid? */
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh buffer = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
0d0ba3a410038e179b695446bb149cce6264e0abnd apr_uuid_format(buffer, z->uuid);
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh /* save the session with the uuid as key */
0d0ba3a410038e179b695446bb149cce6264e0abnd if (z->encoded && z->encoded[0]) {
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh ret = dbd_save(r, buffer, z->encoded, z->expiry);
888cb40bdeec5abf452bd85d6bf63b26d5913d4chumbedooh }
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh else {
0d0ba3a410038e179b695446bb149cce6264e0abnd ret = dbd_remove(r, buffer);
0d0ba3a410038e179b695446bb149cce6264e0abnd }
0d0ba3a410038e179b695446bb149cce6264e0abnd if (ret != APR_SUCCESS) {
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh return ret;
0d0ba3a410038e179b695446bb149cce6264e0abnd }
0d0ba3a410038e179b695446bb149cce6264e0abnd
0d0ba3a410038e179b695446bb149cce6264e0abnd /* create RFC2109 compliant cookie */
ed62c84ee0911cfebbd8da319ac00757b555707chumbedooh if (conf->name_set) {
0d0ba3a410038e179b695446bb149cce6264e0abnd ap_cookie_write(r, conf->name, buffer, conf->name_attrs, z->maxage,
0d0ba3a410038e179b695446bb149cce6264e0abnd r->headers_out, r->err_headers_out, NULL);
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh }
5effc8b39fae5cd169d17f342bfc265705840014rbowen
d229f940abfb2490dee17979e9a5ff31b7012eb5rbowen /* create RFC2965 compliant cookie */
0d0ba3a410038e179b695446bb149cce6264e0abnd if (conf->name2_set) {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd ap_cookie_write2(r, conf->name2, buffer, conf->name2_attrs, z->maxage,
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd r->headers_out, r->err_headers_out, NULL);
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd }
5a58787efeb02a1c3f06569d019ad81fd2efa06end
return OK;
}
/* save named session */
else if (conf->peruser) {
/* don't cache pages with a session */
apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
if (r->user) {
ret = dbd_save(r, r->user, z->encoded, z->expiry);
if (ret != APR_SUCCESS) {
return ret;
}
return OK;
}
else {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01865)
"peruser sessions can only be saved if a user is logged in, "
"session not saved: %s", r->uri);
}
}
return DECLINED;
}
/**
* This function performs housekeeping on the database, deleting expired
* sessions.
*/
static int session_dbd_monitor(apr_pool_t *p, server_rec *s)
{
/* TODO handle housekeeping */
dbd_clean(p, s);
return OK;
}
static void *create_session_dbd_dir_config(apr_pool_t * p, char *dummy)
{
session_dbd_dir_conf *new =
(session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
new->remove = 1;
new->selectlabel = "selectsession";
new->insertlabel = "insertsession";
new->updatelabel = "updatesession";
new->deletelabel = "deletesession";
return (void *) new;
}
static void *merge_session_dbd_dir_config(apr_pool_t * p, void *basev, void *addv)
{
session_dbd_dir_conf *new = (session_dbd_dir_conf *) apr_pcalloc(p, sizeof(session_dbd_dir_conf));
session_dbd_dir_conf *add = (session_dbd_dir_conf *) addv;
session_dbd_dir_conf *base = (session_dbd_dir_conf *) basev;
new->name = (add->name_set == 0) ? base->name : add->name;
new->name_attrs = (add->name_set == 0) ? base->name_attrs : add->name_attrs;
new->name_set = add->name_set || base->name_set;
new->name2 = (add->name2_set == 0) ? base->name2 : add->name2;
new->name2_attrs = (add->name2_set == 0) ? base->name2_attrs : add->name2_attrs;
new->name2_set = add->name2_set || base->name2_set;
new->peruser = (add->peruser_set == 0) ? base->peruser : add->peruser;
new->peruser_set = add->peruser_set || base->peruser_set;
new->remove = (add->remove_set == 0) ? base->remove : add->remove;
new->remove_set = add->remove_set || base->remove_set;
new->selectlabel = (!add->selectlabel) ? base->selectlabel : add->selectlabel;
new->updatelabel = (!add->updatelabel) ? base->updatelabel : add->updatelabel;
new->insertlabel = (!add->insertlabel) ? base->insertlabel : add->insertlabel;
new->deletelabel = (!add->deletelabel) ? base->deletelabel : add->deletelabel;
return new;
}
/**
* Sanity check a given string that it exists, is not empty,
* and does not contain special characters.
*/
static const char *check_string(cmd_parms * cmd, const char *string)
{
if (APR_SUCCESS != ap_cookie_check_string(string)) {
return apr_pstrcat(cmd->pool, cmd->directive->directive,
" cannot be empty, or contain '=', ';' or '&'.",
NULL);
}
return NULL;
}
static const char *
set_dbd_peruser(cmd_parms * parms, void *dconf, int flag)
{
session_dbd_dir_conf *conf = dconf;
conf->peruser = flag;
conf->peruser_set = 1;
return NULL;
}
static const char *
set_dbd_cookie_remove(cmd_parms * parms, void *dconf, int flag)
{
session_dbd_dir_conf *conf = dconf;
conf->remove = flag;
conf->remove_set = 1;
return NULL;
}
static const char *set_cookie_name(cmd_parms * cmd, void *config, const char *args)
{
char *last;
char *line = apr_pstrdup(cmd->pool, args);
session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
char *cookie = apr_strtok(line, " \t", &last);
conf->name = cookie;
conf->name_set = 1;
while (apr_isspace(*last)) {
last++;
}
conf->name_attrs = last;
return check_string(cmd, cookie);
}
static const char *set_cookie_name2(cmd_parms * cmd, void *config, const char *args)
{
char *last;
char *line = apr_pstrdup(cmd->pool, args);
session_dbd_dir_conf *conf = (session_dbd_dir_conf *) config;
char *cookie = apr_strtok(line, " \t", &last);
conf->name2 = cookie;
conf->name2_set = 1;
while (apr_isspace(*last)) {
last++;
}
conf->name2_attrs = last;
return check_string(cmd, cookie);
}
static const command_rec session_dbd_cmds[] =
{
AP_INIT_TAKE1("SessionDBDSelectLabel", ap_set_string_slot,
(void *) APR_OFFSETOF(session_dbd_dir_conf, selectlabel), RSRC_CONF|OR_AUTHCFG,
"Query label used to select a new session"),
AP_INIT_TAKE1("SessionDBDInsertLabel", ap_set_string_slot,
(void *) APR_OFFSETOF(session_dbd_dir_conf, insertlabel), RSRC_CONF|OR_AUTHCFG,
"Query label used to insert a new session"),
AP_INIT_TAKE1("SessionDBDUpdateLabel", ap_set_string_slot,
(void *) APR_OFFSETOF(session_dbd_dir_conf, updatelabel), RSRC_CONF|OR_AUTHCFG,
"Query label used to update an existing session"),
AP_INIT_TAKE1("SessionDBDDeleteLabel", ap_set_string_slot,
(void *) APR_OFFSETOF(session_dbd_dir_conf, deletelabel), RSRC_CONF|OR_AUTHCFG,
"Query label used to delete an existing session"),
AP_INIT_FLAG("SessionDBDPerUser", set_dbd_peruser, NULL, RSRC_CONF|OR_AUTHCFG,
"Save the session per user"),
AP_INIT_FLAG("SessionDBDCookieRemove", set_dbd_cookie_remove, NULL, RSRC_CONF|OR_AUTHCFG,
"Remove the session cookie after session load. On by default."),
AP_INIT_RAW_ARGS("SessionDBDCookieName", set_cookie_name, NULL, RSRC_CONF|OR_AUTHCFG,
"The name of the RFC2109 cookie carrying the session key"),
AP_INIT_RAW_ARGS("SessionDBDCookieName2", set_cookie_name2, NULL, RSRC_CONF|OR_AUTHCFG,
"The name of the RFC2965 cookie carrying the session key"),
{NULL}
};
static void register_hooks(apr_pool_t * p)
{
ap_hook_session_load(session_dbd_load, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_session_save(session_dbd_save, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_monitor(session_dbd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
}
AP_DECLARE_MODULE(session_dbd) =
{
STANDARD20_MODULE_STUFF,
create_session_dbd_dir_config, /* dir config creater */
merge_session_dbd_dir_config, /* dir merger --- default is to
* override */
NULL, /* server config */
NULL, /* merge server config */
session_dbd_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};