Change negotiated mechanism:

If application provide one, use it.  If application doesn't
	provide one, use best of server advertised.
Fix SASL/ANONYMOUS (not normally used, but should work)
PLAIN is not currently working... might be local to me as my
Cyrus installation is a bit hosted.
This commit is contained in:
Kurt Zeilenga 2000-05-11 20:16:26 +00:00
parent 7ca81c0a03
commit 643864c569
4 changed files with 751 additions and 707 deletions

View file

@ -552,7 +552,7 @@ main( int argc, char **argv )
if ( ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id, if ( ldap_negotiated_sasl_bind_s( ld, binddn, sasl_authc_id,
sasl_authz_id, sasl_mech, NULL, NULL, NULL ) sasl_authz_id, sasl_mech, NULL, NULL, NULL )
!= LDAP_SUCCESS ) { != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_sasl_bind" ); ldap_perror( ld, "ldap_negotiated_sasl_bind_s" );
return( EXIT_FAILURE ); return( EXIT_FAILURE );
} }
#else #else

1372
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -540,7 +540,7 @@ sasl_err2ldap( int saslerr )
} }
int int
ldap_pvt_sasl_getmechs ( LDAP *ld, LDAP_CONST char *desired, char **pmechlist ) ldap_pvt_sasl_getmechs ( LDAP *ld, char **pmechlist )
{ {
/* we need to query the server for supported mechs anyway */ /* we need to query the server for supported mechs anyway */
LDAPMessage *res, *e; LDAPMessage *res, *e;
@ -548,6 +548,8 @@ ldap_pvt_sasl_getmechs ( LDAP *ld, LDAP_CONST char *desired, char **pmechlist )
char **values, *mechlist, **p; char **values, *mechlist, **p;
int rc; int rc;
Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_getmech\n", 0, 0, 0 );
rc = ldap_search_s( ld, NULL, LDAP_SCOPE_BASE, rc = ldap_search_s( ld, NULL, LDAP_SCOPE_BASE,
NULL, attrs, 0, &res ); NULL, attrs, 0, &res );
@ -570,27 +572,6 @@ ldap_pvt_sasl_getmechs ( LDAP *ld, LDAP_CONST char *desired, char **pmechlist )
return ld->ld_errno; return ld->ld_errno;
} }
if ( desired != NULL ) {
rc = LDAP_INAPPROPRIATE_AUTH;
for ( p = values; *p != NULL; p++ ) {
if ( strcmp( *p, desired ) == 0 ) {
rc = LDAP_SUCCESS;
break;
}
}
if ( rc == LDAP_SUCCESS ) {
/* just return this */
*pmechlist = LDAP_STRDUP( desired );
return LDAP_SUCCESS;
} else {
/* couldn't find it */
ld->ld_errno = LDAP_INAPPROPRIATE_AUTH;
return ld->ld_errno;
}
}
mechlist = array2str( values ); mechlist = array2str( values );
if ( mechlist == NULL ) { if ( mechlist == NULL ) {
ld->ld_errno = LDAP_NO_MEMORY; ld->ld_errno = LDAP_NO_MEMORY;
@ -611,14 +592,14 @@ int
ldap_pvt_sasl_bind( ldap_pvt_sasl_bind(
LDAP *ld, LDAP *ld,
LDAP_CONST char *dn, LDAP_CONST char *dn,
LDAP_CONST char *mechanism, LDAP_CONST char *mechs,
LDAP_CONST sasl_callback_t *callbacks, LDAP_CONST sasl_callback_t *callbacks,
LDAPControl **sctrls, LDAPControl **sctrls,
LDAPControl **cctrls ) LDAPControl **cctrls )
{ {
const char *mech;
int saslrc, rc, msgid, ssf = 0; int saslrc, rc, msgid, ssf = 0;
struct berval ccred, *scred; struct berval ccred, *scred;
char *mechlist = NULL;
char *host; char *host;
sasl_interact_t *client_interact = NULL; sasl_interact_t *client_interact = NULL;
@ -630,26 +611,22 @@ ldap_pvt_sasl_bind(
return ld->ld_errno; return ld->ld_errno;
} }
/* if( ! ber_pvt_sb_in_use( &ld->ld_sb ) ) {
* This connects to the host, side effect being that /* not connected yet */
* ldap_host_connected_to() works. int rc = ldap_open_defconn( ld );
*/
rc = ldap_pvt_sasl_getmechs( ld, mechanism, &mechlist ); if( rc < 0 ) return ld->ld_errno;
if ( rc != LDAP_SUCCESS ) {
return ld->ld_errno;
} }
/* XXX this doesn't work with PF_LOCAL hosts */ /* XXX this doesn't work with PF_LOCAL hosts */
host = ldap_host_connected_to( &ld->ld_sb ); host = ldap_host_connected_to( &ld->ld_sb );
if ( host == NULL ) { if ( host == NULL ) {
LDAP_FREE( mechlist );
ld->ld_errno = LDAP_UNAVAILABLE; ld->ld_errno = LDAP_UNAVAILABLE;
return ld->ld_errno; return ld->ld_errno;
} }
if ( ld->ld_sasl_context != NULL ) { if ( ld->ld_sasl_context != NULL ) {
LDAP_FREE( mechlist );
sasl_dispose( &ld->ld_sasl_context ); sasl_dispose( &ld->ld_sasl_context );
} }
@ -658,7 +635,6 @@ ldap_pvt_sasl_bind(
LDAP_FREE( host ); LDAP_FREE( host );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
LDAP_FREE( mechlist );
ld->ld_errno = sasl_err2ldap( rc ); ld->ld_errno = sasl_err2ldap( rc );
sasl_dispose( &ld->ld_sasl_context ); sasl_dispose( &ld->ld_sasl_context );
return ld->ld_errno; return ld->ld_errno;
@ -668,14 +644,12 @@ ldap_pvt_sasl_bind(
ccred.bv_len = 0; ccred.bv_len = 0;
saslrc = sasl_client_start( ld->ld_sasl_context, saslrc = sasl_client_start( ld->ld_sasl_context,
mechlist, mechs,
NULL, NULL,
&client_interact, &client_interact,
&ccred.bv_val, &ccred.bv_val,
(unsigned int *)&ccred.bv_len, (unsigned int *)&ccred.bv_len,
&mechanism ); &mech );
LDAP_FREE( mechlist );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
ld->ld_errno = sasl_err2ldap( saslrc ); ld->ld_errno = sasl_err2ldap( saslrc );
@ -688,7 +662,7 @@ ldap_pvt_sasl_bind(
do { do {
sasl_interact_t *client_interact = NULL; sasl_interact_t *client_interact = NULL;
rc = ldap_sasl_bind_s( ld, dn, mechanism, &ccred, sctrls, cctrls, &scred ); rc = ldap_sasl_bind_s( ld, dn, mech, &ccred, sctrls, cctrls, &scred );
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
break; break;
} else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) { } else if ( rc != LDAP_SASL_BIND_IN_PROGRESS ) {
@ -732,7 +706,8 @@ ldap_pvt_sasl_bind(
/* based on sample/sample-client.c */ /* based on sample/sample-client.c */
static int static int
ldap_pvt_sasl_getsecret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret) ldap_pvt_sasl_getsecret(sasl_conn_t *conn,
void *context, int id, sasl_secret_t **psecret)
{ {
struct berval *passphrase = (struct berval *)context; struct berval *passphrase = (struct berval *)context;
size_t len; size_t len;
@ -805,9 +780,11 @@ ldap_pvt_sasl_get_option( LDAP *ld, int option, void *arg )
*(int *)arg = -1; *(int *)arg = -1;
break; break;
} }
if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF, &ssf ) if ( sasl_getprop( ld->ld_sasl_context, SASL_SSF,
!= SASL_OK ) (void **) &ssf ) != SASL_OK )
{
return -1; return -1;
}
*(int *)arg = *ssf; *(int *)arg = *ssf;
break; break;
default: default:
@ -855,11 +832,15 @@ ldap_pvt_sasl_set_option( LDAP *ld, int option, void *arg )
* *
* Examples: * Examples:
* ldap_negotiated_sasl_bind_s( ld, NULL, * ldap_negotiated_sasl_bind_s( ld, NULL,
* NULL, NULL, NULL,
* NULL, NULL, NULL, NULL );
*
* ldap_negotiated_sasl_bind_s( ld, NULL,
* "user@OPENLDAP.ORG", NULL, NULL, * "user@OPENLDAP.ORG", NULL, NULL,
* "GSSAPI", NULL, NULL, NULL ); * "GSSAPI", NULL, NULL, NULL );
* *
* ldap_negotiated_sasl_bind_s( ld, NULL, * ldap_negotiated_sasl_bind_s( ld, NULL,
* "manager", "cn=user,dc=openldap,dc=org", NULL, * "manager", "dn:cn=user,dc=openldap,dc=org", NULL,
* "DIGEST-MD5", NULL, NULL, NULL ); * "DIGEST-MD5", NULL, NULL, NULL );
* *
* ldap_negotiated_sasl_bind_s( ld, NULL, * ldap_negotiated_sasl_bind_s( ld, NULL,
@ -885,6 +866,19 @@ ldap_negotiated_sasl_bind_s(
sasl_callback_t callbacks[4]; sasl_callback_t callbacks[4];
int rc; int rc;
Debug( LDAP_DEBUG_TRACE, "ldap_negotiated_sasl_bind_s\n", 0, 0, 0 );
if( saslMechanism == NULL || *saslMechanism == '\0' ) {
char *mechs;
rc = ldap_pvt_sasl_getmechs( ld, &mechs );
if( rc != LDAP_SUCCESS ) {
return rc;
}
saslMechanism = mechs;
}
/* SASL Authentication Identity */ /* SASL Authentication Identity */
callbacks[n=0].id = SASL_CB_AUTHNAME; callbacks[n=0].id = SASL_CB_AUTHNAME;
callbacks[n].proc = ldap_pvt_sasl_getsimple; callbacks[n].proc = ldap_pvt_sasl_getsimple;

View file

@ -239,7 +239,7 @@ do_bind(
edn = NULL; edn = NULL;
rc = sasl_bind( conn, op, dn, ndn, mech, &cred, &edn ); rc = sasl_bind( conn, op, dn, ndn, mech, &cred, &edn );
if( rc == LDAP_SUCCESS && edn != NULL ) { if( rc == LDAP_SUCCESS ) {
ldap_pvt_thread_mutex_lock( &conn->c_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_mutex );
#ifdef HAVE_CYRUS_SASL #ifdef HAVE_CYRUS_SASL
assert( conn->c_sasl_bind_context == NULL ); assert( conn->c_sasl_bind_context == NULL );