mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-01 12:39:35 -05:00
More bind changes to support SASL/DIGEST.
Added configuration support for "digest-realm <realm>" configure directive. Added connection state and bind_in_progress fields to cn=monitor connection attribute.
This commit is contained in:
parent
c8e37af0ca
commit
b7bbc7504d
7 changed files with 138 additions and 49 deletions
|
|
@ -385,6 +385,9 @@ backend_db_init(
|
|||
be->be_sizelimit = defsize;
|
||||
be->be_timelimit = deftime;
|
||||
|
||||
be->be_realm = global_realm != NULL
|
||||
? ch_strdup( global_realm ) : NULL;
|
||||
|
||||
if(bi->bi_db_init) {
|
||||
rc = bi->bi_db_init( be );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ do_bind(
|
|||
char *mech;
|
||||
char *cdn, *ndn;
|
||||
ber_tag_t tag;
|
||||
int rc;
|
||||
int rc = LDAP_SUCCESS;
|
||||
struct berval cred;
|
||||
Backend *be;
|
||||
|
||||
|
|
@ -50,6 +50,25 @@ do_bind(
|
|||
mech = NULL;
|
||||
cred.bv_val = NULL;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
/* Force to connection to "anonymous" until bind succeeds.
|
||||
* This may need to be relocated or done on a case by case basis
|
||||
* to handle certain SASL mechanisms.
|
||||
*/
|
||||
|
||||
if ( conn->c_cdn != NULL ) {
|
||||
free( conn->c_cdn );
|
||||
conn->c_cdn = NULL;
|
||||
}
|
||||
|
||||
if ( conn->c_dn != NULL ) {
|
||||
free( conn->c_dn );
|
||||
conn->c_dn = NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
/*
|
||||
* Parse the bind request. It looks like this:
|
||||
*
|
||||
|
|
@ -59,8 +78,14 @@ do_bind(
|
|||
* authentication CHOICE {
|
||||
* simple [0] OCTET STRING -- passwd
|
||||
* krbv42ldap [1] OCTET STRING
|
||||
* krbv42dsa [1] OCTET STRING
|
||||
* krbv42dsa [2] OCTET STRING
|
||||
* SASL [3] SaslCredentials
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* SaslCredentials ::= SEQUENCE {
|
||||
* mechanism LDAPString,
|
||||
* credentials OCTET STRING OPTIONAL
|
||||
* }
|
||||
*/
|
||||
|
||||
|
|
@ -152,26 +177,58 @@ do_bind(
|
|||
NULL, "sasl mechanism not supported" );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
if ( conn->c_authmech != NULL ) {
|
||||
assert( conn->c_bind_in_progress );
|
||||
|
||||
if((strcmp(conn->c_authmech, mech) != 0)) {
|
||||
/* mechanism changed, cancel in progress bind */
|
||||
conn->c_bind_in_progress = 0;
|
||||
if( conn->c_authstate != NULL ) {
|
||||
free(conn->c_authstate);
|
||||
conn->c_authstate = NULL;
|
||||
}
|
||||
free(conn->c_authmech);
|
||||
conn->c_authmech = NULL;
|
||||
}
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
} else {
|
||||
assert( !conn->c_bind_in_progress );
|
||||
assert( conn->c_authmech == NULL );
|
||||
assert( conn->c_authstate == NULL );
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
if ( conn->c_authmech != NULL ) {
|
||||
assert( conn->c_bind_in_progress );
|
||||
|
||||
/* cancel in progress bind */
|
||||
conn->c_bind_in_progress = 0;
|
||||
|
||||
if( conn->c_authstate != NULL ) {
|
||||
free(conn->c_authstate);
|
||||
conn->c_authstate = NULL;
|
||||
}
|
||||
free(conn->c_authmech);
|
||||
conn->c_authmech = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
conn->c_protocol = version;
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
/* accept null binds */
|
||||
if ( ndn == NULL || *ndn == '\0' ) {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
if ( conn->c_cdn != NULL ) {
|
||||
free( conn->c_cdn );
|
||||
conn->c_cdn = NULL;
|
||||
}
|
||||
|
||||
if ( conn->c_dn != NULL ) {
|
||||
free( conn->c_dn );
|
||||
conn->c_dn = NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
/*
|
||||
* we already forced connection to "anonymous", we just
|
||||
* need to send success
|
||||
*/
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
@ -184,27 +241,13 @@ do_bind(
|
|||
|
||||
if ( (be = select_backend( ndn )) == NULL ) {
|
||||
if ( cred.bv_len == 0 ) {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
if ( conn->c_cdn != NULL ) {
|
||||
free( conn->c_cdn );
|
||||
conn->c_cdn = NULL;
|
||||
}
|
||||
|
||||
if ( conn->c_dn != NULL ) {
|
||||
free( conn->c_dn );
|
||||
conn->c_dn = NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS,
|
||||
NULL, NULL );
|
||||
|
||||
} else if ( default_referral && *default_referral ) {
|
||||
send_ldap_result( conn, op, rc = LDAP_PARTIAL_RESULTS,
|
||||
NULL, default_referral );
|
||||
|
||||
} else {
|
||||
send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
|
||||
NULL, default_referral );
|
||||
|
|
@ -222,19 +265,9 @@ do_bind(
|
|||
if ( (*be->be_bind)( be, conn, op, ndn, method, mech, &cred, &edn ) == 0 ) {
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
|
||||
|
||||
conn->c_protocol = version;
|
||||
|
||||
if ( conn->c_cdn != NULL ) {
|
||||
free( conn->c_cdn );
|
||||
}
|
||||
|
||||
conn->c_cdn = cdn;
|
||||
cdn = NULL;
|
||||
|
||||
if ( conn->c_dn != NULL ) {
|
||||
free( conn->c_dn );
|
||||
}
|
||||
|
||||
if(edn != NULL) {
|
||||
conn->c_dn = edn;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ int global_default_access = ACL_READ;
|
|||
char *replogfile;
|
||||
int global_lastmod;
|
||||
int global_idletimeout = 0;
|
||||
char *global_realm = NULL;
|
||||
char *ldap_srvtab = "";
|
||||
|
||||
char *slapd_pid_file = NULL;
|
||||
|
|
@ -144,7 +145,28 @@ read_config( char *fname )
|
|||
|
||||
slapd_args_file = ch_strdup( cargv[1] );
|
||||
|
||||
/* set size limit */
|
||||
/* set DIGEST realm */
|
||||
} else if ( strcasecmp( cargv[0], "digest-realm" ) == 0 ) {
|
||||
if ( cargc < 2 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: missing realm in \"digest-realm <realm>\" line\n",
|
||||
fname, lineno, 0 );
|
||||
return( 1 );
|
||||
}
|
||||
if ( be != NULL ) {
|
||||
be->be_realm = ch_strdup( cargv[1] );
|
||||
|
||||
} else if ( global_realm != NULL ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: already set global realm!\n",
|
||||
fname, lineno, 0 );
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
global_realm = ch_strdup( cargv[1] );
|
||||
}
|
||||
|
||||
/* set time limit */
|
||||
} else if ( strcasecmp( cargv[0], "sizelimit" ) == 0 ) {
|
||||
if ( cargc < 2 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@ static unsigned long conn_nextid = 0;
|
|||
#define SLAP_C_BINDING 0x03 /* binding */
|
||||
#define SLAP_C_CLOSING 0x04 /* closing */
|
||||
|
||||
char* connection_state2str( int state ) {
|
||||
switch( state ) {
|
||||
case SLAP_C_INVALID: return "!";
|
||||
case SLAP_C_INACTIVE: return "|";
|
||||
case SLAP_C_ACTIVE: return "";
|
||||
case SLAP_C_BINDING: return "B";
|
||||
case SLAP_C_CLOSING: return "C";
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
|
||||
static Connection* connection_get( ber_socket_t s );
|
||||
|
||||
static int connection_input( Connection *c );
|
||||
|
|
@ -326,6 +338,8 @@ long connection_init(
|
|||
c->c_client_addr = NULL;
|
||||
c->c_ops = NULL;
|
||||
c->c_pending_ops = NULL;
|
||||
c->c_authmech = NULL;
|
||||
c->c_authstate = NULL;
|
||||
|
||||
c->c_sb = ber_sockbuf_alloc( );
|
||||
|
||||
|
|
@ -346,6 +360,8 @@ long connection_init(
|
|||
assert( c->c_client_addr == NULL );
|
||||
assert( c->c_ops == NULL );
|
||||
assert( c->c_pending_ops == NULL );
|
||||
assert( c->c_authmech == NULL );
|
||||
assert( c->c_authstate == NULL );
|
||||
|
||||
c->c_client_name = ch_strdup( name == NULL ? "" : name );
|
||||
c->c_client_addr = ch_strdup( addr );
|
||||
|
|
@ -416,6 +432,14 @@ connection_destroy( Connection *c )
|
|||
free(c->c_client_addr);
|
||||
c->c_client_addr = NULL;
|
||||
}
|
||||
if(c->c_authmech != NULL ) {
|
||||
free(c->c_authmech);
|
||||
c->c_authmech = NULL;
|
||||
}
|
||||
if(c->c_authstate != NULL ) {
|
||||
free(c->c_authstate);
|
||||
c->c_authstate = NULL;
|
||||
}
|
||||
|
||||
if ( ber_pvt_sb_in_use(c->c_sb) ) {
|
||||
int sd = ber_pvt_sb_get_desc(c->c_sb);
|
||||
|
|
@ -916,10 +940,10 @@ static int connection_op_activate( Connection *conn, Operation *op )
|
|||
|
||||
arg->co_op->o_protocol = conn->c_protocol;
|
||||
|
||||
arg->co_op->o_authtype = conn->c_authtype;
|
||||
arg->co_op->o_authmech = conn->c_authmech != NULL
|
||||
? ch_strdup( conn->c_authmech ) : NULL;
|
||||
arg->co_op->o_authtype = conn->c_authtype;
|
||||
|
||||
|
||||
slap_op_add( &conn->c_ops, arg->co_op );
|
||||
|
||||
if(tag == LDAP_REQ_BIND) {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ monitor_info( Connection *conn, Operation *op )
|
|||
"%ld : %ld "
|
||||
": %ld/%ld/%ld/%ld "
|
||||
": %ld/%ld/%ld "
|
||||
": %s%s%s%s "
|
||||
": %s%s%s%s%s%s "
|
||||
": %s : %s : %s "
|
||||
": %s : %s",
|
||||
|
||||
|
|
@ -127,6 +127,8 @@ monitor_info( Connection *conn, Operation *op )
|
|||
c->c_writewaiter ? "w" : "",
|
||||
c->c_ops != NULL ? "x" : "",
|
||||
c->c_pending_ops != NULL ? "p" : "",
|
||||
connection_state2str( c->c_conn_state ),
|
||||
c->c_bind_in_progress ? "S" : "",
|
||||
|
||||
c->c_cdn ? c->c_cdn : "<anonymous>",
|
||||
c->c_client_addr ? c->c_client_addr : "unknown",
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ long connection_init LDAP_P((
|
|||
|
||||
void connection_closing LDAP_P(( Connection *c ));
|
||||
int connection_state_closing LDAP_P(( Connection *c ));
|
||||
char *connection_state2str LDAP_P(( int state ));
|
||||
|
||||
int connection_write LDAP_P((ber_socket_t s));
|
||||
int connection_read LDAP_P((ber_socket_t s));
|
||||
|
|
@ -331,6 +332,7 @@ extern int global_default_access;
|
|||
extern int global_lastmod;
|
||||
extern int global_idletimeout;
|
||||
extern int global_schemacheck;
|
||||
extern char *global_realm;
|
||||
extern int lber_debug;
|
||||
extern int ldap_syslog;
|
||||
|
||||
|
|
|
|||
|
|
@ -363,6 +363,8 @@ struct backend_db {
|
|||
char *be_update_ndn; /* allowed to make changes (in replicas) */
|
||||
int be_lastmod; /* keep track of lastmodified{by,time} */
|
||||
|
||||
char *be_realm;
|
||||
|
||||
void *be_private; /* anything the backend database needs */
|
||||
};
|
||||
|
||||
|
|
@ -542,8 +544,9 @@ typedef struct slap_conn {
|
|||
char *c_cdn; /* DN provided by the client */
|
||||
char *c_dn; /* DN bound to this conn */
|
||||
ber_int_t c_protocol; /* version of the LDAP protocol used by client */
|
||||
ber_tag_t c_authtype; /* auth method used to bind c_dn */
|
||||
ber_tag_t c_authtype;/* auth method used to bind c_dn */
|
||||
char *c_authmech; /* SASL mechanism used to bind c_dn */
|
||||
void *c_authstate; /* SASL state data */
|
||||
|
||||
Operation *c_ops; /* list of operations being processed */
|
||||
Operation *c_pending_ops; /* list of pending operations */
|
||||
|
|
|
|||
Loading…
Reference in a new issue