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

« back to all changes in this revision

Viewing changes to srclib/apr-util/ldap/apr_ldap_option.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
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * 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
/*  apr_ldap_option.c -- LDAP options
 
18
 *
 
19
 *  The LDAP SDK allows the getting and setting of options on an LDAP
 
20
 *  connection.
 
21
 *
 
22
 */
 
23
 
 
24
#include "apr.h"
 
25
#include "apu.h"
 
26
#include "apr_ldap.h"
 
27
#include "apr_errno.h"
 
28
#include "apr_pools.h"
 
29
#include "apr_strings.h"
 
30
#include "apr_tables.h"
 
31
 
 
32
#if APR_HAS_LDAP
 
33
 
 
34
static void option_set_cert(apr_pool_t *pool, LDAP *ldap, const void *invalue,
 
35
                           apr_ldap_err_t *result);
 
36
static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
 
37
                          apr_ldap_err_t *result);
 
38
 
 
39
/**
 
40
 * APR LDAP get option function
 
41
 *
 
42
 * This function gets option values from a given LDAP session if
 
43
 * one was specified.
 
44
 */
 
45
APU_DECLARE(int) apr_ldap_get_option(apr_pool_t *pool,
 
46
                                     LDAP *ldap,
 
47
                                     int option,
 
48
                                     void *outvalue,
 
49
                                     apr_ldap_err_t **result_err)
 
50
{
 
51
    apr_ldap_err_t *result;
 
52
 
 
53
    result = apr_pcalloc(pool, sizeof(apr_ldap_err_t));
 
54
    *result_err = result;
 
55
    if (!result) {
 
56
        return APR_ENOMEM;
 
57
    }
 
58
 
 
59
    /* get the option specified using the native LDAP function */
 
60
    result->rc = ldap_get_option(ldap, option, outvalue);
 
61
 
 
62
    /* handle the error case */
 
63
    if (result->rc != LDAP_SUCCESS) {
 
64
        result->msg = ldap_err2string(result-> rc);
 
65
        result->reason = apr_pstrdup(pool, "LDAP: Could not get an option");
 
66
        return APR_EGENERAL;
 
67
    }
 
68
 
 
69
    return APR_SUCCESS;
 
70
 
 
71
 
72
 
 
73
/**
 
74
 * APR LDAP set option function
 
75
 *
 
76
 * This function sets option values to a given LDAP session if
 
77
 * one was specified.
 
78
 *
 
79
 * Where an option is not supported by an LDAP toolkit, this function
 
80
 * will try and apply legacy functions to achieve the same effect,
 
81
 * depending on the platform.
 
82
 */
 
83
APU_DECLARE(int) apr_ldap_set_option(apr_pool_t *pool,
 
84
                                     LDAP *ldap,
 
85
                                     int option,
 
86
                                     const void *invalue,
 
87
                                     apr_ldap_err_t **result_err)
 
88
{
 
89
    apr_ldap_err_t *result;
 
90
 
 
91
    result = apr_pcalloc(pool, sizeof(apr_ldap_err_t));
 
92
    *result_err = result;
 
93
    if (!result) {
 
94
        return APR_ENOMEM;
 
95
    }
 
96
 
 
97
    switch (option) {
 
98
    case APR_LDAP_OPT_TLS_CERT:
 
99
        option_set_cert(pool, ldap, invalue, result);
 
100
        break;
 
101
 
 
102
    case APR_LDAP_OPT_TLS:
 
103
        option_set_tls(pool, ldap, invalue, result);
 
104
        break;
 
105
        
 
106
    case APR_LDAP_OPT_VERIFY_CERT:
 
107
#if APR_HAS_NETSCAPE_LDAPSDK || APR_HAS_SOLARIS_LDAPSDK || APR_HAS_MOZILLA_LDAPSK
 
108
        result->reason = "LDAP: Verify certificate not yet supported by APR on the "
 
109
                         "Netscape, Solaris or Mozilla LDAP SDKs";
 
110
        result->rc = -1;
 
111
        return APR_EGENERAL;
 
112
#endif
 
113
#if APR_HAS_NOVELL_LDAPSDK
 
114
        if (*((int*)invalue)) {
 
115
            result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
 
116
        }
 
117
        else {
 
118
            result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
 
119
        }
 
120
#endif
 
121
#if APR_HAS_OPENLDAP_LDAPSDK
 
122
#ifdef LDAP_OPT_X_TLS
 
123
                /* This is not a per-connection setting so just pass NULL for the
 
124
                   Ldap connection handle */
 
125
        if (*((int*)invalue)) {
 
126
                        int i = LDAP_OPT_X_TLS_DEMAND;
 
127
                        result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
 
128
        }
 
129
        else {
 
130
                        int i = LDAP_OPT_X_TLS_NEVER;
 
131
                        result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
 
132
        }
 
133
#else
 
134
        result->reason = "LDAP: SSL/TLS not yet supported by APR on this "
 
135
                         "version of the OpenLDAP toolkit";
 
136
        result->rc = -1;
 
137
        return APR_EGENERAL;
 
138
#endif
 
139
#endif
 
140
 
 
141
        /* handle the error case */
 
142
        if (result->rc != LDAP_SUCCESS) {
 
143
            result->msg = ldap_err2string(result->rc);
 
144
            result->reason = "LDAP: Could not set verify mode";
 
145
        }
 
146
        break;
 
147
        
 
148
    default:
 
149
        /* set the option specified using the native LDAP function */
 
150
        result->rc = ldap_set_option(ldap, option, (void *)invalue);
 
151
        
 
152
        /* handle the error case */
 
153
        if (result->rc != LDAP_SUCCESS) {
 
154
            result->msg = ldap_err2string(result->rc);
 
155
            result->reason = "LDAP: Could not set an option";
 
156
        }
 
157
        break;
 
158
    }
 
159
 
 
160
    /* handle the error case */
 
161
    if (result->rc != LDAP_SUCCESS) {
 
162
        return APR_EGENERAL;
 
163
    }
 
164
 
 
165
    return APR_SUCCESS;
 
166
 
 
167
}
 
168
 
 
169
/**
 
170
 * Handle APR_LDAP_OPT_TLS
 
171
 *
 
172
 * This function sets the type of TLS to be applied to this connection.
 
173
 * The options are:
 
174
 * APR_LDAP_NONE: no encryption
 
175
 * APR_LDAP_SSL: SSL encryption (ldaps://)
 
176
 * APR_LDAP_STARTTLS: STARTTLS encryption
 
177
 * APR_LDAP_STOPTLS: Stop existing TLS connecttion
 
178
 */
 
179
static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
 
180
                          apr_ldap_err_t *result)
 
181
{
 
182
    int tls = * (const int *)invalue;
 
183
 
 
184
#if APR_HAS_LDAP_SSL /* compiled with ssl support */
 
185
 
 
186
    /* Netscape/Mozilla/Solaris SDK */
 
187
#if APR_HAS_NETSCAPE_LDAPSDK || APR_HAS_SOLARIS_LDAPSDK || APR_HAS_MOZILLA_LDAPSK
 
188
#if APR_HAS_LDAPSSL_INSTALL_ROUTINES
 
189
    if (tls == APR_LDAP_SSL) {
 
190
        result->rc = ldapssl_install_routines(ldap);
 
191
#ifdef LDAP_OPT_SSL
 
192
        /* apparently Netscape and Mozilla need this too, Solaris doesn't */
 
193
        if (result->rc == LDAP_SUCCESS) {
 
194
            result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
 
195
        }
 
196
#endif
 
197
        if (result->rc != LDAP_SUCCESS) {
 
198
            result->msg = ldap_err2string(result->rc);
 
199
            result->reason = "LDAP: Could not switch SSL on for this "
 
200
                             "connection.";
 
201
        }
 
202
    }
 
203
    else if (tls == APR_LDAP_STARTTLS) {
 
204
        result->reason = "LDAP: STARTTLS is not supported by the "
 
205
                         "Netscape/Mozilla/Solaris SDK";
 
206
        result->rc = -1;
 
207
    }
 
208
    else if (tls == APR_LDAP_STOPTLS) {
 
209
        result->reason = "LDAP: STOPTLS is not supported by the "
 
210
                         "Netscape/Mozilla/Solaris SDK";
 
211
        result->rc = -1;
 
212
    }
 
213
#else
 
214
    if (tls != APR_LDAP_NONE) {
 
215
        result->reason = "LDAP: SSL/TLS is not supported by this version "
 
216
                         "of the Netscape/Mozilla/Solaris SDK";
 
217
        result->rc = -1;
 
218
    }
 
219
#endif
 
220
#endif
 
221
 
 
222
    /* Novell SDK */
 
223
#if APR_HAS_NOVELL_LDAPSDK
 
224
    /* ldapssl_install_routines(ldap)
 
225
     * Behavior is unpredictable when other LDAP functions are called
 
226
     * between the ldap_init function and the ldapssl_install_routines
 
227
     * function.
 
228
     * 
 
229
     * STARTTLS is supported by the ldap_start_tls_s() method
 
230
     */
 
231
    if (tls == APR_LDAP_SSL) {
 
232
        result->rc = ldapssl_install_routines(ldap);
 
233
        if (result->rc != LDAP_SUCCESS) {
 
234
            result->msg = ldap_err2string(result->rc);
 
235
            result->reason = "LDAP: Could not switch SSL on for this "
 
236
                             "connection.";
 
237
        }
 
238
    }
 
239
    if (tls == APR_LDAP_STARTTLS) {
 
240
        result->rc = ldapssl_start_tls(ldap);
 
241
        if (result->rc != LDAP_SUCCESS) {
 
242
            result->msg = ldap_err2string(result->rc);
 
243
            result->reason = "LDAP: Could not start TLS on this connection";
 
244
        }
 
245
    }
 
246
    else if (tls == APR_LDAP_STOPTLS) {
 
247
        result->rc = ldapssl_stop_tls(ldap);
 
248
        if (result->rc != LDAP_SUCCESS) {
 
249
            result->msg = ldap_err2string(result->rc);
 
250
            result->reason = "LDAP: Could not stop TLS on this connection";
 
251
        }
 
252
    }
 
253
#endif
 
254
 
 
255
    /* OpenLDAP SDK */
 
256
#if APR_HAS_OPENLDAP_LDAPSDK
 
257
#ifdef LDAP_OPT_X_TLS
 
258
    if (tls == APR_LDAP_SSL) {
 
259
        int SSLmode = LDAP_OPT_X_TLS_HARD;
 
260
        result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, &SSLmode);
 
261
        if (result->rc != LDAP_SUCCESS) {
 
262
            result->reason = "LDAP: ldap_set_option failed. "
 
263
                             "Could not set LDAP_OPT_X_TLS to "
 
264
                             "LDAP_OPT_X_TLS_HARD";
 
265
            result->msg = ldap_err2string(result->rc);
 
266
        }   
 
267
    }
 
268
    else if (tls == APR_LDAP_STARTTLS) {
 
269
        result->rc = ldap_start_tls_s(ldap, NULL, NULL);
 
270
        if (result->rc != LDAP_SUCCESS) {
 
271
            result->reason = "LDAP: ldap_start_tls_s() failed";
 
272
            result->msg = ldap_err2string(result->rc);
 
273
        }
 
274
    }
 
275
    else if (tls == APR_LDAP_STOPTLS) {
 
276
        result->reason = "LDAP: STOPTLS is not supported by the "
 
277
                         "OpenLDAP SDK";
 
278
        result->rc = -1;
 
279
    }
 
280
#else
 
281
    if (tls != APR_LDAP_NONE) {
 
282
        result->reason = "LDAP: SSL/TLS not yet supported by APR on this "
 
283
                         "version of the OpenLDAP toolkit";
 
284
        result->rc = -1;
 
285
    }
 
286
#endif
 
287
#endif
 
288
 
 
289
    /* Microsoft SDK */
 
290
#if APR_HAS_MICROSOFT_LDAPSDK
 
291
    if (tls == APR_LDAP_NONE) {
 
292
        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_OFF);
 
293
        if (result->rc != LDAP_SUCCESS) {
 
294
            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL off "
 
295
                             "failed.";
 
296
            result->msg = ldap_err2string(result->rc);
 
297
        }
 
298
    }
 
299
    else if (tls == APR_LDAP_SSL) {
 
300
        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
 
301
        if (result->rc != LDAP_SUCCESS) {
 
302
            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL on "
 
303
                             "failed.";
 
304
            result->msg = ldap_err2string(result->rc);
 
305
        }
 
306
    }
 
307
#if APR_HAS_LDAP_START_TLS_S
 
308
    else if (tls == APR_LDAP_STARTTLS) {
 
309
        result->rc = ldap_start_tls_s(ldap, NULL, NULL, NULL, NULL);
 
310
        if (result->rc != LDAP_SUCCESS) {
 
311
            result->reason = "LDAP: ldap_start_tls_s() failed";
 
312
            result->msg = ldap_err2string(result->rc);
 
313
        }
 
314
    }
 
315
    else if (tls == APR_LDAP_STOPTLS) {
 
316
        result->rc = ldap_stop_tls_s(ldap);
 
317
        if (result->rc != LDAP_SUCCESS) {
 
318
            result->reason = "LDAP: ldap_stop_tls_s() failed";
 
319
            result->msg = ldap_err2string(result->rc);
 
320
        }
 
321
    }
 
322
#endif
 
323
#endif
 
324
 
 
325
#if APR_HAS_OTHER_LDAPSDK
 
326
    if (tls != APR_LDAP_NONE) {
 
327
        result->reason = "LDAP: SSL/TLS is currently not supported by "
 
328
                         "APR on this LDAP SDK";
 
329
        result->rc = -1;
 
330
    }
 
331
#endif
 
332
 
 
333
#endif /* APR_HAS_LDAP_SSL */
 
334
 
 
335
}
 
336
 
 
337
/**
 
338
 * Handle APR_LDAP_OPT_TLS_CACERTFILE
 
339
 *
 
340
 * This function sets the CA certificate for further SSL/TLS connections.
 
341
 *
 
342
 * The file provided are in different formats depending on the toolkit used:
 
343
 *
 
344
 * Netscape: cert7.db file
 
345
 * Novell: PEM or DER
 
346
 * OpenLDAP: PEM (others supported?)
 
347
 * Microsoft: unknown
 
348
 * Solaris: unknown
 
349
 */
 
350
static void option_set_cert(apr_pool_t *pool, LDAP *ldap,
 
351
                           const void *invalue, apr_ldap_err_t *result)
 
352
{
 
353
    apr_array_header_t *certs = (apr_array_header_t *)invalue;
 
354
    struct apr_ldap_opt_tls_cert_t *ents = (struct apr_ldap_opt_tls_cert_t *)certs->elts;
 
355
    int i = 0;
 
356
 
 
357
#if APR_HAS_LDAP_SSL
 
358
 
 
359
    /* Netscape/Mozilla/Solaris SDK */
 
360
#if APR_HAS_NETSCAPE_LDAPSDK || APR_HAS_SOLARIS_LDAPSDK || APR_HAS_MOZILLA_LDAPSDK
 
361
#if APR_HAS_LDAPSSL_CLIENT_INIT
 
362
    const char *nickname = NULL;
 
363
    const char *secmod = NULL;
 
364
    const char *key3db = NULL;
 
365
    const char *cert7db = NULL;
 
366
    const char *password = NULL;
 
367
 
 
368
    /* set up cert7.db, key3.db and secmod parameters */
 
369
    for (i = 0; i < certs->nelts; i++) {
 
370
        switch (ents[i].type) {
 
371
        case APR_LDAP_CA_TYPE_CERT7_DB:
 
372
            cert7db = ents[i].path;
 
373
            break;
 
374
        case APR_LDAP_CA_TYPE_SECMOD:
 
375
            secmod = ents[i].path;
 
376
            break;
 
377
        case APR_LDAP_CERT_TYPE_KEY3_DB:
 
378
            key3db = ents[i].path;
 
379
            break;
 
380
        case APR_LDAP_CERT_TYPE_NICKNAME:
 
381
            nickname = ents[i].path;
 
382
            password = ents[i].password;
 
383
            break;
 
384
        default:
 
385
            result->rc = -1;
 
386
            result->reason = "LDAP: The Netscape/Mozilla LDAP SDK only "
 
387
                "understands the CERT7, KEY3 and SECMOD "
 
388
                "file types.";
 
389
            break;
 
390
        }
 
391
        if (result->rc != LDAP_SUCCESS) {
 
392
            break;
 
393
        }
 
394
    }
 
395
 
 
396
    /* actually set the certificate parameters */
 
397
    if (result->rc == LDAP_SUCCESS) {
 
398
        if (nickname) {
 
399
            result->rc = ldapssl_enable_clientauth(ldap, "",
 
400
                                                   (char *)password,
 
401
                                                   (char *)nickname);
 
402
            if (result->rc != LDAP_SUCCESS) {
 
403
                result->reason = "LDAP: could not set client certificate: "
 
404
                                 "ldapssl_enable_clientauth() failed.";
 
405
                result->msg = ldap_err2string(result->rc);
 
406
            }
 
407
        }
 
408
        else if (secmod) {
 
409
            result->rc = ldapssl_advclientauth_init(cert7db, NULL,
 
410
                                                    key3db ? 1 : 0, key3db, NULL,
 
411
                                                    1, secmod, LDAPSSL_AUTH_CNCHECK);
 
412
            if (result->rc != LDAP_SUCCESS) {
 
413
                result->reason = "LDAP: ldapssl_advclientauth_init() failed.";
 
414
                result->msg = ldap_err2string(result->rc);
 
415
            }
 
416
        }
 
417
        else if (key3db) {
 
418
            result->rc = ldapssl_clientauth_init(cert7db, NULL,
 
419
                                                    1, key3db, NULL);
 
420
            if (result->rc != LDAP_SUCCESS) {
 
421
                result->reason = "LDAP: ldapssl_clientauth_init() failed.";
 
422
                result->msg = ldap_err2string(result->rc);
 
423
            }
 
424
        }
 
425
        else {
 
426
            result->rc = ldapssl_client_init(cert7db, NULL);
 
427
            if (result->rc != LDAP_SUCCESS) {
 
428
                result->reason = "LDAP: ldapssl_client_init() failed.";
 
429
                result->msg = ldap_err2string(result->rc);
 
430
            }
 
431
        }
 
432
    }
 
433
#else
 
434
    result->reason = "LDAP: SSL/TLS ldapssl_client_init() function not "
 
435
                     "supported by this Netscape/Mozilla/Solaris SDK. "
 
436
                     "Certificate authority file not set";
 
437
    result->rc = -1;
 
438
#endif
 
439
#endif
 
440
 
 
441
    /* Novell SDK */
 
442
#if APR_HAS_NOVELL_LDAPSDK
 
443
#if APR_HAS_LDAPSSL_CLIENT_INIT && APR_HAS_LDAPSSL_ADD_TRUSTED_CERT && APR_HAS_LDAPSSL_CLIENT_DEINIT
 
444
    /* The Novell library cannot support per connection certificates. Error
 
445
     * out if the ldap handle is provided.
 
446
     */
 
447
    if (ldap) {
 
448
        result->rc = -1;
 
449
        result->reason = "LDAP: The Novell LDAP SDK cannot support the setting "
 
450
                         "of certificates or keys on a per connection basis.";
 
451
    }
 
452
    /* Novell's library needs to be initialised first */
 
453
    else {
 
454
        result->rc = ldapssl_client_init(NULL, NULL);
 
455
        if (result->rc != LDAP_SUCCESS) {
 
456
            result->msg = ldap_err2string(result-> rc);
 
457
            result->reason = apr_pstrdup(pool, "LDAP: Could not "
 
458
                                         "initialize SSL");
 
459
        }
 
460
    }
 
461
    /* set one or more certificates */
 
462
    for (i = 0; LDAP_SUCCESS == result->rc && i < certs->nelts; i++) {
 
463
        /* Novell SDK supports DER or BASE64 files. */
 
464
        switch (ents[i].type) {
 
465
        case APR_LDAP_CA_TYPE_DER:
 
466
            result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
 
467
                                                  LDAPSSL_CERT_FILETYPE_DER);
 
468
            result->msg = ldap_err2string(result->rc);
 
469
            break;
 
470
        case APR_LDAP_CA_TYPE_BASE64:
 
471
            result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
 
472
                                                  LDAPSSL_CERT_FILETYPE_B64);
 
473
            result->msg = ldap_err2string(result->rc);
 
474
            break;
 
475
        case APR_LDAP_CERT_TYPE_DER:
 
476
            result->rc = ldapssl_set_client_cert((void *)ents[i].path,
 
477
                                                 LDAPSSL_CERT_FILETYPE_DER,
 
478
                                                 (void*)ents[i].password);
 
479
            result->msg = ldap_err2string(result->rc);
 
480
            break;
 
481
        case APR_LDAP_CERT_TYPE_BASE64: 
 
482
            result->rc = ldapssl_set_client_cert((void *)ents[i].path,
 
483
                                                 LDAPSSL_CERT_FILETYPE_B64,
 
484
                                                 (void*)ents[i].password);
 
485
            result->msg = ldap_err2string(result->rc);
 
486
            break;
 
487
        case APR_LDAP_CERT_TYPE_PFX: 
 
488
            result->rc = ldapssl_set_client_cert((void *)ents[i].path,
 
489
                                                 LDAPSSL_FILETYPE_P12,
 
490
                                                 (void*)ents[i].password);
 
491
            result->msg = ldap_err2string(result->rc);
 
492
            break;
 
493
        case APR_LDAP_KEY_TYPE_DER:
 
494
            result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
 
495
                                                        LDAPSSL_CERT_FILETYPE_DER,
 
496
                                                        (void*)ents[i].password);
 
497
            result->msg = ldap_err2string(result->rc);
 
498
            break;
 
499
        case APR_LDAP_KEY_TYPE_BASE64:
 
500
            result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
 
501
                                                        LDAPSSL_CERT_FILETYPE_B64,
 
502
                                                        (void*)ents[i].password);
 
503
            result->msg = ldap_err2string(result->rc);
 
504
            break;
 
505
        case APR_LDAP_KEY_TYPE_PFX:
 
506
            result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
 
507
                                                        LDAPSSL_FILETYPE_P12,
 
508
                                                        (void*)ents[i].password);
 
509
            result->msg = ldap_err2string(result->rc);
 
510
            break;
 
511
        default:
 
512
            result->rc = -1;
 
513
            result->reason = "LDAP: The Novell LDAP SDK only understands the "
 
514
                "DER and PEM (BASE64) file types.";
 
515
            break;
 
516
        }
 
517
        if (result->rc != LDAP_SUCCESS) {
 
518
            break;
 
519
        }
 
520
    }
 
521
#else
 
522
    result->reason = "LDAP: ldapssl_client_init(), "
 
523
                     "ldapssl_add_trusted_cert() or "
 
524
                     "ldapssl_client_deinit() functions not supported "
 
525
                     "by this Novell SDK. Certificate authority file "
 
526
                     "not set";
 
527
    result->rc = -1;
 
528
#endif
 
529
#endif
 
530
 
 
531
    /* OpenLDAP SDK */
 
532
#if APR_HAS_OPENLDAP_LDAPSDK
 
533
#ifdef LDAP_OPT_X_TLS_CACERTFILE
 
534
    /* set one or more certificates */
 
535
    /* FIXME: make it support setting directories as well as files */
 
536
    for (i = 0; i < certs->nelts; i++) {
 
537
        /* OpenLDAP SDK supports BASE64 files. */
 
538
        switch (ents[i].type) {
 
539
        case APR_LDAP_CA_TYPE_BASE64:
 
540
            result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTFILE,
 
541
                                         (void *)ents[i].path);
 
542
            result->msg = ldap_err2string(result->rc);
 
543
            break;
 
544
        case APR_LDAP_CERT_TYPE_BASE64:
 
545
            result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CERTFILE,
 
546
                                         (void *)ents[i].path);
 
547
            result->msg = ldap_err2string(result->rc);
 
548
            break;
 
549
        case APR_LDAP_KEY_TYPE_BASE64:
 
550
            result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_KEYFILE,
 
551
                                         (void *)ents[i].path);
 
552
            result->msg = ldap_err2string(result->rc);
 
553
            break;
 
554
        default:
 
555
            result->rc = -1;
 
556
            result->reason = "LDAP: The OpenLDAP SDK only understands the "
 
557
                "PEM (BASE64) file type.";
 
558
            break;
 
559
        }
 
560
        if (result->rc != LDAP_SUCCESS) {
 
561
            break;
 
562
        }
 
563
    }
 
564
#else
 
565
    result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
 
566
                     "defined by this OpenLDAP SDK. Certificate "
 
567
                     "authority file not set";
 
568
    result->rc = -1;
 
569
#endif
 
570
#endif
 
571
 
 
572
    /* Microsoft SDK */
 
573
#if APR_HAS_MICROSOFT_LDAPSDK
 
574
    /* Microsoft SDK use the registry certificate store - error out
 
575
     * here with a message explaining this. */
 
576
    result->reason = "LDAP: CA certificates cannot be set using this method, "
 
577
                     "as they are stored in the registry instead.";
 
578
    result->rc = -1;
 
579
#endif
 
580
 
 
581
    /* SDK not recognised */
 
582
#if APR_HAS_OTHER_LDAPSDK
 
583
    result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
 
584
                     "defined by this LDAP SDK. Certificate "
 
585
                     "authority file not set";
 
586
    result->rc = -1;
 
587
#endif
 
588
 
 
589
#else  /* not compiled with SSL Support */
 
590
    result->reason = "LDAP: Attempt to set certificate(s) failed. "
 
591
                     "Not built with SSL support";
 
592
    result->rc = -1;
 
593
#endif /* APR_HAS_LDAP_SSL */
 
594
 
 
595
}
 
596
 
 
597
#endif /* APR_HAS_LDAP */
 
598