~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to modules/ldap/util_ldap_cache.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
 
2
 * contributor license agreements.  See the NOTICE file distributed with
 
3
 * this work for additional information regarding copyright ownership.
 
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
5
 * (the "License"); you may not use this file except in compliance with
 
6
 * the License.  You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
/*
 
18
 * util_ldap_cache.c: LDAP cache things
 
19
 *
 
20
 * Original code from auth_ldap module for Apache v1.3:
 
21
 * Copyright 1998, 1999 Enbridge Pipelines Inc.
 
22
 * Copyright 1999-2001 Dave Carrigan
 
23
 */
 
24
 
 
25
#include "httpd.h"
 
26
#include "util_ldap.h"
 
27
#include "util_ldap_cache.h"
 
28
#include <apr_strings.h>
 
29
 
 
30
#if APR_HAS_LDAP
 
31
 
 
32
/* ------------------------------------------------------------------ */
 
33
 
 
34
unsigned long util_ldap_url_node_hash(void *n)
 
35
{
 
36
    util_url_node_t *node = n;
 
37
    return util_ald_hash_string(1, node->url);
 
38
}
 
39
 
 
40
int util_ldap_url_node_compare(void *a, void *b)
 
41
{
 
42
    util_url_node_t *na = a;
 
43
    util_url_node_t *nb = b;
 
44
 
 
45
    return (strcmp(na->url, nb->url) == 0);
 
46
}
 
47
 
 
48
void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c)
 
49
{
 
50
    util_url_node_t *n = c;
 
51
    util_url_node_t *node = util_ald_alloc(cache, sizeof *node);
 
52
 
 
53
    if (node) {
 
54
        if (!(node->url = util_ald_strdup(cache, n->url))) {
 
55
            util_ald_free(cache, node->url);
 
56
            return NULL;
 
57
        }
 
58
        node->search_cache = n->search_cache;
 
59
        node->compare_cache = n->compare_cache;
 
60
        node->dn_compare_cache = n->dn_compare_cache;
 
61
        return node;
 
62
    }
 
63
    else {
 
64
        return NULL;
 
65
    }
 
66
}
 
67
 
 
68
void util_ldap_url_node_free(util_ald_cache_t *cache, void *n)
 
69
{
 
70
    util_url_node_t *node = n;
 
71
 
 
72
    util_ald_free(cache, node->url);
 
73
    util_ald_destroy_cache(node->search_cache);
 
74
    util_ald_destroy_cache(node->compare_cache);
 
75
    util_ald_destroy_cache(node->dn_compare_cache);
 
76
    util_ald_free(cache, node);
 
77
}
 
78
 
 
79
void util_ldap_url_node_display(request_rec *r, util_ald_cache_t *cache, void *n)
 
80
{
 
81
    util_url_node_t *node = n;
 
82
    char date_str[APR_CTIME_LEN+1];
 
83
    const char *type_str;
 
84
    util_ald_cache_t *cache_node;
 
85
    int x;
 
86
 
 
87
    for (x=0;x<3;x++) {
 
88
        switch (x) {
 
89
            case 0:
 
90
                cache_node = node->search_cache;
 
91
                type_str = "Searches";
 
92
                break;
 
93
            case 1:
 
94
                cache_node = node->compare_cache;
 
95
                type_str = "Compares";
 
96
                break;
 
97
            case 2:
 
98
            default:
 
99
                cache_node = node->dn_compare_cache;
 
100
                type_str = "DN Compares";
 
101
                break;
 
102
        }
 
103
 
 
104
        if (cache_node->marktime) {
 
105
            apr_ctime(date_str, cache_node->marktime);
 
106
        }
 
107
        else
 
108
            date_str[0] = 0;
 
109
 
 
110
        ap_rprintf(r,
 
111
                   "<tr valign='top'>"
 
112
                   "<td nowrap>%s (%s)</td>"
 
113
                   "<td nowrap>%ld</td>"
 
114
                   "<td nowrap>%ld</td>"
 
115
                   "<td nowrap>%ld</td>"
 
116
                   "<td nowrap>%ld</td>"
 
117
                   "<td nowrap>%s</td>"
 
118
                   "</tr>",
 
119
                   node->url,
 
120
                   type_str,
 
121
                   cache_node->size,
 
122
                   cache_node->maxentries,
 
123
                   cache_node->numentries,
 
124
                   cache_node->fullmark,
 
125
                   date_str);
 
126
    }
 
127
 
 
128
}
 
129
 
 
130
/* ------------------------------------------------------------------ */
 
131
 
 
132
/* Cache functions for search nodes */
 
133
unsigned long util_ldap_search_node_hash(void *n)
 
134
{
 
135
    util_search_node_t *node = n;
 
136
    return util_ald_hash_string(1, node->username);
 
137
}
 
138
 
 
139
int util_ldap_search_node_compare(void *a, void *b)
 
140
{
 
141
    util_search_node_t *na = a;
 
142
    util_search_node_t *nb = b;
 
143
 
 
144
    return (strcmp(na->username, nb->username) == 0);
 
145
}
 
146
 
 
147
void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c)
 
148
{
 
149
    util_search_node_t *node = c;
 
150
    util_search_node_t *newnode = util_ald_alloc(cache, sizeof *newnode);
 
151
 
 
152
    /* safety check */
 
153
    if (newnode) {
 
154
 
 
155
        /* copy vals */
 
156
        if (node->vals) {
 
157
            int k = node->numvals;
 
158
            int i = 0;
 
159
            if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) {
 
160
                util_ldap_search_node_free(cache, newnode);
 
161
                return NULL;
 
162
            }
 
163
            newnode->numvals = node->numvals;
 
164
            for (;k;k--) {
 
165
                if (node->vals[i]) {
 
166
                    if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) {
 
167
                        util_ldap_search_node_free(cache, newnode);
 
168
                        return NULL;
 
169
                    }
 
170
                }
 
171
                else
 
172
                    newnode->vals[i] = NULL;
 
173
                i++;
 
174
            }
 
175
        }
 
176
        else {
 
177
            newnode->vals = NULL;
 
178
        }
 
179
        if (!(newnode->username = util_ald_strdup(cache, node->username)) ||
 
180
            !(newnode->dn = util_ald_strdup(cache, node->dn)) ) {
 
181
            util_ldap_search_node_free(cache, newnode);
 
182
            return NULL;
 
183
        }
 
184
        if(node->bindpw) {
 
185
            if(!(newnode->bindpw = util_ald_strdup(cache, node->bindpw))) {
 
186
                util_ldap_search_node_free(cache, newnode);
 
187
                return NULL;
 
188
            }
 
189
        } else {
 
190
            newnode->bindpw = NULL;
 
191
        }
 
192
        newnode->lastbind = node->lastbind;
 
193
 
 
194
    }
 
195
    return (void *)newnode;
 
196
}
 
197
 
 
198
void util_ldap_search_node_free(util_ald_cache_t *cache, void *n)
 
199
{
 
200
    int i = 0;
 
201
    util_search_node_t *node = n;
 
202
    int k = node->numvals;
 
203
 
 
204
    if (node->vals) {
 
205
        for (;k;k--,i++) {
 
206
            if (node->vals[i]) {
 
207
                util_ald_free(cache, node->vals[i]);
 
208
            }
 
209
        }
 
210
        util_ald_free(cache, node->vals);
 
211
    }
 
212
    util_ald_free(cache, node->username);
 
213
    util_ald_free(cache, node->dn);
 
214
    util_ald_free(cache, node->bindpw);
 
215
    util_ald_free(cache, node);
 
216
}
 
217
 
 
218
void util_ldap_search_node_display(request_rec *r, util_ald_cache_t *cache, void *n)
 
219
{
 
220
    util_search_node_t *node = n;
 
221
    char date_str[APR_CTIME_LEN+1];
 
222
 
 
223
    apr_ctime(date_str, node->lastbind);
 
224
 
 
225
    ap_rprintf(r,
 
226
               "<tr valign='top'>"
 
227
               "<td nowrap>%s</td>"
 
228
               "<td nowrap>%s</td>"
 
229
               "<td nowrap>%s</td>"
 
230
               "</tr>",
 
231
               node->username,
 
232
               node->dn,
 
233
               date_str);
 
234
}
 
235
 
 
236
/* ------------------------------------------------------------------ */
 
237
 
 
238
unsigned long util_ldap_compare_node_hash(void *n)
 
239
{
 
240
    util_compare_node_t *node = n;
 
241
    return util_ald_hash_string(3, node->dn, node->attrib, node->value);
 
242
}
 
243
 
 
244
int util_ldap_compare_node_compare(void *a, void *b)
 
245
{
 
246
    util_compare_node_t *na = a;
 
247
    util_compare_node_t *nb = b;
 
248
 
 
249
    return (strcmp(na->dn, nb->dn) == 0 &&
 
250
            strcmp(na->attrib, nb->attrib) == 0 &&
 
251
            strcmp(na->value, nb->value) == 0);
 
252
}
 
253
 
 
254
void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c)
 
255
{
 
256
    util_compare_node_t *n = c;
 
257
    util_compare_node_t *node = util_ald_alloc(cache, sizeof *node);
 
258
 
 
259
    if (node) {
 
260
        if (!(node->dn = util_ald_strdup(cache, n->dn)) ||
 
261
            !(node->attrib = util_ald_strdup(cache, n->attrib)) ||
 
262
            !(node->value = util_ald_strdup(cache, n->value))) {
 
263
            util_ldap_compare_node_free(cache, node);
 
264
            return NULL;
 
265
        }
 
266
        node->lastcompare = n->lastcompare;
 
267
        node->result = n->result;
 
268
        return node;
 
269
    }
 
270
    else {
 
271
        return NULL;
 
272
    }
 
273
}
 
274
 
 
275
void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n)
 
276
{
 
277
    util_compare_node_t *node = n;
 
278
    util_ald_free(cache, node->dn);
 
279
    util_ald_free(cache, node->attrib);
 
280
    util_ald_free(cache, node->value);
 
281
    util_ald_free(cache, node);
 
282
}
 
283
 
 
284
void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n)
 
285
{
 
286
    util_compare_node_t *node = n;
 
287
    char date_str[APR_CTIME_LEN+1];
 
288
    char *cmp_result;
 
289
 
 
290
    apr_ctime(date_str, node->lastcompare);
 
291
 
 
292
    if (node->result == LDAP_COMPARE_TRUE) {
 
293
        cmp_result = "LDAP_COMPARE_TRUE";
 
294
    }
 
295
    else if (node->result == LDAP_COMPARE_FALSE) {
 
296
        cmp_result = "LDAP_COMPARE_FALSE";
 
297
    }
 
298
    else {
 
299
        cmp_result = apr_itoa(r->pool, node->result);
 
300
    }
 
301
 
 
302
    ap_rprintf(r,
 
303
               "<tr valign='top'>"
 
304
               "<td nowrap>%s</td>"
 
305
               "<td nowrap>%s</td>"
 
306
               "<td nowrap>%s</td>"
 
307
               "<td nowrap>%s</td>"
 
308
               "<td nowrap>%s</td>"
 
309
               "</tr>",
 
310
               node->dn,
 
311
               node->attrib,
 
312
               node->value,
 
313
               date_str,
 
314
               cmp_result);
 
315
}
 
316
 
 
317
/* ------------------------------------------------------------------ */
 
318
 
 
319
unsigned long util_ldap_dn_compare_node_hash(void *n)
 
320
{
 
321
    util_dn_compare_node_t *node = n;
 
322
    return util_ald_hash_string(1, node->reqdn);
 
323
}
 
324
 
 
325
int util_ldap_dn_compare_node_compare(void *a, void *b)
 
326
{
 
327
    util_dn_compare_node_t *na = a;
 
328
    util_dn_compare_node_t *nb = b;
 
329
 
 
330
    return (strcmp(na->reqdn, nb->reqdn) == 0);
 
331
}
 
332
 
 
333
void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c)
 
334
{
 
335
    util_dn_compare_node_t *n = c;
 
336
    util_dn_compare_node_t *node = util_ald_alloc(cache, sizeof *node);
 
337
 
 
338
    if (node) {
 
339
        if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) ||
 
340
            !(node->dn = util_ald_strdup(cache, n->dn))) {
 
341
            util_ldap_dn_compare_node_free(cache, node);
 
342
            return NULL;
 
343
        }
 
344
        return node;
 
345
    }
 
346
    else {
 
347
        return NULL;
 
348
    }
 
349
}
 
350
 
 
351
void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n)
 
352
{
 
353
    util_dn_compare_node_t *node = n;
 
354
    util_ald_free(cache, node->reqdn);
 
355
    util_ald_free(cache, node->dn);
 
356
    util_ald_free(cache, node);
 
357
}
 
358
 
 
359
void util_ldap_dn_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n)
 
360
{
 
361
    util_dn_compare_node_t *node = n;
 
362
 
 
363
    ap_rprintf(r,
 
364
               "<tr valign='top'>"
 
365
               "<td nowrap>%s</td>"
 
366
               "<td nowrap>%s</td>"
 
367
               "</tr>",
 
368
               node->reqdn,
 
369
               node->dn);
 
370
}
 
371
 
 
372
 
 
373
/* ------------------------------------------------------------------ */
 
374
static apr_status_t util_ldap_cache_module_kill(void *data)
 
375
{
 
376
    util_ldap_state_t *st = data;
 
377
 
 
378
    util_ald_destroy_cache(st->util_ldap_cache);
 
379
#if APR_HAS_SHARED_MEMORY
 
380
    if (st->cache_rmm != NULL) {
 
381
        apr_rmm_destroy (st->cache_rmm);
 
382
        st->cache_rmm = NULL;
 
383
    }
 
384
    if (st->cache_shm != NULL) {
 
385
        apr_status_t result = apr_shm_destroy(st->cache_shm);
 
386
        st->cache_shm = NULL;
 
387
        return result;
 
388
    }
 
389
#endif
 
390
    return APR_SUCCESS;
 
391
}
 
392
 
 
393
apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
 
394
{
 
395
#if APR_HAS_SHARED_MEMORY
 
396
    apr_status_t result;
 
397
    apr_size_t size;
 
398
 
 
399
    if (st->cache_file) {
 
400
        /* Remove any existing shm segment with this name. */
 
401
        apr_shm_remove(st->cache_file, st->pool);
 
402
    }
 
403
 
 
404
    size = APR_ALIGN_DEFAULT(st->cache_bytes);
 
405
 
 
406
    result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool);
 
407
    if (result != APR_SUCCESS) {
 
408
        return result;
 
409
    }
 
410
 
 
411
    /* Determine the usable size of the shm segment. */
 
412
    size = apr_shm_size_get(st->cache_shm);
 
413
 
 
414
    /* This will create a rmm "handler" to get into the shared memory area */
 
415
    result = apr_rmm_init(&st->cache_rmm, NULL,
 
416
                          apr_shm_baseaddr_get(st->cache_shm), size,
 
417
                          st->pool);
 
418
    if (result != APR_SUCCESS) {
 
419
        return result;
 
420
    }
 
421
 
 
422
#endif
 
423
 
 
424
    apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null);
 
425
 
 
426
    st->util_ldap_cache =
 
427
        util_ald_create_cache(st,
 
428
                              st->search_cache_size,
 
429
                              util_ldap_url_node_hash,
 
430
                              util_ldap_url_node_compare,
 
431
                              util_ldap_url_node_copy,
 
432
                              util_ldap_url_node_free,
 
433
                              util_ldap_url_node_display);
 
434
    return APR_SUCCESS;
 
435
}
 
436
 
 
437
 
 
438
#endif /* APR_HAS_LDAP */