+#ifdef SLAPD_SPASSWD
+ sasl_dispose( &lutil_passwd_sasl_conn );
+#endif
+ charray_free( supportedSASLMechanisms );
+ return 0;
+}
+
+#ifdef HAVE_CYRUS_SASL
+int sasl_bind(
+ Connection *conn,
+ Operation *op,
+ const char *dn,
+ const char *ndn,
+ const char *mech,
+ struct berval *cred,
+ char **edn )
+{
+ struct berval response;
+ const char *errstr;
+ int sc;
+ int rc = 1;
+
+ Debug(LDAP_DEBUG_ARGS,
+ "==> sasl_bind: dn=\"%s\" mech=%s cred->bv_len=%d\n",
+ dn, mech, cred ? cred->bv_len : 0 );
+
+ if ( conn->c_sasl_bind_context == NULL ) {
+ sasl_callback_t callbacks[4];
+ int cbnum = 0;
+
+#if 0
+ if (be->be_sasl_authorize) {
+ callbacks[cbnum].id = SASL_CB_PROXY_POLICY;
+ callbacks[cbnum].proc = be->be_sasl_authorize;
+ callbacks[cbnum].context = be;
+ ++cbnum;
+ }
+
+ if (be->be_sasl_getsecret) {
+ callbacks[cbnum].id = SASL_CB_SERVER_GETSECRET;
+ callbacks[cbnum].proc = be->be_sasl_getsecret;
+ callbacks[cbnum].context = be;
+ ++cbnum;
+ }
+
+ if (be->be_sasl_putsecret) {
+ callbacks[cbnum].id = SASL_CB_SERVER_PUTSECRET;
+ callbacks[cbnum].proc = be->be_sasl_putsecret;
+ callbacks[cbnum].context = be;
+ ++cbnum;
+ }
+#endif
+
+ callbacks[cbnum].id = SASL_CB_LIST_END;
+ callbacks[cbnum].proc = NULL;
+ callbacks[cbnum].context = NULL;
+
+ /* create new SASL context */
+ sc = sasl_server_new( "ldap", sasl_host, global_realm,
+ callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_bind_context );
+
+ if( sc != SASL_OK ) {
+ send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
+ NULL, NULL, NULL, NULL );
+ } else {
+ unsigned reslen;
+ conn->c_authmech = ch_strdup( mech );
+
+ sc = sasl_server_start( conn->c_sasl_bind_context, conn->c_authmech,
+ cred->bv_val, cred->bv_len,
+ (char **)&response.bv_val, &reslen, &errstr );
+
+ response.bv_len = reslen;
+
+ if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
+ send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
+ NULL, errstr, NULL, NULL );
+ }
+ }
+ } else {
+ unsigned reslen;
+ sc = sasl_server_step( conn->c_sasl_bind_context, cred->bv_val, cred->bv_len,
+ (char **)&response.bv_val, &reslen, &errstr );
+
+ response.bv_len = reslen;
+
+ if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
+ send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ),
+ NULL, errstr, NULL, NULL );
+ }