[16576] in Kerberos_V5_Development

home help back first fref pref prev next nref lref last post

SASL support for kldap

daemon@ATHENA.MIT.EDU (Zoran Pericic)
Mon Jan 10 13:09:51 2011

Message-ID: <4D2A29F9.1020302@inet.hr>
Date: Sun, 09 Jan 2011 22:34:49 +0100
From: Zoran Pericic <zpericic@inet.hr>
MIME-Version: 1.0
To: krbdev@mit.edu
Content-Type: multipart/mixed; boundary="------------080806060709000808050209"
Errors-To: krbdev-bounces@mit.edu

This is a multi-part message in MIME format.
--------------080806060709000808050209
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

This patch add support for SASL auth to LDAP server. It support any SASL 
auth method and it support separate options for kdc, kadmin, kpasswd.

I have not touch e-Directory stuffs but I believe it could be removed.

This options are per global for server:
ldap_debug - LDAP debug level, see ldap_set_option(3)
ldap_starttls - Should we start StartTLS. StartTLS would not be issued 
if server uri begins with ldaps. Acceptable are any integers, yes/no, 
true/false

Thease options could be separate per service by replacing ldap_ with 
ldap_kdc_, ldap_kadmin_, ldap_kpasswd.
ldap_auth_method - "none" for anonymous bind, "simple" for simple bind 
and "sasl" for SASL bind
ldap_sasl_mech - See SASL documentations.
ldap_sasl_user - Authorization user. See SASL documentations.
ldap_sasl_auth_user - Authentication user. See SASL documentations.
ldap_sasl_realm - See SASL documentations.
ldap_sasl_secret - See SASL documentations.
ldap_tls_cacert_file - Filename of CA certificate file.
ldap_tls_cacert_dir - Path to CA certification dir.
ldap_tls_cert_file - Certificate we could use for auth
ldap_tls_cert_key_file - Certificate key we could use for auth
ldap_tls_reqcert - "none", "allow", "try", "demand", "hard". See 
SSL/LDAP documentation.
ldap_tls_crl_file - CRL file. Depands on SSL implementation. See 
ldap_set_option(3)
ldap_tls_crlcheck - "none", "peer", "all". Check CRL. Depands on SSL 
implementation. See ldap_set_option(3)

Here is sample config for SASL EXTERNAL

[dbmodules]
     ldapconf = {
         dbname = ldap
         db_library = kldap
         ldap_kerberos_container_dn = "ou=Kerberos,dc=example"
         ldap_servers = ldap://server.example
         ldap_starttls = 1
         ldap_conns_per_server = 5
         ldap_auth_method = sasl
         ldap_sasl_mech = EXTERNAL
         ldap_tls_cacert_file = /etc/pki/tls/certs/cacert.pem
         ldap_tls_cert_file = /etc/pki/tls/certs/server.pem
         ldap_tls_cert_key_file = /etc/pki/tls/private/server.key
         ldap_tls_reqcert = demand
         }

Best regard,
Zoran Pericic

--------------080806060709000808050209
Content-Type: text/x-patch;
 name="krb5-1.8.2-sasl.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="krb5-1.8.2-sasl.patch"

diff -ur krb5-1.8.2.org/src/include/k5-int.h krb5-1.8.2.sasl/src/include/k5-int.h
--- krb5-1.8.2.org/src/include/k5-int.h	2010-12-12 21:51:20.000000000 +0100
+++ krb5-1.8.2.sasl/src/include/k5-int.h	2011-01-09 19:23:35.063370520 +0100
@@ -236,7 +236,61 @@
 #define KRB5_CONF_LDAP_SERVICE_PASSWORD_FILE  "ldap_service_password_file"
 #define KRB5_CONF_LDAP_ROOT_CERTIFICATE_FILE  "ldap_root_certificate_file"
 #define KRB5_CONF_LDAP_SERVERS                "ldap_servers"
+#define KRB5_CONF_LDAP_STARTTLS               "ldap_starttls"
 #define KRB5_CONF_LDAP_CONNS_PER_SERVER       "ldap_conns_per_server"
+#define KRB5_CONF_LDAP_DEBUG                  "ldap_debug"
+#define KRB5_CONF_LDAP_AUTH_METHOD            "ldap_auth_method"
+#define KRB5_CONF_LDAP_SASL_MECH              "ldap_sasl_mech"
+#define KRB5_CONF_LDAP_SASL_USER              "ldap_sasl_user"
+#define KRB5_CONF_LDAP_SASL_AUTH_USER         "ldap_sasl_auth_user"
+#define KRB5_CONF_LDAP_SASL_REALM             "ldap_sasl_realm"
+#define KRB5_CONF_LDAP_SASL_SECRET            "ldap_sasl_secret"
+#define KRB5_CONF_LDAP_TLS_CACERT_FILE        "ldap_tls_cacert_file"
+#define KRB5_CONF_LDAP_TLS_CACERT_DIR         "ldap_tls_cacert_dir"
+#define KRB5_CONF_LDAP_TLS_CERT_FILE          "ldap_tls_cert_file"
+#define KRB5_CONF_LDAP_TLS_CERT_KEY_FILE      "ldap_tls_cert_key_file"
+#define KRB5_CONF_LDAP_TLS_REQCERT            "ldap_tls_reqcert"
+#define KRB5_CONF_LDAP_TLS_CRL_FILE           "ldap_tls_crl_file"
+#define KRB5_CONF_LDAP_TLS_CRLCHECK           "ldap_tls_crlcheck"
+#define KRB5_CONF_LDAP_KDC_AUTH_METHOD        "ldap_kdc_auth_method"
+#define KRB5_CONF_LDAP_KDC_SASL_MECH          "ldap_kdc_sasl_mech"
+#define KRB5_CONF_LDAP_KDC_SASL_USER          "ldap_kdc_sasl_user"
+#define KRB5_CONF_LDAP_KDC_SASL_AUTH_USER     "ldap_kdc_sasl_auth_user"
+#define KRB5_CONF_LDAP_KDC_SASL_REALM         "ldap_kdc_sasl_realm"
+#define KRB5_CONF_LDAP_KDC_SASL_SECRET        "ldap_kdc_sasl_secret"
+#define KRB5_CONF_LDAP_KDC_TLS_CACERT_FILE    "ldap_kdc_tls_cacert_file"
+#define KRB5_CONF_LDAP_KDC_TLS_CACERT_DIR     "ldap_kdc_tls_cacert_dir"
+#define KRB5_CONF_LDAP_KDC_TLS_CERT_FILE      "ldap_kdc_tls_cert_file"
+#define KRB5_CONF_LDAP_KDC_TLS_CERT_KEY_FILE  "ldap_kdc_tls_cert_key_file"
+#define KRB5_CONF_LDAP_KDC_TLS_REQCERT        "ldap_kdc_tls_reqcert"
+#define KRB5_CONF_LDAP_KDC_TLS_CRL_FILE       "ldap_kdc_tls_crl_file"
+#define KRB5_CONF_LDAP_KDC_TLS_CRLCHECK       "ldap_kdc_tls_crlcheck"
+#define KRB5_CONF_LDAP_KADMIN_AUTH_METHOD     "ldap_kadmin_auth_method"
+#define KRB5_CONF_LDAP_KADMIN_SASL_MECH       "ldap_kadmin_sasl_mech"
+#define KRB5_CONF_LDAP_KADMIN_SASL_USER       "ldap_kadmin_sasl_user"
+#define KRB5_CONF_LDAP_KADMIN_SASL_AUTH_USER  "ldap_kadmin_sasl_auth_user"
+#define KRB5_CONF_LDAP_KADMIN_SASL_REALM      "ldap_kadmin_sasl_realm"
+#define KRB5_CONF_LDAP_KADMIN_SASL_SECRET     "ldap_kadmin_sasl_secret"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CACERT_FILE "ldap_kadmin_tls_cacert_file"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CACERT_DIR  "ldap_kadmin_tls_cacert_dir"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CERT_FILE   "ldap_kadmin_tls_cert_file"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CERT_KEY_FILE "ldap_kadmin_tls_cert_key_file"
+#define KRB5_CONF_LDAP_KADMIN_TLS_REQCERT     "ldap_kadmin_tls_reqcert"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CRL_FILE    "ldap_kadmin_tls_crl_file"
+#define KRB5_CONF_LDAP_KADMIN_TLS_CRLCHECK    "ldap_kadmin_tls_crlcheck"
+#define KRB5_CONF_LDAP_KPASSWD_AUTH_METHOD    "ldap_kpasswd_auth_method"
+#define KRB5_CONF_LDAP_KPASSWD_SASL_MECH      "ldap_kpasswd_sasl_mech"
+#define KRB5_CONF_LDAP_KPASSWD_SASL_USER      "ldap_kpasswd_sasl_user"
+#define KRB5_CONF_LDAP_KPASSWD_SASL_AUTH_USER "ldap_kpasswd_sasl_auth_user"
+#define KRB5_CONF_LDAP_KPASSWD_SASL_REALM     "ldap_kpasswd_sasl_realm"
+#define KRB5_CONF_LDAP_KPASSWD_SASL_SECRET    "ldap_kpasswd_sasl_secret"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CACERT_FILE "ldap_kpasswd_tls_cacert_file"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CACERT_DIR "ldap_kpasswd_tls_cacert_dir"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CERT_FILE  "ldap_kpasswd_tls_cert_file"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CERT_KEY_FILE "ldap_kpasswd_tls_cert_key_file"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_REQCERT    "ldap_kpasswd_tls_reqcert"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CRL_FILE   "ldap_kpasswd_tls_crl_file"
+#define KRB5_CONF_LDAP_KPASSWD_TLS_CRLCHECK   "ldap_kpasswd_tls_crlcheck"
 #define KRB5_CONF_NO_HOST_REFERRAL            "no_host_referral"
 #define KRB5_CONF_MASTER_KEY_NAME             "master_key_name"
 #define KRB5_CONF_MASTER_KEY_TYPE             "master_key_type"
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c	2009-11-25 00:52:25.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c	2011-01-09 21:31:42.156530231 +0100
@@ -311,7 +311,10 @@
     }
 
     ldap_context->kcontext = context;
-
+    ldap_context->auth_method = -1;
+    ldap_context->tls_reqcert = -1;
+    ldap_context->tls_crlcheck = -1;
+ 
     while (t_ptr && *t_ptr) {
         char *opt = NULL, *val = NULL;
 
@@ -411,6 +414,250 @@
             }
 
             srv_cnt++;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_DEBUG)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_DEBUG);
+                free(opt);
+                goto clean_n_exit;
+            }
+            ldap_context->ldap_debug = atoi(val) ? atoi(val) : 0;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_STARTTLS)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_STARTTLS);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if ((!strcasecmp(val, "yes")) || (!strcasecmp(val, "true")) || (!strcmp(val, "1"))) {
+                ldap_context->starttls = 1;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_AUTH_METHOD)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_AUTH_METHOD);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (!strcasecmp(val, "sasl")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SASL;
+            } else if (!strcasecmp(val, "none")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_NONE;
+            } else if (!strcasecmp(val, "simple")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SIMPLE;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_MECH)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_MECH);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->sasl_mech) {
+                free(ldap_context->sasl_mech);
+            }
+            ldap_context->sasl_mech = strdup(val);
+            if (ldap_context->sasl_mech == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_USER)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_USER);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->sasl_user) {
+                free(ldap_context->sasl_user);
+            }
+            ldap_context->sasl_user = strdup(val);
+            if (ldap_context->sasl_user == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_AUTH_USER)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_AUTH_USER);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->sasl_auth_user) {
+                free(ldap_context->sasl_auth_user);
+            }
+            ldap_context->sasl_auth_user = strdup(val);
+            if (ldap_context->sasl_auth_user == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_REALM)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_REALM);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->sasl_realm) {
+                free(ldap_context->sasl_realm);
+            }
+            ldap_context->sasl_realm = strdup(val);
+            if (ldap_context->sasl_realm == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_SECRET)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_SECRET);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->sasl_secret) {
+                free(ldap_context->sasl_secret);
+            }
+            ldap_context->sasl_secret = strdup(val);
+            if (ldap_context->sasl_secret == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CACERT_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CACERT_FILE);
+                free(opt);
+                goto clean_n_exit;
+            }
+
+            if (ldap_context->tls_cacert_file == NULL) {
+                ldap_context->tls_cacert_file = strdup(val);
+                if (ldap_context->tls_cacert_file == NULL) {
+                    free (opt);
+                    free (val);
+                    status = ENOMEM;
+                    goto clean_n_exit;
+                }
+            } else {
+                char *newstr;
+
+                if (asprintf(&newstr, "%s %s",
+                             ldap_context->tls_cacert_file, val) < 0) {
+                    free (opt);
+                    free (val);
+                    status = ENOMEM;
+                    goto clean_n_exit;
+                }
+                free(ldap_context->tls_cacert_file);
+                ldap_context->tls_cacert_file = newstr;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CACERT_DIR)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CACERT_DIR);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->tls_cacert_dir) {
+                free(ldap_context->tls_cacert_dir);
+            }
+            ldap_context->tls_cacert_dir = strdup(val);
+            if (ldap_context->tls_cacert_dir == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CERT_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CERT_FILE);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->tls_cert_file) {
+                free(ldap_context->tls_cert_file);
+            }
+            ldap_context->tls_cert_file = strdup(val);
+            if (ldap_context->tls_cert_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CERT_KEY_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CERT_KEY_FILE);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->tls_cert_key_file) {
+                free(ldap_context->tls_cert_key_file);
+            }
+            ldap_context->tls_cert_key_file = strdup(val);
+            if (ldap_context->tls_cert_key_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_REQCERT)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_REQCERT);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (!strcmp(val, "never"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_NEVER;
+            else if (!strcmp(val, "allow"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
+            else if (!strcmp(val, "try"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_TRY;
+            else if (!strcmp(val, "demand"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
+            else if (!strcmp(val, "hard"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_HARD;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CRL_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CRL_FILE);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (ldap_context->tls_crl_file == NULL) {
+                free(ldap_context->tls_crl_file);
+            }
+            ldap_context->tls_crl_file = strdup(val);
+            if (ldap_context->tls_crl_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto clean_n_exit;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CRLCHECK)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CRLCHECK);
+                free(opt);
+                goto clean_n_exit;
+            }
+            if (!strcmp(val, "none")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
+            else if (!strcmp(val, "peer")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
+            else if (!strcmp(val, "all"))
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
 #ifdef HAVE_EDIRECTORY
         } else if (opt && !strcmp(opt, "cert")) {
             if (val == NULL) {
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c	2009-11-25 00:52:25.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c	2011-01-09 21:55:39.503389651 +0100
@@ -34,6 +34,8 @@
 #include <unistd.h>
 #endif
 
+#include <sasl/sasl.h>
+
 #include "ldap_main.h"
 #include "ldap_service_stash.h"
 #include <kdb5.h>
@@ -45,6 +47,9 @@
     krb5_error_code             st=0;
     unsigned char               *password=NULL;
 
+    if ((ldap_context->auth_method==KRB5_LDAP_AUTH_NONE) ||
+        (ldap_context->auth_method==KRB5_LDAP_AUTH_SASL))
+        goto err_out;
     if (ldap_context->bind_dn == NULL) {
         st = EINVAL;
         krb5_set_error_message(context, st, "LDAP bind dn value missing ");
@@ -95,6 +100,75 @@
     return st;
 }
 
+static int
+krb5_ldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sin)
+{
+    sasl_interact_t *in;
+    krb5_ldap_context *ldap_context = defaults;
+    int ret = LDAP_OTHER;
+
+    if (ldap_context == NULL) {
+       in->result = NULL;
+       in->len = 0;
+       ret = LDAP_OTHER;
+    }
+
+    if (ld == NULL || sin == NULL)
+        return LDAP_PARAM_ERROR;
+
+    for (in = sin; in != NULL && in->id != SASL_CB_LIST_END; in++) {
+        switch (in->id) {
+        case SASL_CB_USER:
+            if (ldap_context->sasl_user) {
+                in->result = ldap_context->sasl_user;
+                in->len = strlen(ldap_context->sasl_user);
+            } else {
+                in->result = NULL;
+                in->len = 0;
+            }
+            ret = LDAP_SUCCESS;
+            break;
+        case SASL_CB_GETREALM:
+            if (ldap_context->sasl_realm) {
+                in->result = ldap_context->sasl_realm;
+                in->len = strlen(ldap_context->sasl_realm);
+            } else {
+                in->result = NULL;
+                in->len = 0;
+            }
+            ret = LDAP_SUCCESS;
+            break;
+        case SASL_CB_AUTHNAME:
+            if (ldap_context->sasl_auth_user) {
+                in->result = ldap_context->sasl_auth_user;
+                in->len = strlen(ldap_context->sasl_auth_user);
+            } else {
+                in->result = NULL;
+                in->len = 0;
+            }
+            ret = LDAP_SUCCESS;
+            break;
+        case SASL_CB_PASS:
+            if (ldap_context->sasl_secret) {
+                in->result = ldap_context->sasl_secret;
+                in->len = strlen(ldap_context->sasl_secret);
+            } else {
+                in->result = NULL;
+                in->len = 0;
+            }
+            ret = LDAP_SUCCESS;
+            break;
+        default:
+            in->result = NULL;
+            in->len = 0;
+            ret = LDAP_OTHER;
+        }
+    }
+
+    return ret;
+}
+
+
 /*
  * Internal Functions called by init functions.
  */
@@ -104,36 +178,26 @@
                krb5_ldap_server_handle *ldap_server_handle)
 {
     krb5_error_code             st=0;
-    struct berval               bv={0, NULL}, *servercreds=NULL;
-
-    if (ldap_context->service_cert_path != NULL) {
-        /* Certificate based bind (SASL EXTERNAL mechanism) */
 
-        st = ldap_sasl_bind_s(ldap_server_handle->ldap_handle,
-                              NULL,        /* Authenticating dn */
-                              "EXTERNAL",  /* Method used for authentication */
-                              &bv,
-                              NULL,
-                              NULL,
-                              &servercreds);
-
-        if (st == LDAP_SASL_BIND_IN_PROGRESS) {
-            st = ldap_sasl_bind_s(ldap_server_handle->ldap_handle,
-                                  NULL,
-                                  "EXTERNAL",
-                                  servercreds,
-                                  NULL,
-                                  NULL,
-                                  &servercreds);
-        }
-    } else {
-        /* password based simple bind */
-        bv.bv_val = ldap_context->bind_pwd;
-        bv.bv_len = strlen(ldap_context->bind_pwd);
-        st = ldap_sasl_bind_s(ldap_server_handle->ldap_handle,
-                              ldap_context->bind_dn,
-                              NULL, &bv, NULL,
-                              NULL, NULL);
+    switch(ldap_context->auth_method) {
+    case KRB5_LDAP_AUTH_NONE:
+        st = ldap_simple_bind_s(ldap_server_handle->ldap_handle, NULL, NULL);
+        break;
+    case KRB5_LDAP_AUTH_SIMPLE:
+        st = ldap_simple_bind_s(ldap_server_handle->ldap_handle, 
+                                ldap_context->bind_dn, 
+                                ldap_context->bind_pwd);
+        break;
+    case KRB5_LDAP_AUTH_SASL:
+        st = ldap_sasl_interactive_bind_s(ldap_server_handle->ldap_handle,
+                                          NULL,
+                                          ldap_context->sasl_mech,
+                                          NULL,
+                                          NULL,
+                                          LDAP_SASL_QUIET,
+                                          &krb5_ldap_sasl_interact,
+                                          (void *)ldap_context);
+        break;
     }
     return st;
 }
@@ -161,6 +225,16 @@
         goto err_out;
     }
 
+    if ((ldap_context->starttls != 0) 
+            && (strncmp(server_info->server_name, "ldaps", 5))
+            && (st = ldap_start_tls_s(ldap_server_handle->ldap_handle, NULL, NULL) != LDAP_SUCCESS)) {
+        if (ldap_context->kcontext)
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "LDAP StartTLS failed. %s",
+                                    ldap_err2string(st));
+        st = KRB5_KDB_ACCESS_ERROR;
+        goto err_out;
+    }
+
     if ((st=krb5_ldap_bind(ldap_context, ldap_server_handle)) == 0) {
         ldap_server_handle->server_info_update_pending = FALSE;
         server_info->server_status = ON;
@@ -196,6 +270,7 @@
     if ((st=krb5_validate_ldap_context(context, ldap_context)) != 0)
         goto err_out;
 
+    ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_context->ldap_debug);
     ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &version);
 #ifdef LDAP_OPT_NETWORK_TIMEOUT
     ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &local_timelimit);
@@ -206,6 +281,70 @@
     st = HNDL_LOCK(ldap_context);
     if (st)
         return st;
+
+    if (ldap_context->tls_cacert_file) {
+        st = ldap_set_option (NULL,
+                        LDAP_OPT_X_TLS_CACERTFILE,
+                        ldap_context->tls_cacert_file);
+        if (st != LDAP_OPT_SUCCESS) {
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "Could not set TLS_CACERTFILE: %s",
+                                    ldap_err2string(st));
+            st = KRB5_KDB_ACCESS_ERROR;
+            goto err_out;
+        }
+    }
+    if (ldap_context->tls_cacert_dir) {
+        st = ldap_set_option (NULL,
+                        LDAP_OPT_X_TLS_CACERTDIR,
+                        ldap_context->tls_cacert_file);
+        if (st != LDAP_OPT_SUCCESS) {
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "Could not set TLS_CACERTDIR: %s",
+                                    ldap_err2string(st));
+            st = KRB5_KDB_ACCESS_ERROR;
+            goto err_out;
+        }
+    }
+    if (ldap_context->tls_cert_file) {
+        st = ldap_set_option (NULL,
+                        LDAP_OPT_X_TLS_CERTFILE,
+                        ldap_context->tls_cert_file);
+        if (st != LDAP_OPT_SUCCESS) {
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "Could not set TLS_CERTFILE: %s",
+                                    ldap_err2string(st));
+            st = KRB5_KDB_ACCESS_ERROR;
+            goto err_out;
+        }
+    }
+    if (ldap_context->tls_cert_key_file) {
+        st = ldap_set_option (NULL, 
+                        LDAP_OPT_X_TLS_KEYFILE,
+                        ldap_context->tls_cert_key_file);
+        if (st != LDAP_OPT_SUCCESS) {
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "Could not set TLS_KEYFILE: %s",
+                                    ldap_err2string(st));
+            st = KRB5_KDB_ACCESS_ERROR;
+            goto err_out;
+        }
+    }
+    if (ldap_context->tls_reqcert!=-1) {
+        st = ldap_set_option (NULL, 
+                        LDAP_OPT_X_TLS_REQUIRE_CERT,
+                        &ldap_context->tls_reqcert);
+        if (st != LDAP_OPT_SUCCESS) {
+            krb5_set_error_message (ldap_context->kcontext, KRB5_KDB_ACCESS_ERROR, "Could not set TLS_REQUIRE_CERT: %s",
+                                    ldap_err2string(st));
+            st = KRB5_KDB_ACCESS_ERROR;
+            goto err_out;
+        }
+    }
+
+    ldap_set_option (NULL,
+                    LDAP_OPT_X_TLS_CRLFILE,
+                    ldap_context->tls_crl_file);
+    ldap_set_option (NULL,
+                    LDAP_OPT_X_TLS_CRLCHECK,
+                    &ldap_context->tls_crlcheck);
+
     while (ldap_context->server_info_list[cnt] != NULL) {
         krb5_ldap_server_info *server_info=NULL;
 
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h	2009-11-25 00:52:25.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h	2011-01-09 19:25:02.687375764 +0100
@@ -206,15 +206,31 @@
 /* ldap server structure */
 
 typedef enum {SERVICE_DN_TYPE_SERVER, SERVICE_DN_TYPE_CLIENT} krb5_ldap_servicetype;
+typedef enum {KRB5_LDAP_AUTH_NONE, KRB5_LDAP_AUTH_SIMPLE, KRB5_LDAP_AUTH_SASL} krb5_ldap_authmethod;
 
 typedef struct _krb5_ldap_context {
     krb5_ldap_servicetype         service_type;
     krb5_ldap_server_info         **server_info_list;
     krb5_ui_4                     max_server_conns;
     char                          *conf_section;
+    krb5_ldap_authmethod          auth_method;
     char                          *bind_dn;
     char                          *bind_pwd;
     char                          *service_password_file;
+    int                           ldap_debug;
+    int                           starttls;
+    char                          *sasl_mech;
+    char                          *sasl_user;
+    char                          *sasl_auth_user;
+    char                          *sasl_realm;
+    char                          *sasl_secret;
+    char                          *tls_cacert_file;
+    char                          *tls_cacert_dir;
+    char                          *tls_cert_file;
+    char                          *tls_cert_key_file;
+    int                           tls_reqcert;
+    char                          *tls_crl_file;
+    int                           tls_crlcheck;
     char                          *root_certificate_file;
     char                          *service_cert_path;
     char                          *service_cert_pass;
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c	2009-11-25 00:52:25.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c	2011-01-09 21:31:34.783606985 +0100
@@ -78,6 +78,9 @@
     memset(ldap_context, 0, sizeof(*ldap_context));
 
     ldap_context->kcontext = context;
+    ldap_context->auth_method = -1;
+    ldap_context->tls_reqcert = -1;
+    ldap_context->tls_crlcheck = -1;
 
     /* populate ldap_context with ldap specific options */
     while (t_ptr && *t_ptr) {
@@ -181,6 +184,250 @@
             }
 
             srv_cnt++;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_DEBUG)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_DEBUG);
+                free(opt);
+                goto cleanup;
+            }
+            ldap_context->ldap_debug = atoi(val) ? atoi(val) : 0;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_STARTTLS)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_STARTTLS);
+                free(opt);
+                goto cleanup;
+            }
+            if ((!strcasecmp(val, "yes")) || (!strcasecmp(val, "true")) || (!strcmp(val, "1"))) {
+                ldap_context->starttls = 1;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_AUTH_METHOD)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_AUTH_METHOD);
+                free(opt);
+                goto cleanup;
+            }
+            if (strcasecmp(val, "sasl")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SASL;
+            } else if (strcasecmp(val, "none")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_NONE;
+            } else if (strcasecmp(val, "simple")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SIMPLE;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_MECH)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_MECH);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->sasl_mech) {
+                free(ldap_context->sasl_mech);
+            }
+            ldap_context->sasl_mech = strdup(val);
+            if (ldap_context->sasl_mech == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_USER)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_USER);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->sasl_user) {
+                free(ldap_context->sasl_user);
+            }
+            ldap_context->sasl_user = strdup(val);
+            if (ldap_context->sasl_user == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_AUTH_USER)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_AUTH_USER);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->sasl_auth_user) {
+                free(ldap_context->sasl_auth_user);
+            }
+            ldap_context->sasl_auth_user = strdup(val);
+            if (ldap_context->sasl_auth_user == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_REALM)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_REALM);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->sasl_realm) {
+                free(ldap_context->sasl_realm);
+            }
+            ldap_context->sasl_realm = strdup(val);
+            if (ldap_context->sasl_realm == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_SASL_SECRET)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_SASL_SECRET);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->sasl_secret) {
+                free(ldap_context->sasl_secret);
+            }
+            ldap_context->sasl_secret = strdup(val);
+            if (ldap_context->sasl_secret == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CACERT_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CACERT_FILE);
+                free(opt);
+                goto cleanup;
+            }
+
+            if (ldap_context->tls_cacert_file == NULL) {
+                ldap_context->tls_cacert_file = strdup(val);
+                if (ldap_context->tls_cacert_file == NULL) {
+                    free (opt);
+                    free (val);
+                    status = ENOMEM;
+                    goto cleanup;
+                }
+            } else {
+                char *newstr;
+
+                if (asprintf(&newstr, "%s %s",
+                             ldap_context->tls_cacert_file, val) < 0) {
+                    free (opt);
+                    free (val);
+                    status = ENOMEM;
+                    goto cleanup;
+                }
+                free(ldap_context->tls_cacert_file);
+                ldap_context->tls_cacert_file = newstr;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CACERT_DIR)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CACERT_DIR);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->tls_cacert_dir) {
+                free(ldap_context->tls_cacert_dir);
+            }
+            ldap_context->tls_cacert_dir = strdup(val);
+            if (ldap_context->tls_cacert_dir == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CERT_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CERT_FILE);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->tls_cert_file) {
+                free(ldap_context->tls_cert_file);
+            }
+            ldap_context->tls_cert_file = strdup(val);
+            if (ldap_context->tls_cert_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CERT_KEY_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CERT_KEY_FILE);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->tls_cert_key_file) {
+                free(ldap_context->tls_cert_key_file);
+            }
+            ldap_context->tls_cert_key_file = strdup(val);
+            if (ldap_context->tls_cert_key_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_REQCERT)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_REQCERT);
+                free(opt);
+                goto cleanup;
+            }
+            if (!strcmp(val, "never"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_NEVER;
+            else if (!strcmp(val, "allow"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
+            else if (!strcmp(val, "try"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_TRY;
+            else if (!strcmp(val, "demand"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
+            else if (!strcmp(val, "hard"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_HARD;
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CRL_FILE)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CRL_FILE);
+                free(opt);
+                goto cleanup;
+            }
+            if (ldap_context->tls_crl_file == NULL) {
+                free(ldap_context->tls_crl_file);
+            }
+            ldap_context->tls_crl_file = strdup(val);
+            if (ldap_context->tls_crl_file == NULL) {
+                free (opt);
+                free (val);
+                status = ENOMEM;
+                goto cleanup;
+            }
+        } else if (opt && !strcmp(opt, KRB5_CONF_LDAP_TLS_CRLCHECK)) {
+            if (val == NULL) {
+                status = EINVAL;
+                krb5_set_error_message (context, status, "'%s' value missing", KRB5_CONF_LDAP_TLS_CRLCHECK);
+                free(opt);
+                goto cleanup;
+            }
+            if (!strcmp(val, "none")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
+            else if (!strcmp(val, "peer")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
+            else if (!strcmp(val, "all"))
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
 #ifdef HAVE_EDIRECTORY
         } else if (opt && !strcmp(opt, "cert")) {
             if (val == NULL) {
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2010-12-12 21:51:20.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c	2011-01-09 22:00:21.813058992 +0100
@@ -134,8 +134,409 @@
     return 0;
 }
 
+krb5_error_code
+krb5_ldap_read_auth_params(krb5_context context, krb5_ldap_context *ldap_context, 
+                            char *conf_section,
+                            int srv_type)
+{
+    krb5_error_code             st=0;
+    char *name = 0;
+    char *val;
+
+    st = prof_get_integer_def (context, conf_section,
+                               KRB5_CONF_LDAP_DEBUG,
+                               0,
+                               &ldap_context->ldap_debug);
+
+    if (st)
+        goto cleanup;
+    st = prof_get_string_def (context, conf_section,
+                              KRB5_CONF_LDAP_STARTTLS,
+                              &val);
+    if (st)
+        goto cleanup;
+    if (val) {
+        if ((!strcasecmp(val, "yes")) || (!strcasecmp(val, "true")) || (!strcmp(val, "1"))) {
+            ldap_context->starttls = 1;
+        }
+        krb5_xfree(val);
+    }
 
+    if (ldap_context->auth_method == -1) {
+        char *val;
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_AUTH_METHOD;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_AUTH_METHOD;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_AUTH_METHOD;
+        else
+            name = KRB5_CONF_LDAP_AUTH_METHOD;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &val);
+        if (st)
+            goto cleanup;
+        if (val) {
+            if (!strcasecmp(val, "sasl")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SASL;
+            } else if (!strcasecmp(val, "none")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_NONE;
+            } else if (!strcasecmp(val, "simple")) {
+                ldap_context->auth_method = KRB5_LDAP_AUTH_SIMPLE;
+            }
+            krb5_xfree(val);
+        }
+        /* Get default */
+        if (ldap_context->auth_method == -1) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_AUTH_METHOD,
+                                      &val);
+            if (st)
+                goto cleanup;
+            if (val) {
+                if (!strcasecmp(val, "sasl")) {
+                    ldap_context->auth_method = KRB5_LDAP_AUTH_SASL;
+                } else if (!strcasecmp(val, "none")) {
+                    ldap_context->auth_method = KRB5_LDAP_AUTH_NONE;
+                } else if (!strcasecmp(val, "simple")) {
+                    ldap_context->auth_method = KRB5_LDAP_AUTH_SIMPLE;
+                }
+                krb5_xfree(val);
+            }
+        }
+        /* Not set, default simple auth */
+        if (ldap_context->auth_method == -1)
+            ldap_context->auth_method = KRB5_LDAP_AUTH_SIMPLE;
+    }
+
+    if (ldap_context->sasl_mech == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_SASL_MECH;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_SASL_MECH;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_MECH;
+        else
+            name = KRB5_CONF_LDAP_SASL_MECH;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->sasl_mech);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->sasl_mech == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_SASL_MECH,
+                                      &ldap_context->sasl_mech);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->sasl_user == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_SASL_USER;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_SASL_USER;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_USER;
+        else
+            name = KRB5_CONF_LDAP_SASL_USER;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->sasl_user);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->sasl_user == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_SASL_USER,
+                                      &ldap_context->sasl_user);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->sasl_auth_user == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_SASL_AUTH_USER;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_SASL_AUTH_USER;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_AUTH_USER;
+        else
+            name = KRB5_CONF_LDAP_SASL_AUTH_USER;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->sasl_auth_user);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->sasl_auth_user == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_SASL_AUTH_USER,
+                                      &ldap_context->sasl_auth_user);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->sasl_realm == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_SASL_REALM;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_SASL_REALM;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_REALM;
+        else
+            name = KRB5_CONF_LDAP_SASL_REALM;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->sasl_realm);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->sasl_realm == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_SASL_REALM,
+                                      &ldap_context->sasl_realm);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->sasl_secret == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_SASL_SECRET;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_SASL_SECRET;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_SECRET;
+        else
+            name = KRB5_CONF_LDAP_SASL_SECRET;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->sasl_secret);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->sasl_secret == NULL) {
+            name = KRB5_CONF_LDAP_KPASSWD_SASL_SECRET;
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_SASL_SECRET,
+                                      &ldap_context->sasl_secret);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_cacert_file == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CACERT_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CACERT_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CACERT_FILE;
+        else
+            name = KRB5_CONF_LDAP_TLS_CACERT_FILE;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->tls_cacert_file);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->tls_cacert_file == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CACERT_FILE,
+                                      &ldap_context->tls_cacert_file);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_cacert_dir == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CACERT_DIR;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CACERT_DIR;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CACERT_DIR;
+        else
+            name = KRB5_CONF_LDAP_TLS_CACERT_DIR;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->tls_cacert_dir);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->tls_cacert_dir == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CACERT_DIR,
+                                      &ldap_context->tls_cacert_dir);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_cert_file == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CERT_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CERT_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CERT_FILE;
+        else
+            name = KRB5_CONF_LDAP_TLS_CERT_FILE;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->tls_cert_file);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->tls_cert_file == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CERT_FILE,
+                                      &ldap_context->tls_cert_file);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_cert_key_file == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CERT_KEY_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CERT_KEY_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CERT_KEY_FILE;
+        else
+            name = KRB5_CONF_LDAP_TLS_CERT_KEY_FILE;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->tls_cert_key_file);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->tls_cert_key_file == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CERT_KEY_FILE,
+                                      &ldap_context->tls_cert_key_file);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_reqcert == -1) {
+        char *val;
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_REQCERT;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_REQCERT;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_REQCERT;
+        else
+            name = KRB5_CONF_LDAP_TLS_REQCERT;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &val);
+        if (st)
+            goto cleanup;
+        if (val) {
+            if (!strcmp(val, "never"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_NEVER;
+            else if (!strcmp(val, "allow"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
+            else if (!strcmp(val, "try"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_TRY;
+            else if (!strcmp(val, "demand"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
+            else if (!strcmp(val, "hard"))
+                ldap_context->tls_reqcert = LDAP_OPT_X_TLS_HARD;
+            krb5_xfree(val);
+        }
+        /* Get default */
+        if (ldap_context->tls_reqcert == -1) {
+            st = prof_get_string_def (context, conf_section,
+                                  KRB5_CONF_LDAP_TLS_REQCERT,
+                                  &val);
+            if (st)
+                goto cleanup;
+            if (val) {
+                if (!strcmp(val, "never"))
+                    ldap_context->tls_reqcert = LDAP_OPT_X_TLS_NEVER;
+                else if (!strcmp(val, "allow"))
+                    ldap_context->tls_reqcert = LDAP_OPT_X_TLS_ALLOW;
+                else if (!strcmp(val, "try"))
+                    ldap_context->tls_reqcert = LDAP_OPT_X_TLS_TRY;
+                else if (!strcmp(val, "demand"))
+                    ldap_context->tls_reqcert = LDAP_OPT_X_TLS_DEMAND;
+                else if (!strcmp(val, "hard"))
+                    ldap_context->tls_reqcert = LDAP_OPT_X_TLS_HARD;
+                krb5_xfree(val);
+            }
+        }
+    }
+    if (ldap_context->tls_crl_file == NULL) {
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CRL_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CRL_FILE;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CRL_FILE;
+        else
+            name = KRB5_CONF_LDAP_TLS_CRL_FILE;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &ldap_context->tls_crl_file);
+        if (st)
+            goto cleanup;
+        /* Get default */
+        if (ldap_context->tls_crl_file == NULL) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CRL_FILE,
+                                      &ldap_context->tls_crl_file);
+            if (st)
+                goto cleanup;
+        }
+    }
+    if (ldap_context->tls_crlcheck == -1) {
+        char *val;
+        if (srv_type == KRB5_KDB_SRV_TYPE_KDC)
+            name = KRB5_CONF_LDAP_KDC_TLS_CRLCHECK;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_ADMIN)
+            name = KRB5_CONF_LDAP_KADMIN_TLS_CRLCHECK;
+        else if (srv_type == KRB5_KDB_SRV_TYPE_PASSWD)
+            name = KRB5_CONF_LDAP_KPASSWD_TLS_CRLCHECK;
+        else
+            name = KRB5_CONF_LDAP_TLS_CRLCHECK;
+        st = prof_get_string_def (context, conf_section,
+                                  name,
+                                  &val);
+        if (st)
+            goto cleanup;
+        if (val) {
+            if (!strcmp(val, "none")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
+            else if (!strcmp(val, "peer")) 
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
+            else if (!strcmp(val, "all"))
+                ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
+            krb5_xfree(val);
+        }
+        /* Get default */
+        if (ldap_context->tls_crlcheck == -1) {
+            st = prof_get_string_def (context, conf_section,
+                                      KRB5_CONF_LDAP_TLS_CRLCHECK,
+                                      &val);
+            if (st)
+                goto cleanup;
+            if (val) {
+                if (!strcmp(val, "none")) 
+                    ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_NONE;
+                else if (!strcmp(val, "peer")) 
+                    ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_PEER;
+                else if (!strcmp(val, "all"))
+                    ldap_context->tls_crlcheck = LDAP_OPT_X_TLS_CRL_ALL;
+                krb5_xfree(val);
+            }
+        }
+    }
 
+cleanup:
+    return(st);
+}
 /*
  * This function reads the parameters from the krb5.conf file. The
  * parameters read here are DAL-LDAP specific attributes. Some of
@@ -235,6 +636,10 @@
             goto cleanup;
     }
 
+    st = krb5_ldap_read_auth_params(context, ldap_context, conf_section, srv_type);
+    if (st)
+        goto cleanup;
+
 #ifdef HAVE_EDIRECTORY
     /*
      * If root certificate file is not set read it from database
@@ -375,6 +780,60 @@
         ldap_context->service_password_file = NULL;
     }
 
+    if (ldap_context->sasl_mech != NULL) {
+        krb5_xfree(ldap_context->sasl_mech);
+        ldap_context->sasl_mech = NULL;
+    }
+
+    if (ldap_context->sasl_user != NULL) {
+        krb5_xfree(ldap_context->sasl_user);
+        ldap_context->sasl_user = NULL;
+    }
+
+    if (ldap_context->sasl_auth_user != NULL) {
+        krb5_xfree(ldap_context->sasl_auth_user);
+        ldap_context->sasl_auth_user = NULL;
+    }
+
+    if (ldap_context->sasl_realm != NULL) {
+        krb5_xfree(ldap_context->sasl_realm);
+        ldap_context->sasl_realm = NULL;
+    }
+
+    if (ldap_context->sasl_secret != NULL) {
+        krb5_xfree(ldap_context->sasl_secret);
+        ldap_context->sasl_secret = NULL;
+    }
+
+    if (ldap_context->tls_cacert_file != NULL) {
+        krb5_xfree(ldap_context->tls_cacert_file);
+        ldap_context->tls_cacert_file = NULL;
+    }
+
+    if (ldap_context->tls_cacert_dir != NULL) {
+        krb5_xfree(ldap_context->tls_cacert_dir);
+        ldap_context->tls_cacert_dir = NULL;
+    }
+
+    if (ldap_context->tls_cert_file != NULL) {
+        krb5_xfree(ldap_context->tls_cert_file);
+        ldap_context->tls_cert_file = NULL;
+    }
+
+    if (ldap_context->tls_cert_key_file != NULL) {
+        krb5_xfree(ldap_context->tls_cert_key_file);
+        ldap_context->tls_cert_key_file = NULL;
+    }
+
+    ldap_context->tls_reqcert = -1;
+
+    if (ldap_context->tls_crl_file != NULL) {
+        krb5_xfree(ldap_context->tls_crl_file);
+        ldap_context->tls_crl_file = NULL;
+    }
+
+    ldap_context->tls_crlcheck = -1;
+
 #ifdef HAVE_EDIRECTORY
     if (ldap_context->root_certificate_file != NULL) {
         krb5_xfree(ldap_context->root_certificate_file);
diff -ur krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.h krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.h
--- krb5-1.8.2.org/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.h	2009-11-25 00:52:25.000000000 +0100
+++ krb5-1.8.2.sasl/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.h	2011-01-09 01:54:25.000000000 +0100
@@ -153,4 +153,9 @@
 
 int kldap_ensure_initialized (void);
 
+krb5_error_code
+krb5_ldap_read_auth_params(krb5_context context, krb5_ldap_context *ldap_context, 
+                            char *conf_section,
+                            int srv_type);
+
 #endif

--------------080806060709000808050209
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
krbdev mailing list             krbdev@mit.edu
https://mailman.mit.edu/mailman/listinfo/krbdev

--------------080806060709000808050209--


home help back first fref pref prev next nref lref last post