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);