diff options
Diffstat (limited to 'modules/ldap/util_ldap_cache.c')
-rw-r--r-- | modules/ldap/util_ldap_cache.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/modules/ldap/util_ldap_cache.c b/modules/ldap/util_ldap_cache.c new file mode 100644 index 0000000..774a76e --- /dev/null +++ b/modules/ldap/util_ldap_cache.c @@ -0,0 +1,467 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * util_ldap_cache.c: LDAP cache things + * + * Original code from auth_ldap module for Apache v1.3: + * Copyright 1998, 1999 Enbridge Pipelines Inc. + * Copyright 1999-2001 Dave Carrigan + */ + +#include "httpd.h" +#include "util_ldap.h" +#include "util_ldap_cache.h" +#include <apr_strings.h> + +#if APR_HAS_LDAP + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_url_node_hash(void *n) +{ + util_url_node_t *node = n; + return util_ald_hash_string(1, node->url); +} + +int util_ldap_url_node_compare(void *a, void *b) +{ + util_url_node_t *na = a; + util_url_node_t *nb = b; + + return (strcmp(na->url, nb->url) == 0); +} + +void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c) +{ + util_url_node_t *n = c; + util_url_node_t *node = util_ald_alloc(cache, sizeof *node); + + if (node) { + if (!(node->url = util_ald_strdup(cache, n->url))) { + util_ald_free(cache, node); + return NULL; + } + node->search_cache = n->search_cache; + node->compare_cache = n->compare_cache; + node->dn_compare_cache = n->dn_compare_cache; + return node; + } + else { + return NULL; + } +} + +void util_ldap_url_node_free(util_ald_cache_t *cache, void *n) +{ + util_url_node_t *node = n; + + util_ald_free(cache, node->url); + util_ald_destroy_cache(node->search_cache); + util_ald_destroy_cache(node->compare_cache); + util_ald_destroy_cache(node->dn_compare_cache); + util_ald_free(cache, node); +} + +void util_ldap_url_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_url_node_t *node = n; + char date_str[APR_CTIME_LEN]; + const char *type_str; + util_ald_cache_t *cache_node; + int x; + + for (x=0;x<3;x++) { + switch (x) { + case 0: + cache_node = node->search_cache; + type_str = "Searches"; + break; + case 1: + cache_node = node->compare_cache; + type_str = "Compares"; + break; + case 2: + default: + cache_node = node->dn_compare_cache; + type_str = "DN Compares"; + break; + } + + if (cache_node->marktime) { + apr_ctime(date_str, cache_node->marktime); + } + else + date_str[0] = 0; + + ap_rprintf(r, + "<tr valign='top'>" + "<td nowrap>%s (%s)</td>" + "<td nowrap>%ld</td>" + "<td nowrap>%ld</td>" + "<td nowrap>%ld</td>" + "<td nowrap>%" APR_TIME_T_FMT "</td>" + "<td nowrap>%ld</td>" + "<td nowrap>%s</td>" + "</tr>", + node->url, + type_str, + cache_node->size, + cache_node->maxentries, + cache_node->numentries, + apr_time_sec(cache_node->ttl), + cache_node->fullmark, + date_str); + } + +} + +/* ------------------------------------------------------------------ */ + +/* Cache functions for search nodes */ +unsigned long util_ldap_search_node_hash(void *n) +{ + util_search_node_t *node = n; + return util_ald_hash_string(1, node->username); +} + +int util_ldap_search_node_compare(void *a, void *b) +{ + util_search_node_t *na = a; + util_search_node_t *nb = b; + + return (strcmp(na->username, nb->username) == 0); +} + +void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c) +{ + util_search_node_t *node = c; + util_search_node_t *newnode = util_ald_alloc(cache, sizeof *newnode); + + /* safety check */ + if (newnode) { + + /* copy vals */ + if (node->vals) { + int k = node->numvals; + int i = 0; + if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + newnode->numvals = node->numvals; + for (;k;k--) { + if (node->vals[i]) { + if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + } + else + newnode->vals[i] = NULL; + i++; + } + } + else { + newnode->vals = NULL; + } + if (!(newnode->username = util_ald_strdup(cache, node->username)) || + !(newnode->dn = util_ald_strdup(cache, node->dn)) ) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + if (node->bindpw) { + if (!(newnode->bindpw = util_ald_strdup(cache, node->bindpw))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } + } else { + newnode->bindpw = NULL; + } + newnode->lastbind = node->lastbind; + + } + return (void *)newnode; +} + +void util_ldap_search_node_free(util_ald_cache_t *cache, void *n) +{ + int i = 0; + util_search_node_t *node = n; + int k = node->numvals; + + if (node->vals) { + for (;k;k--,i++) { + if (node->vals[i]) { + util_ald_free(cache, node->vals[i]); + } + } + util_ald_free(cache, node->vals); + } + util_ald_free(cache, node->username); + util_ald_free(cache, node->dn); + util_ald_free(cache, node->bindpw); + util_ald_free(cache, node); +} + +void util_ldap_search_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_search_node_t *node = n; + char date_str[APR_CTIME_LEN]; + + apr_ctime(date_str, node->lastbind); + + ap_rprintf(r, + "<tr valign='top'>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "</tr>", + node->username, + node->dn, + date_str); +} + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_compare_node_hash(void *n) +{ + util_compare_node_t *node = n; + return util_ald_hash_string(3, node->dn, node->attrib, node->value); +} + +int util_ldap_compare_node_compare(void *a, void *b) +{ + util_compare_node_t *na = a; + util_compare_node_t *nb = b; + + return (strcmp(na->dn, nb->dn) == 0 && + strcmp(na->attrib, nb->attrib) == 0 && + strcmp(na->value, nb->value) == 0); +} + +void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c) +{ + util_compare_node_t *n = c; + util_compare_node_t *node = util_ald_alloc(cache, sizeof *node); + + if (node) { + if (!(node->dn = util_ald_strdup(cache, n->dn)) || + !(node->attrib = util_ald_strdup(cache, n->attrib)) || + !(node->value = util_ald_strdup(cache, n->value)) || + ((n->subgroupList) && !(node->subgroupList = util_ald_sgl_dup(cache, n->subgroupList)))) { + util_ldap_compare_node_free(cache, node); + return NULL; + } + node->lastcompare = n->lastcompare; + node->result = n->result; + node->sgl_processed = n->sgl_processed; + return node; + } + else { + return NULL; + } +} + +void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n) +{ + util_compare_node_t *node = n; + + util_ald_sgl_free(cache, &(node->subgroupList)); + util_ald_free(cache, node->dn); + util_ald_free(cache, node->attrib); + util_ald_free(cache, node->value); + util_ald_free(cache, node); +} + +void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_compare_node_t *node = n; + char date_str[APR_CTIME_LEN]; + char *cmp_result; + char *sub_groups_val; + char *sub_groups_checked; + + apr_ctime(date_str, node->lastcompare); + + if (node->result == LDAP_COMPARE_TRUE) { + cmp_result = "LDAP_COMPARE_TRUE"; + } + else if (node->result == LDAP_COMPARE_FALSE) { + cmp_result = "LDAP_COMPARE_FALSE"; + } + else { + cmp_result = apr_itoa(r->pool, node->result); + } + + if (node->subgroupList) { + sub_groups_val = "Yes"; + } + else { + sub_groups_val = "No"; + } + + if (node->sgl_processed) { + sub_groups_checked = "Yes"; + } + else { + sub_groups_checked = "No"; + } + + ap_rprintf(r, + "<tr valign='top'>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "</tr>", + node->dn, + node->attrib, + node->value, + date_str, + cmp_result, + sub_groups_val, + sub_groups_checked); +} + +/* ------------------------------------------------------------------ */ + +unsigned long util_ldap_dn_compare_node_hash(void *n) +{ + util_dn_compare_node_t *node = n; + return util_ald_hash_string(1, node->reqdn); +} + +int util_ldap_dn_compare_node_compare(void *a, void *b) +{ + util_dn_compare_node_t *na = a; + util_dn_compare_node_t *nb = b; + + return (strcmp(na->reqdn, nb->reqdn) == 0); +} + +void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c) +{ + util_dn_compare_node_t *n = c; + util_dn_compare_node_t *node = util_ald_alloc(cache, sizeof *node); + + if (node) { + if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) || + !(node->dn = util_ald_strdup(cache, n->dn))) { + util_ldap_dn_compare_node_free(cache, node); + return NULL; + } + return node; + } + else { + return NULL; + } +} + +void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n) +{ + util_dn_compare_node_t *node = n; + util_ald_free(cache, node->reqdn); + util_ald_free(cache, node->dn); + util_ald_free(cache, node); +} + +void util_ldap_dn_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) +{ + util_dn_compare_node_t *node = n; + + ap_rprintf(r, + "<tr valign='top'>" + "<td nowrap>%s</td>" + "<td nowrap>%s</td>" + "</tr>", + node->reqdn, + node->dn); +} + + +/* ------------------------------------------------------------------ */ +static apr_status_t util_ldap_cache_module_kill(void *data) +{ + util_ldap_state_t *st = data; + + util_ald_destroy_cache(st->util_ldap_cache); +#if APR_HAS_SHARED_MEMORY + if (st->cache_rmm != NULL) { + apr_rmm_destroy (st->cache_rmm); + st->cache_rmm = NULL; + } + if (st->cache_shm != NULL) { + apr_status_t result = apr_shm_destroy(st->cache_shm); + st->cache_shm = NULL; + return result; + } +#endif + return APR_SUCCESS; +} + +apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st) +{ +#if APR_HAS_SHARED_MEMORY + apr_status_t result; + apr_size_t size; + + if (st->cache_bytes > 0) { + if (st->cache_file) { + /* Remove any existing shm segment with this name. */ + apr_shm_remove(st->cache_file, st->pool); + } + + size = APR_ALIGN_DEFAULT(st->cache_bytes); + + result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool); + if (result != APR_SUCCESS) { + return result; + } + + /* Determine the usable size of the shm segment. */ + size = apr_shm_size_get(st->cache_shm); + + /* This will create a rmm "handler" to get into the shared memory area */ + result = apr_rmm_init(&st->cache_rmm, NULL, + apr_shm_baseaddr_get(st->cache_shm), size, + st->pool); + if (result != APR_SUCCESS) { + return result; + } + } + +#endif + + apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null); + + st->util_ldap_cache = + util_ald_create_cache(st, + st->search_cache_size, + st->search_cache_ttl, + util_ldap_url_node_hash, + util_ldap_url_node_compare, + util_ldap_url_node_copy, + util_ldap_url_node_free, + util_ldap_url_node_display); + return APR_SUCCESS; +} + + +#endif /* APR_HAS_LDAP */ |