X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsasl.c;h=b2e40a05b822ad8ca92e2b684040bdce4dd57931;hb=a5ee438c9394a19a241716d3d922299c20b0365d;hp=433cb9d9e46696f6647f929e16a54166713976ab;hpb=9b4e3b2234b0d347c90dc09b1638e8e93497dae1;p=openldap diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 433cb9d9e4..b2e40a05b8 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -16,35 +16,81 @@ #include char **supportedSASLMechanisms = NULL; +char *sasl_host = NULL; #ifdef HAVE_CYRUS_SASL -static void *sasl_pvt_mutex_new(void) + +#ifdef SLAPD_SPASSWD +#include +#endif + +static void *slap_sasl_mutex_new(void) { ldap_pvt_thread_mutex_t *mutex; - mutex = (ldap_pvt_thread_mutex_t *)ch_malloc( sizeof(ldap_pvt_thread_mutex_t) ); + mutex = (ldap_pvt_thread_mutex_t *) ch_malloc( sizeof(ldap_pvt_thread_mutex_t) ); if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) { return mutex; } return NULL; } -static int sasl_pvt_mutex_lock(void *mutex) +static int slap_sasl_mutex_lock(void *mutex) { return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex ); } -static int sasl_pvt_mutex_unlock(void *mutex) +static int slap_sasl_mutex_unlock(void *mutex) { return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex ); } -static void sasl_pvt_mutex_dispose(void *mutex) +static void slap_sasl_mutex_dispose(void *mutex) { (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex ); free( mutex ); } +static int +slap_sasl_err2ldap( int saslerr ) +{ + int rc; + + switch (saslerr) { + case SASL_CONTINUE: + rc = LDAP_SASL_BIND_IN_PROGRESS; + break; + case SASL_OK: + rc = LDAP_SUCCESS; + break; + case SASL_FAIL: + rc = LDAP_OTHER; + break; + case SASL_NOMEM: + rc = LDAP_OTHER; + break; + case SASL_NOMECH: + rc = LDAP_AUTH_METHOD_NOT_SUPPORTED; + break; + case SASL_BADAUTH: + rc = LDAP_INVALID_CREDENTIALS; + break; + case SASL_NOAUTHZ: + rc = LDAP_INSUFFICIENT_ACCESS; + break; + case SASL_TOOWEAK: + case SASL_ENCRYPT: + rc = LDAP_INAPPROPRIATE_AUTH; + break; + default: + rc = LDAP_OTHER; + break; + } + + return rc; +} + + int sasl_init( void ) { int rc; @@ -53,8 +99,11 @@ int sasl_init( void ) sasl_set_alloc( ch_malloc, ch_calloc, ch_realloc, ch_free ); - sasl_set_mutex( sasl_pvt_mutex_new, sasl_pvt_mutex_lock, - sasl_pvt_mutex_unlock, sasl_pvt_mutex_dispose ); + sasl_set_mutex( + slap_sasl_mutex_new, + slap_sasl_mutex_lock, + slap_sasl_mutex_unlock, + slap_sasl_mutex_dispose ); rc = sasl_server_init( NULL, "slapd" ); @@ -64,7 +113,16 @@ int sasl_init( void ) return -1; } - rc = sasl_server_new( "ldap", NULL, NULL, NULL, + if( sasl_host == NULL ) { + static char hostname[MAXHOSTNAMELEN+1]; + + if( gethostname( hostname, MAXHOSTNAMELEN ) == 0 ) { + hostname[MAXHOSTNAMELEN] = '\0'; + sasl_host = hostname; + } + } + + rc = sasl_server_new( "ldap", sasl_host, NULL, NULL, SASL_SECURITY_LAYER, &server ); @@ -105,40 +163,49 @@ int sasl_init( void ) mechs, 0, 0 ); supportedSASLMechanisms = str2charray( mechs, "," ); + +#ifdef SLAPD_SPASSWD + lutil_passwd_sasl_conn = server; +#else sasl_dispose( &server ); +#endif return 0; } int sasl_destroy( void ) { +#ifdef SLAPD_SPASSWD + sasl_dispose( &lutil_passwd_sasl_conn ); +#endif charray_free( supportedSASLMechanisms ); return 0; } #ifdef HAVE_CYRUS_SASL int sasl_bind( - Backend *be, Connection *conn, Operation *op, - char *dn, - char *ndn, - char *mech, + const char *dn, + const char *ndn, + const char *mech, struct berval *cred, - char **edn) + 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", + 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_context == NULL ) { + 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; @@ -159,64 +226,82 @@ int sasl_bind( callbacks[cbnum].context = be; ++cbnum; } +#endif + callbacks[cbnum].id = SASL_CB_LIST_END; callbacks[cbnum].proc = NULL; callbacks[cbnum].context = NULL; - - if ( sasl_server_new( "ldap", NULL, be->be_realm, - callbacks, SASL_SECURITY_LAYER, &conn->c_sasl_context ) != SASL_OK ) { - send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED, + + /* 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_context, conn->c_authmech, - cred->bv_val, cred->bv_len, (char **)&response.bv_val, - (unsigned *)&response.bv_len, &errstr ); + + 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, ldap_pvt_sasl_err2ldap( sc ), + send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ), NULL, errstr, NULL, NULL ); } } } else { - sc = sasl_server_step( conn->c_sasl_context, cred->bv_val, cred->bv_len, - (char **)&response.bv_val, (unsigned *)&response.bv_len, &errstr ); + 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, ldap_pvt_sasl_err2ldap( sc ), + send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ), NULL, errstr, NULL, NULL ); } } + if ( sc == SASL_OK ) { char *authzid; - if ( ( sc = sasl_getprop( conn->c_sasl_context, SASL_USERNAME, + if ( ( sc = sasl_getprop( conn->c_sasl_bind_context, SASL_USERNAME, (void **)&authzid ) ) != SASL_OK ) { - send_ldap_result( conn, op, ldap_pvt_sasl_err2ldap( sc ), + send_ldap_result( conn, op, rc = slap_sasl_err2ldap( sc ), NULL, NULL, NULL, NULL ); + } else { - if ( *edn != NULL ) { - free( *edn ); - } - if ( strcasecmp( authzid, "anonymous" ) == 0 ) { - *edn = ch_strdup( "" ); - } else { - *edn = ch_malloc( strlen( authzid ) + sizeof( "authzid=" ) ); + Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: username=%s\n", + authzid, 0, 0); + + if( strncasecmp( authzid, "anonymous", sizeof("anonyous")-1 ) && + ( ( authzid[sizeof("anonymous")] == '\0' ) || + ( authzid[sizeof("anonymous")] == '@' ) ) ) + { + *edn = ch_malloc( sizeof( "authzid=" ) + strlen( authzid ) ); strcpy( *edn, "authzid=" ); strcat( *edn, authzid ); } - /* let FE send result */ - rc = 0; + + send_ldap_result( conn, op, rc = LDAP_SUCCESS, + NULL, NULL, NULL, NULL ); } + } else if ( sc == SASL_CONTINUE ) { - /* - * We set c_bind_in_progress because it doesn't appear - * that connection.c sets this (unless do_bind() itself - * returns LDAP_SASL_BIND_IN_PROGRESS). - */ - conn->c_bind_in_progress = 1; - send_ldap_sasl( conn, op, LDAP_SASL_BIND_IN_PROGRESS, - /* matched */ NULL, /* text */ NULL, /* refs */ NULL, /* controls */ NULL, &response ); + send_ldap_sasl( conn, op, rc = LDAP_SASL_BIND_IN_PROGRESS, + NULL, NULL, NULL, NULL, &response ); } + if ( sc != SASL_CONTINUE && conn->c_sasl_bind_context != NULL ) { + sasl_dispose( &conn->c_sasl_bind_context ); + conn->c_sasl_bind_context = NULL; + } + Debug(LDAP_DEBUG_TRACE, "<== sasl_bind: rc=%d\n", rc, 0, 0); return rc; @@ -225,6 +310,23 @@ int sasl_bind( #else /* no SASL support */ +int sasl_bind( + Connection *conn, + Operation *op, + const char *dn, + const char *ndn, + const char *mech, + struct berval *cred, + char **edn ) +{ + int rc; + + send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, + NULL, "SASL unavailable", NULL, NULL ); + + return rc; +} + int sasl_init( void ) { return 0; } int sasl_destroy( void ) { return 0; } #endif