3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include "proto-slap.h"
18 char **supportedSASLMechanisms = NULL;
20 #ifdef HAVE_CYRUS_SASL
21 static void *sasl_pvt_mutex_new(void)
23 ldap_pvt_thread_mutex_t *mutex;
25 mutex = (ldap_pvt_thread_mutex_t *)ch_malloc( sizeof(ldap_pvt_thread_mutex_t) );
26 if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
32 static int sasl_pvt_mutex_lock(void *mutex)
34 return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex );
37 static int sasl_pvt_mutex_unlock(void *mutex)
39 return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex );
42 static void sasl_pvt_mutex_dispose(void *mutex)
44 (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
52 sasl_conn_t *server = NULL;
54 sasl_set_alloc( ch_malloc, ch_calloc, ch_realloc, ch_free );
56 sasl_set_mutex( sasl_pvt_mutex_new, sasl_pvt_mutex_lock,
57 sasl_pvt_mutex_unlock, sasl_pvt_mutex_dispose );
59 rc = sasl_server_init( NULL, "slapd" );
62 Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
67 rc = sasl_server_new( "ldap", NULL, NULL, NULL,
72 Debug( LDAP_DEBUG_ANY, "sasl_server_new failed\n",
79 sasl_security_properties_t secprops;
80 memset(&secprops, 0, sizeof(secprops));
81 secprops.security_flags = SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
82 secprops.property_names = NULL;
83 secprops.property_values = NULL;
85 rc = sasl_setprop( server, SASL_SEC_PROPS, &secprops );
88 Debug( LDAP_DEBUG_ANY, "sasl_setprop failed\n",
95 rc = sasl_listmech( server, NULL, NULL, ",", NULL,
99 Debug( LDAP_DEBUG_ANY, "sasl_listmech failed: %d\n",
104 Debug( LDAP_DEBUG_TRACE, "SASL mechanisms: %s\n",
107 supportedSASLMechanisms = str2charray( mechs, "," );
108 sasl_dispose( &server );
113 int sasl_destroy( void )
115 charray_free( supportedSASLMechanisms );
119 #ifdef HAVE_CYRUS_SASL
130 struct berval response;
135 Debug(LDAP_DEBUG_ARGS, "==> sasl_bind: dn=%s, mech=%s, cred->bv_len=%d\n",
136 dn, mech, cred ? cred->bv_len : 0 );
138 if ( conn->c_sasl_context == NULL ) {
139 sasl_callback_t callbacks[4];
142 if (be->be_sasl_authorize) {
143 callbacks[cbnum].id = SASL_CB_PROXY_POLICY;
144 callbacks[cbnum].proc = be->be_sasl_authorize;
145 callbacks[cbnum].context = be;
149 if (be->be_sasl_getsecret) {
150 callbacks[cbnum].id = SASL_CB_SERVER_GETSECRET;
151 callbacks[cbnum].proc = be->be_sasl_getsecret;
152 callbacks[cbnum].context = be;
156 if (be->be_sasl_putsecret) {
157 callbacks[cbnum].id = SASL_CB_SERVER_PUTSECRET;
158 callbacks[cbnum].proc = be->be_sasl_putsecret;
159 callbacks[cbnum].context = be;
162 callbacks[cbnum].id = SASL_CB_LIST_END;
163 callbacks[cbnum].proc = NULL;
164 callbacks[cbnum].context = NULL;
166 if ( sasl_server_new( "ldap", NULL, be->be_realm,
167 callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_context ) != SASL_OK ) {
168 send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
169 NULL, NULL, NULL, NULL );
171 conn->c_authmech = ch_strdup( mech );
172 sc = sasl_server_start( conn->c_sasl_context, conn->c_authmech,
173 cred->bv_val, cred->bv_len, (char **)&response.bv_val,
174 (unsigned *)&response.bv_len, &errstr );
175 if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
176 send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
177 NULL, errstr, NULL, NULL );
181 sc = sasl_server_step( conn->c_sasl_context, cred->bv_val, cred->bv_len,
182 (char **)&response.bv_val, (unsigned *)&response.bv_len, &errstr );
183 if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
184 send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
185 NULL, errstr, NULL, NULL );
188 if ( sc == SASL_OK ) {
191 if ( ( sc = sasl_getprop( conn->c_sasl_context, SASL_USERNAME,
192 (void **)&authzid ) ) != SASL_OK ) {
193 send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ),
194 NULL, NULL, NULL, NULL );
196 if ( *edn != NULL ) {
199 if ( strcasecmp( authzid, "anonymous" ) == 0 ) {
200 *edn = ch_strdup( "" );
202 *edn = ch_malloc( strlen( authzid ) + sizeof( "authzid=" ) );
203 strcpy( *edn, "authzid=" );
204 strcat( *edn, authzid );
206 /* let FE send result */
209 } else if ( sc == SASL_CONTINUE ) {
211 * We set c_bind_in_progress because it doesn't appear
212 * that connection.c sets this (unless do_bind() itself
213 * returns LDAP_SASL_BIND_IN_PROGRESS).
215 conn->c_bind_in_progress = 1;
216 send_ldap_sasl( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
217 /* matched */ NULL, /* text */ NULL, /* refs */ NULL, /* controls */ NULL, &response );
220 Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: rc=%d\n", rc, 0, 0);
224 #endif /* HAVE_CYRUS_SASL */
227 /* no SASL support */
228 int sasl_init( void ) { return 0; }
229 int sasl_destroy( void ) { return 0; }