~ubuntu-dev/ubuntu/lucid/dovecot/lucid-201002110912

« back to all changes in this revision

Viewing changes to src/auth/db-ldap.c

  • Committer: Bazaar Package Importer
  • Author(s): CHuck Short, Chuck Short
  • Date: 2009-11-06 00:47:29 UTC
  • mfrom: (4.1.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091106004729-i39n7v9e7d4h51f6
Tags: 1:1.2.6-1ubuntu1
* Merge from debian testing, remaining changes:
  Add new binary pkg dovecot-postfix that integrates postfix and dovecot
  automatically: (LP: #164837)
  + debian/control:
    - add new binary with short description
    - set Architecture all for dovecot-postfix (LP: #329878)
  + debian/dovecot-postfix.postinst:
    - create initial certificate symlinks to snakeoil.
    - set up postfix with postconf to:
      - use Maildir/ as the default mailbox.
      - use dovecot as the sasl authentication server.
      - use dovecot LDA (deliver).
      - use tls for smtp{d} services.
    - fix certificates paths in postfix' main.cf
    - add reject_unauth_destination to postfix' recipient restrictions
    - add reject_unknown_sender_domain to postfix' sender restrictions
    - rename configuration name on remove, delete on purge
    - restart dovecot after linking certificates
    - handle use case when postfix is unconfigurated
   + debian/dovecot-postfix.dirs: create backup directory for postfix's configuration
   + restart postfix and dovecot.
   + debian/dovecot-postfix.postrm:
     - remove all dovecot related configuration from postfix.
     - restart postfix and dovecot.
   + debian/dovecot-common.init:
     - check if /etc/dovecot/dovecot-postfix.conf exists and use it
       as the configuration file if so.
   + debian/patches/warning-ubuntu-postfix.dpatch
     - add warning about dovecot-postfix.conf in dovecot default 
       configuration file
   + debian/patches/dovecot-postfix.conf.diff:
     - Ubuntu server custom changes to the default dovecot configuration for
       better interfation with postfix
     - enable sieve plugin
   + debian/patches/dovecot-postfix.conf.diff:
     + Ubuntu server custom changes to the default dovecot configuration for
       better integration with postfix:
       - enable imap, pop3, imaps, pop3s and managesieve by default.
       - enable dovecot LDA (deliver).
       - enable SASL auth socket in postfix private directory.
   + debian/rules:
     - copy, patch and install dovecot-postfix.conf in /etc/dovecot/.
     - build architecure independent packages too
   + Use Snakeoil SSL certificates by default.
     - debian/control: Depend on ssl-cert.
     - debian/patches/ssl-cert-snakeoil.dpatch: Change default SSL cert
       paths to snakeoil.
     - debian/dovecot-common.postinst: Relax grep for SSL_* a bit.
   + Add autopkgtest to debian/tests/*.
   + Fast TearDown: Update the lsb init header to not stop in level 6.
   + Add ufw integration:
     - Created debian/dovecot-common.ufw.profile.
     - debian/rules:
       + install profile
     - debian/control:
       + Suggest ufw
   + debian/{control,rules}: enable PIE hardening.
   + dovecot-imapd, dovecot-pop3: Replaces dovecot-common (<< 1:1.1). LP: #254721
   + debian/control:
     - Update Vcs-* headers.
   + debian/rules:
     - Create emtpy stamp.h.in files in dovecot-sieve/ and dovecot-managesieve/
       if they're not there since empty files are not included in the diff.gz 
       file.
   + Add SMTP-AUTH support for Outlook (login auth mechanism)
   + Dropped:
     - debian/patches/security-CVE-2009-3235: Applied upstream.
     - debian/patches/fix-pop3-assertion.dpatch: Applied upstream.
     - dovecot-sieve and dovecot-managesieve: Use the debian patches instead.

  [Chuck Short]
  - Updated dovecot-sieve to 0.1.13.
  - Updated dovecot-managesieve to 0.11.9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
#include "common.h"
4
4
 
5
 
#if defined(PASSDB_LDAP) || defined(USERDB_LDAP)
 
5
#if defined(BUILTIN_LDAP) || defined(PLUGIN_BUILD)
6
6
 
7
7
#include "network.h"
8
8
#include "ioloop.h"
130
130
        MEMBER(deref) "never",
131
131
        MEMBER(scope) "subtree",
132
132
        MEMBER(base) NULL,
133
 
        MEMBER(ldap_version) 2,
 
133
        MEMBER(ldap_version) 3,
134
134
        MEMBER(debug_level) "0",
135
135
        MEMBER(ldaprc_path) "",
136
136
        MEMBER(user_attrs) "homeDirectory=home,uidNumber=uid,gidNumber=gid",
205
205
 
206
206
const char *ldap_get_error(struct ldap_connection *conn)
207
207
{
208
 
        return ldap_err2string(ldap_get_errno(conn));
 
208
        const char *ret;
 
209
        char *str = NULL;
 
210
 
 
211
        ret = ldap_err2string(ldap_get_errno(conn));
 
212
 
 
213
        ldap_get_option(conn->ld, LDAP_OPT_ERROR_STRING, (void *)&str);
 
214
        if (str != NULL) {
 
215
                ret = t_strconcat(ret, ", ", str, NULL);
 
216
                ldap_memfree(str);
 
217
        }
 
218
        ldap_set_option(conn->ld, LDAP_OPT_ERROR_STRING, NULL);
 
219
        return ret;
209
220
}
210
221
 
211
222
static void ldap_conn_reconnect(struct ldap_connection *conn)
311
322
static bool db_ldap_request_queue_next(struct ldap_connection *conn)
312
323
{
313
324
        struct ldap_request *const *requestp, *request;
314
 
        unsigned int queue_size = aqueue_count(conn->request_queue);
315
325
        int ret = -1;
316
326
 
317
 
        if (conn->pending_count == queue_size) {
 
327
        if (conn->pending_count == aqueue_count(conn->request_queue)) {
318
328
                /* no non-pending requests */
319
329
                return FALSE;
320
330
        }
321
 
        if (queue_size > DB_LDAP_MAX_PENDING_REQUESTS) {
 
331
        if (conn->pending_count > DB_LDAP_MAX_PENDING_REQUESTS) {
322
332
                /* wait until server has replied to some requests */
323
333
                return FALSE;
324
334
        }
380
390
        }
381
391
}
382
392
 
 
393
static bool
 
394
db_ldap_check_limits(struct ldap_connection *conn, struct ldap_request *request)
 
395
{
 
396
        struct ldap_request *const *first_requestp;
 
397
        unsigned int count;
 
398
        time_t secs_diff;
 
399
 
 
400
        count = aqueue_count(conn->request_queue);
 
401
        if (count == 0)
 
402
                return TRUE;
 
403
 
 
404
        first_requestp = array_idx(&conn->request_array,
 
405
                                   aqueue_idx(conn->request_queue, 0));
 
406
        secs_diff = ioloop_time - (*first_requestp)->create_time;
 
407
        if (secs_diff > DB_LDAP_REQUEST_LOST_TIMEOUT_SECS) {
 
408
                auth_request_log_error(request->auth_request, "ldap",
 
409
                        "Connection appears to be hanging, reconnecting");
 
410
                ldap_conn_reconnect(conn);
 
411
                return TRUE;
 
412
        }
 
413
        if (conn->request_queue->full && count >= DB_LDAP_MAX_QUEUE_SIZE) {
 
414
                /* Queue is full already, fail this request */
 
415
                auth_request_log_error(request->auth_request, "ldap",
 
416
                        "Request queue is full (oldest added %d secs ago)",
 
417
                        (int)secs_diff);
 
418
                return FALSE;
 
419
        }
 
420
        return TRUE;
 
421
}
 
422
 
383
423
void db_ldap_request(struct ldap_connection *conn,
384
424
                     struct ldap_request *request)
385
425
{
388
428
        request->msgid = -1;
389
429
        request->create_time = ioloop_time;
390
430
 
391
 
        if (conn->request_queue->full &&
392
 
            aqueue_count(conn->request_queue) >= DB_LDAP_MAX_QUEUE_SIZE) {
393
 
                /* Queue is full already, fail this request */
394
 
                struct ldap_request *const *first_requestp;
395
 
 
396
 
                first_requestp = array_idx(&conn->request_array,
397
 
                                           aqueue_idx(conn->request_queue, 0));
398
 
                auth_request_log_error(request->auth_request, "ldap",
399
 
                        "Request queue is full (oldest added %d secs ago)",
400
 
                        (int)(time(NULL) - (*first_requestp)->create_time));
 
431
        if (!db_ldap_check_limits(conn, request)) {
401
432
                request->callback(conn, request, NULL);
402
433
                return;
403
434
        }
551
582
{
552
583
        struct timeval timeout;
553
584
        LDAPMessage *res;
 
585
        time_t prev_reply_diff;
554
586
        int ret;
555
587
 
556
588
        for (;;) {
572
604
                db_ldap_handle_result(conn, res);
573
605
                ldap_msgfree(res);
574
606
        }
 
607
        prev_reply_diff = ioloop_time - conn->last_reply_stamp;
575
608
        conn->last_reply_stamp = ioloop_time;
576
609
 
577
610
        if (ret == 0) {
582
615
                i_error("LDAP: ldap_result() failed: %s", ldap_get_error(conn));
583
616
                ldap_conn_reconnect(conn);
584
617
        } else if (aqueue_count(conn->request_queue) > 0 ||
585
 
                   ioloop_time - conn->last_reply_stamp <
586
 
                                                DB_LDAP_IDLE_RECONNECT_SECS) {
 
618
                   prev_reply_diff < DB_LDAP_IDLE_RECONNECT_SECS) {
587
619
                i_error("LDAP: Connection lost to LDAP server, reconnecting");
588
620
                ldap_conn_reconnect(conn);
589
621
        } else {
924
956
 
925
957
                if (*name != '\0' &&
926
958
                    (skip_attr == NULL || strcmp(skip_attr, value) != 0)) {
927
 
                        hash_insert(attr_map, name, value);
 
959
                        if (hash_table_lookup(attr_map, name) != NULL) {
 
960
                                i_fatal("ldap: LDAP attribute '%s' used multiple times. This is currently unsupported.",
 
961
                                        name);
 
962
                        }
 
963
                        hash_table_insert(attr_map, name, value);
928
964
                        (*attr_names_r)[j++] = name;
929
965
                }
930
966
        }
931
967
        if (str_len(static_data) > 0) {
932
 
                hash_insert(attr_map, "",
933
 
                            p_strdup(conn->pool, str_c(static_data)));
 
968
                hash_table_insert(attr_map, "",
 
969
                                  p_strdup(conn->pool, str_c(static_data)));
934
970
        }
935
971
}
936
972
 
993
1029
        ctx->auth_request = auth_request;
994
1030
        ctx->attr_map = attr_map;
995
1031
 
996
 
        static_data = hash_lookup(attr_map, "");
 
1032
        static_data = hash_table_lookup(attr_map, "");
997
1033
        if (static_data != NULL) {
998
1034
                const struct var_expand_table *table;
999
1035
                string_t *str;
1030
1066
static void
1031
1067
db_ldap_result_change_attr(struct db_ldap_result_iterate_context *ctx)
1032
1068
{
1033
 
        ctx->name = hash_lookup(ctx->attr_map, ctx->attr);
 
1069
        ctx->name = hash_table_lookup(ctx->attr_map, ctx->attr);
1034
1070
        ctx->template = NULL;
1035
1071
 
1036
1072
        if (ctx->debug != NULL) {
1267
1303
        aqueue_deinit(&conn->request_queue);
1268
1304
 
1269
1305
        if (conn->pass_attr_map != NULL)
1270
 
                hash_destroy(&conn->pass_attr_map);
 
1306
                hash_table_destroy(&conn->pass_attr_map);
1271
1307
        if (conn->user_attr_map != NULL)
1272
 
                hash_destroy(&conn->user_attr_map);
 
1308
                hash_table_destroy(&conn->user_attr_map);
1273
1309
        pool_unref(&conn->pool);
1274
1310
}
1275
1311
 
1276
1312
#ifndef BUILTIN_LDAP
1277
1313
/* Building a plugin */
1278
 
extern struct passdb_module_interface passdb_ldap;
1279
 
extern struct userdb_module_interface userdb_ldap;
 
1314
extern struct passdb_module_interface passdb_ldap_plugin;
 
1315
extern struct userdb_module_interface userdb_ldap_plugin;
1280
1316
 
1281
1317
void authdb_ldap_init(void);
1282
1318
void authdb_ldap_deinit(void);
1283
1319
 
1284
1320
void authdb_ldap_init(void)
1285
1321
{
1286
 
        passdb_register_module(&passdb_ldap);
1287
 
        userdb_register_module(&userdb_ldap);
 
1322
        passdb_register_module(&passdb_ldap_plugin);
 
1323
        userdb_register_module(&userdb_ldap_plugin);
1288
1324
 
1289
1325
}
1290
1326
void authdb_ldap_deinit(void)
1291
1327
{
1292
 
        passdb_unregister_module(&passdb_ldap);
1293
 
        userdb_unregister_module(&userdb_ldap);
 
1328
        passdb_unregister_module(&passdb_ldap_plugin);
 
1329
        userdb_unregister_module(&userdb_ldap_plugin);
1294
1330
}
1295
1331
#endif
1296
1332