X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconnection.c;h=742934113b1af7441130a5b5c0c401f01c2db79b;hb=05752bea50e1bcca485aad61ca4a291cc6e01b7c;hp=fc0ebed127cb71edb58e182ca8918c51675f6148;hpb=1d8cee1c70148ae0a905df1cc90acecc25ef92eb;p=openldap
diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c
index fc0ebed127..742934113b 100644
--- a/servers/slapd/connection.c
+++ b/servers/slapd/connection.c
@@ -1,7 +1,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2008 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -196,21 +196,22 @@ int connections_shutdown(void)
ber_socket_t i;
for ( i = 0; i < dtblsize; i++ ) {
- ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
- if( connections[i].c_struct_state == SLAP_C_USED ) {
-
- /* give persistent clients a chance to cleanup */
- if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
- ldap_pvt_thread_pool_submit( &connection_pool,
- connections[i].c_clientfunc, connections[i].c_clientarg );
- continue;
- } else {
- /* c_mutex is locked */
- connection_closing( &connections[i], "slapd shutdown" );
- connection_close( &connections[i] );
+ if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) {
+ ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
+ if( connections[i].c_struct_state == SLAP_C_USED ) {
+
+ /* give persistent clients a chance to cleanup */
+ if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
+ ldap_pvt_thread_pool_submit( &connection_pool,
+ connections[i].c_clientfunc, connections[i].c_clientarg );
+ } else {
+ /* c_mutex is locked */
+ connection_closing( &connections[i], "slapd shutdown" );
+ connection_close( &connections[i] );
+ }
}
+ ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
}
- ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
}
return 0;
@@ -309,6 +310,15 @@ static Connection* connection_get( ber_socket_t s )
assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+#ifdef HAVE_WINSOCK
+ /* Avoid race condition after releasing
+ * connections_mutex
+ */
+ if ( sd != s ) {
+ ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+ return NULL;
+ }
+#endif
if( c->c_struct_state != SLAP_C_USED ) {
/* connection must have been closed due to resched */
@@ -737,11 +747,12 @@ connection_destroy( Connection *c )
slapd_remove( sd, sb, 1, 0, 0 );
if ( close_reason == NULL ) {
- close_reason = "";
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed\n",
+ connid, (long) sd, 0, 0, 0 );
+ } else {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n",
+ connid, (long) sd, close_reason, 0, 0 );
}
-
- Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n",
- connid, (long) sd, close_reason, 0, 0 );
}
}
@@ -1521,11 +1532,11 @@ connection_input( Connection *conn )
ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
+ if ( err != EWOULDBLOCK && err != EAGAIN ) {
+ /* log, close and send error */
Debug( LDAP_DEBUG_TRACE,
"ber_get_next on fd %d failed errno=%d (%s)\n",
sd, err, sock_errstr(err) );
- if ( err != EWOULDBLOCK && err != EAGAIN ) {
- /* log, close and send error */
ber_free( conn->c_currentber, 1 );
conn->c_currentber = NULL;
@@ -1701,6 +1712,9 @@ connection_resched( Connection *conn )
{
Operation *op;
+ if( conn->c_writewaiter )
+ return 0;
+
if( conn->c_conn_state == SLAP_C_CLOSING ) {
ber_socket_t sd;
ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
@@ -1712,7 +1726,7 @@ connection_resched( Connection *conn )
return 0;
}
- if( conn->c_conn_state != SLAP_C_ACTIVE || conn->c_writewaiter ) {
+ if( conn->c_conn_state != SLAP_C_ACTIVE ) {
/* other states need different handling */
return 0;
}
@@ -1794,13 +1808,14 @@ static int connection_bind_cb( Operation *op, SlapReply *rs )
/* log authorization identity */
Statslog( LDAP_DEBUG_STATS,
- "%s BIND dn=\"%s\" mech=%s ssf=%d\n",
+ "%s BIND dn=\"%s\" mech=%s sasl_ssf=%d ssf=%d\n",
op->o_log_prefix,
BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val,
- op->o_conn->c_authmech.bv_val, op->orb_ssf, 0 );
+ op->o_conn->c_authmech.bv_val,
+ op->orb_ssf, op->o_conn->c_ssf );
Debug( LDAP_DEBUG_TRACE,
- "do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
+ "do_bind: SASL/%s bind: dn=\"%s\" sasl_ssf=%d\n",
op->o_conn->c_authmech.bv_val,
BER_BVISNULL( &op->o_conn->c_dn ) ? "" : op->o_conn->c_dn.bv_val,
op->orb_ssf );
@@ -1939,6 +1954,36 @@ int connection_write(ber_socket_t s)
return 0;
}
+#ifdef LDAP_SLAPI
+typedef struct conn_fake_extblock {
+ void *eb_conn;
+ void *eb_op;
+} conn_fake_extblock;
+
+static void
+connection_fake_destroy(
+ void *key,
+ void *data )
+{
+ Connection conn = {0};
+ Operation op = {0};
+ Opheader ohdr = {0};
+
+ conn_fake_extblock *eb = data;
+
+ op.o_hdr = &ohdr;
+ op.o_hdr->oh_extensions = eb->eb_op;
+ conn.c_extensions = eb->eb_conn;
+ op.o_conn = &conn;
+ conn.c_connid = -1;
+ op.o_connid = -1;
+
+ ber_memfree_x( eb, NULL );
+ slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, &op );
+ slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, &conn );
+}
+#endif
+
void
connection_fake_init(
Connection *conn,
@@ -1969,8 +2014,24 @@ connection_fake_init(
connection_init_log_prefix( op );
#ifdef LDAP_SLAPI
- slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
- slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
+ if ( slapi_plugins_used ) {
+ conn_fake_extblock *eb = NULL;
+
+ /* Use thread keys to make sure these eventually get cleaned up */
+ if ( ldap_pvt_thread_pool_getkey( ctx, connection_fake_init, &eb,
+ NULL )) {
+ eb = ch_malloc( sizeof( *eb ));
+ slapi_int_create_object_extensions( SLAPI_X_EXT_CONNECTION, conn );
+ slapi_int_create_object_extensions( SLAPI_X_EXT_OPERATION, op );
+ eb->eb_conn = conn->c_extensions;
+ eb->eb_op = op->o_hdr->oh_extensions;
+ ldap_pvt_thread_pool_setkey( ctx, connection_fake_init, eb,
+ connection_fake_destroy );
+ } else {
+ conn->c_extensions = eb->eb_conn;
+ op->o_hdr->oh_extensions = eb->eb_op;
+ }
+ }
#endif /* LDAP_SLAPI */
slap_op_time( &op->o_time, &op->o_tincr );