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;
19 char *sasl_host = NULL;
21 #ifdef HAVE_CYRUS_SASL
22 static void *sasl_pvt_mutex_new(void)
24 ldap_pvt_thread_mutex_t *mutex;
26 mutex = (ldap_pvt_thread_mutex_t *)ch_malloc( sizeof(ldap_pvt_thread_mutex_t) );
27 if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
33 static int sasl_pvt_mutex_lock(void *mutex)
35 return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex );
38 static int sasl_pvt_mutex_unlock(void *mutex)
40 return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex );
43 static void sasl_pvt_mutex_dispose(void *mutex)
45 (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
53 sasl_conn_t *server = NULL;
55 sasl_set_alloc( ch_malloc, ch_calloc, ch_realloc, ch_free );
57 sasl_set_mutex( sasl_pvt_mutex_new, sasl_pvt_mutex_lock,
58 sasl_pvt_mutex_unlock, sasl_pvt_mutex_dispose );
60 rc = sasl_server_init( NULL, "slapd" );
63 Debug( LDAP_DEBUG_ANY, "sasl_server_init failed\n",
68 if( sasl_host == NULL ) {
69 char hostname[MAXHOSTNAMELEN+1];
71 if( gethostname( hostname, MAXHOSTNAMELEN ) == 0 ) {
72 hostname[MAXHOSTNAMELEN] = '\0';
77 rc = sasl_server_new( "ldap", sasl_host, NULL, NULL,
82 Debug( LDAP_DEBUG_ANY, "sasl_server_new failed\n",
89 sasl_security_properties_t secprops;
90 memset(&secprops, 0, sizeof(secprops));
91 secprops.security_flags = SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
92 secprops.property_names = NULL;
93 secprops.property_values = NULL;
95 rc = sasl_setprop( server, SASL_SEC_PROPS, &secprops );
98 Debug( LDAP_DEBUG_ANY, "sasl_setprop failed\n",
105 rc = sasl_listmech( server, NULL, NULL, ",", NULL,
108 if( rc != SASL_OK ) {
109 Debug( LDAP_DEBUG_ANY, "sasl_listmech failed: %d\n",
114 Debug( LDAP_DEBUG_TRACE, "SASL mechanisms: %s\n",
117 supportedSASLMechanisms = str2charray( mechs, "," );
118 sasl_dispose( &server );
123 int sasl_destroy( void )
125 charray_free( supportedSASLMechanisms );
129 #ifdef HAVE_CYRUS_SASL
139 struct berval response;
144 Debug(LDAP_DEBUG_ARGS, "==> sasl_bind: dn=%s, mech=%s, cred->bv_len=%d\n",
145 dn, mech, cred ? cred->bv_len : 0 );
147 if ( conn->c_sasl_bind_context ) {
148 sasl_callback_t callbacks[4];
152 if (be->be_sasl_authorize) {
153 callbacks[cbnum].id = SASL_CB_PROXY_POLICY;
154 callbacks[cbnum].proc = be->be_sasl_authorize;
155 callbacks[cbnum].context = be;
159 if (be->be_sasl_getsecret) {
160 callbacks[cbnum].id = SASL_CB_SERVER_GETSECRET;
161 callbacks[cbnum].proc = be->be_sasl_getsecret;
162 callbacks[cbnum].context = be;
166 if (be->be_sasl_putsecret) {
167 callbacks[cbnum].id = SASL_CB_SERVER_PUTSECRET;
168 callbacks[cbnum].proc = be->be_sasl_putsecret;
169 callbacks[cbnum].context = be;
174 callbacks[cbnum].id = SASL_CB_LIST_END;
175 callbacks[cbnum].proc = NULL;
176 callbacks[cbnum].context = NULL;
178 /* create new SASL context */
179 sc = sasl_server_new( "ldap", sasl_host, global_realm,
180 callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_bind_context );
182 if( sc != SASL_OK ) {
183 send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
184 NULL, NULL, NULL, NULL );
186 conn->c_authmech = ch_strdup( mech );
187 sc = sasl_server_start( conn->c_sasl_bind_context, conn->c_authmech,
188 cred->bv_val, cred->bv_len, (char **)&response.bv_val,
189 (unsigned *)&response.bv_len, &errstr );
190 if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
191 send_ldap_result( conn, op, rc = ldap_pvt_sasl_err2ldap( sc ),
192 NULL, errstr, NULL, NULL );
196 sc = sasl_server_step( conn->c_sasl_bind_context, cred->bv_val, cred->bv_len,
197 (char **)&response.bv_val, (unsigned *)&response.bv_len, &errstr );
198 if ( (sc != SASL_OK) && (sc != SASL_CONTINUE) ) {
199 send_ldap_result( conn, op, rc = ldap_pvt_sasl_err2ldap( sc ),
200 NULL, errstr, NULL, NULL );
204 if ( sc == SASL_OK ) {
207 if ( ( sc = sasl_getprop( conn->c_sasl_bind_context, SASL_USERNAME,
208 (void **)&authzid ) ) != SASL_OK ) {
209 send_ldap_result( conn, op, rc = ldap_pvt_sasl_err2ldap( sc ),
210 NULL, NULL, NULL, NULL );
213 if( strncasecmp( authzid, "anonymous", sizeof("anonyous")-1 ) &&
214 ( ( authzid[sizeof("anonymous")] == '\0' ) ||
215 ( authzid[sizeof("anonymous")] == '@' ) ) )
217 *edn = ch_malloc( sizeof( "authzid=" ) + strlen( authzid ) );
218 strcpy( *edn, "authzid=" );
219 strcat( *edn, authzid );
222 send_ldap_result( conn, op, rc = LDAP_SUCCESS,
223 NULL, NULL, NULL, NULL );
226 } else if ( sc == SASL_CONTINUE ) {
228 * We set c_sasl_bind_in_progress because it doesn't appear
229 * that connection.c sets this (unless do_bind() itself
230 * returns LDAP_SASL_BIND_IN_PROGRESS).
232 send_ldap_sasl( conn, op, rc = LDAP_SASL_BIND_IN_PROGRESS,
233 NULL, NULL, NULL, NULL, &response );
236 Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: rc=%d\n", rc, 0, 0);
240 #endif /* HAVE_CYRUS_SASL */
243 /* no SASL support */
244 int sasl_init( void ) { return 0; }
245 int sasl_destroy( void ) { return 0; }