Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/auth/db-ldap.c @ 7191:1cbaa724aba8 HEAD
Added support for OpenLDAP-specific TLS settings.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 25 Jan 2008 14:25:11 +0200 |
parents | 7ed926ed7aa4 |
children | 5b654defd376 |
comparison
equal
deleted
inserted
replaced
7190:b9a9c7257f4e | 7191:1cbaa724aba8 |
---|---|
23 # include <sasl/sasl.h> | 23 # include <sasl/sasl.h> |
24 #elif defined (HAVE_SASL_H) | 24 #elif defined (HAVE_SASL_H) |
25 # include <sasl.h> | 25 # include <sasl.h> |
26 #else | 26 #else |
27 # undef HAVE_LDAP_SASL | 27 # undef HAVE_LDAP_SASL |
28 #endif | |
29 #ifdef LDAP_OPT_X_TLS | |
30 # define OPENLDAP_TLS_OPTIONS | |
28 #endif | 31 #endif |
29 #if SASL_VERSION_MAJOR < 2 | 32 #if SASL_VERSION_MAJOR < 2 |
30 # undef HAVE_LDAP_SASL | 33 # undef HAVE_LDAP_SASL |
31 #endif | 34 #endif |
32 | 35 |
82 DEF_BOOL(tls), | 85 DEF_BOOL(tls), |
83 DEF_BOOL(sasl_bind), | 86 DEF_BOOL(sasl_bind), |
84 DEF_STR(sasl_mech), | 87 DEF_STR(sasl_mech), |
85 DEF_STR(sasl_realm), | 88 DEF_STR(sasl_realm), |
86 DEF_STR(sasl_authz_id), | 89 DEF_STR(sasl_authz_id), |
90 DEF_STR(tls_ca_cert_file), | |
91 DEF_STR(tls_ca_cert_dir), | |
92 DEF_STR(tls_cert_file), | |
93 DEF_STR(tls_key_file), | |
94 DEF_STR(tls_cipher_suite), | |
95 DEF_STR(tls_require_cert), | |
87 DEF_STR(deref), | 96 DEF_STR(deref), |
88 DEF_STR(scope), | 97 DEF_STR(scope), |
89 DEF_STR(base), | 98 DEF_STR(base), |
90 DEF_INT(ldap_version), | 99 DEF_INT(ldap_version), |
91 DEF_STR(user_attrs), | 100 DEF_STR(user_attrs), |
107 MEMBER(tls) FALSE, | 116 MEMBER(tls) FALSE, |
108 MEMBER(sasl_bind) FALSE, | 117 MEMBER(sasl_bind) FALSE, |
109 MEMBER(sasl_mech) NULL, | 118 MEMBER(sasl_mech) NULL, |
110 MEMBER(sasl_realm) NULL, | 119 MEMBER(sasl_realm) NULL, |
111 MEMBER(sasl_authz_id) NULL, | 120 MEMBER(sasl_authz_id) NULL, |
121 MEMBER(tls_ca_cert_file) NULL, | |
122 MEMBER(tls_ca_cert_dir) NULL, | |
123 MEMBER(tls_cert_file) NULL, | |
124 MEMBER(tls_key_file) NULL, | |
125 MEMBER(tls_cipher_suite) NULL, | |
126 MEMBER(tls_require_cert) NULL, | |
112 MEMBER(deref) "never", | 127 MEMBER(deref) "never", |
113 MEMBER(scope) "subtree", | 128 MEMBER(scope) "subtree", |
114 MEMBER(base) NULL, | 129 MEMBER(base) NULL, |
115 MEMBER(ldap_version) 2, | 130 MEMBER(ldap_version) 2, |
116 MEMBER(user_attrs) "homeDirectory=home,uidNumber=uid,gidNumber=gid", | 131 MEMBER(user_attrs) "homeDirectory=home,uidNumber=uid,gidNumber=gid", |
148 if (strcasecmp(str, "subtree") == 0) | 163 if (strcasecmp(str, "subtree") == 0) |
149 return LDAP_SCOPE_SUBTREE; | 164 return LDAP_SCOPE_SUBTREE; |
150 | 165 |
151 i_fatal("LDAP: Unknown scope option '%s'", str); | 166 i_fatal("LDAP: Unknown scope option '%s'", str); |
152 } | 167 } |
168 | |
169 #ifdef OPENLDAP_TLS_OPTIONS | |
170 static int tls_require_cert2str(const char *str) | |
171 { | |
172 if (strcasecmp(str, "never") == 0) | |
173 return LDAP_OPT_X_TLS_NEVER; | |
174 if (strcasecmp(str, "hard") == 0) | |
175 return LDAP_OPT_X_TLS_HARD; | |
176 if (strcasecmp(str, "demand") == 0) | |
177 return LDAP_OPT_X_TLS_DEMAND; | |
178 if (strcasecmp(str, "allow") == 0) | |
179 return LDAP_OPT_X_TLS_ALLOW; | |
180 if (strcasecmp(str, "try") == 0) | |
181 return LDAP_OPT_X_TLS_TRY; | |
182 | |
183 i_fatal("LDAP: Unknown tls_require_cert value '%s'", str); | |
184 } | |
185 #endif | |
153 | 186 |
154 static int ldap_get_errno(struct ldap_connection *conn) | 187 static int ldap_get_errno(struct ldap_connection *conn) |
155 { | 188 { |
156 int ret, err; | 189 int ret, err; |
157 | 190 |
619 } | 652 } |
620 i_assert(conn->fd != -1); | 653 i_assert(conn->fd != -1); |
621 net_set_nonblock(conn->fd, TRUE); | 654 net_set_nonblock(conn->fd, TRUE); |
622 } | 655 } |
623 | 656 |
657 static void | |
658 db_ldap_set_opt(struct ldap_connection *conn, int opt, const void *value, | |
659 const char *optname, const char *value_str) | |
660 { | |
661 int ret; | |
662 | |
663 ret = ldap_set_option(conn == NULL ? NULL : conn->ld, opt, value); | |
664 if (ret != LDAP_SUCCESS) { | |
665 i_fatal("LDAP: Can't set option %s to %s: %s", | |
666 optname, value_str, ldap_err2string(ret)); | |
667 } | |
668 } | |
669 | |
670 static void | |
671 db_ldap_set_opt_str(struct ldap_connection *conn, int opt, const char *value, | |
672 const char *optname) | |
673 { | |
674 if (value != NULL) | |
675 db_ldap_set_opt(conn, opt, value, optname, value); | |
676 } | |
677 | |
678 static void db_ldap_set_tls_options(struct ldap_connection *conn) | |
679 { | |
680 if (!conn->set.tls) | |
681 return; | |
682 | |
683 #ifdef OPENLDAP_TLS_OPTIONS | |
684 db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CACERTFILE, | |
685 conn->set.tls_ca_cert_file, "tls_ca_cert_file"); | |
686 db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CACERTDIR, | |
687 conn->set.tls_ca_cert_dir, "tls_ca_cert_dir"); | |
688 db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CERTFILE, | |
689 conn->set.tls_cert_file, "tls_cert_file"); | |
690 db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_KEYFILE, | |
691 conn->set.tls_key_file, "tls_key_file"); | |
692 db_ldap_set_opt_str(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, | |
693 conn->set.tls_cipher_suite, "tls_cipher_suite"); | |
694 if (conn->set.tls_require_cert != NULL) { | |
695 int value = tls_require_cert2str(conn->set.tls_require_cert); | |
696 db_ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &value, | |
697 "tls_require_cert", conn->set.tls_require_cert); | |
698 } | |
699 #endif | |
700 } | |
701 | |
702 static void db_ldap_set_options(struct ldap_connection *conn) | |
703 { | |
704 unsigned int ldap_version; | |
705 | |
706 db_ldap_set_opt(conn, LDAP_OPT_DEREF, &conn->set.ldap_deref, | |
707 "deref", conn->set.deref); | |
708 | |
709 /* If SASL binds are used, the protocol version needs to be | |
710 at least 3 */ | |
711 ldap_version = conn->set.sasl_bind && | |
712 conn->set.ldap_version < 3 ? 3 : conn->set.ldap_version; | |
713 db_ldap_set_opt(conn, LDAP_OPT_PROTOCOL_VERSION, &ldap_version, | |
714 "protocol_version", dec2str(ldap_version)); | |
715 db_ldap_set_tls_options(conn); | |
716 } | |
717 | |
624 int db_ldap_connect(struct ldap_connection *conn) | 718 int db_ldap_connect(struct ldap_connection *conn) |
625 { | 719 { |
626 unsigned int ldap_version; | |
627 int ret; | 720 int ret; |
628 | 721 |
629 if (conn->conn_state != LDAP_CONN_STATE_DISCONNECTED) | 722 if (conn->conn_state != LDAP_CONN_STATE_DISCONNECTED) |
630 return 0; | 723 return 0; |
631 | 724 |
644 | 737 |
645 if (conn->ld == NULL) | 738 if (conn->ld == NULL) |
646 i_fatal("LDAP: ldap_init() failed with hosts: %s", | 739 i_fatal("LDAP: ldap_init() failed with hosts: %s", |
647 conn->set.hosts); | 740 conn->set.hosts); |
648 | 741 |
649 ret = ldap_set_option(conn->ld, LDAP_OPT_DEREF, | 742 db_ldap_set_options(conn); |
650 (void *)&conn->set.ldap_deref); | |
651 if (ret != LDAP_SUCCESS) { | |
652 i_fatal("LDAP: Can't set deref option: %s", | |
653 ldap_err2string(ret)); | |
654 } | |
655 | |
656 /* If SASL binds are used, the protocol version needs to be | |
657 at least 3 */ | |
658 ldap_version = conn->set.sasl_bind && | |
659 conn->set.ldap_version < 3 ? 3 : | |
660 conn->set.ldap_version; | |
661 ret = ldap_set_option(conn->ld, LDAP_OPT_PROTOCOL_VERSION, | |
662 (void *)&ldap_version); | |
663 if (ret != LDAP_OPT_SUCCESS) { | |
664 i_fatal("LDAP: Can't set protocol version %u: %s", | |
665 ldap_version, ldap_err2string(ret)); | |
666 } | |
667 } | 743 } |
668 | 744 |
669 if (conn->set.tls) { | 745 if (conn->set.tls) { |
670 #ifdef LDAP_HAVE_START_TLS_S | 746 #ifdef LDAP_HAVE_START_TLS_S |
671 ret = ldap_start_tls_s(conn->ld, NULL, NULL); | 747 ret = ldap_start_tls_s(conn->ld, NULL, NULL); |