X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconnection.c;h=766ca439bf0ce53f5c10611bfe00a655a4ff1c87;hb=f8fb4aca7668c722f41941be719203aa8c298e12;hp=31c8b976fdda82887479fa3ceff48b4e79980408;hpb=926b4547653668c1041b90b8562672b7e0af8475;p=openldap diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 31c8b976fd..766ca439bf 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1,6 +1,6 @@ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -14,6 +14,7 @@ #include #include #include +#include #include "ldap_pvt.h" #include "lutil.h" @@ -300,7 +301,13 @@ static Connection* connection_get( ber_socket_t s ) assert( c->c_conn_state != SLAP_C_INVALID ); assert( sd != AC_SOCKET_INVALID ); - c->c_activitytime = slap_get_time(); +#ifdef SLAPD_MONITOR + c->c_activitytime = slap_get_time(); +#else + if( global_idletimeout > 0 ) { + c->c_activitytime = slap_get_time(); + } +#endif } return c; @@ -358,7 +365,7 @@ long connection_init( #else { - unsigned int i; + ber_socket_t i; c = NULL; @@ -406,16 +413,21 @@ long connection_init( if( c->c_struct_state == SLAP_C_UNINITIALIZED ) { c->c_authmech = NULL; - c->c_dn = NULL; - c->c_cdn = NULL; + c->c_dn.bv_val = NULL; + c->c_dn.bv_len = 0; + c->c_ndn.bv_val = NULL; + c->c_ndn.bv_len = 0; + c->c_cdn.bv_val = NULL; + c->c_cdn.bv_len = 0; + c->c_groups = NULL; c->c_listener_url = NULL; c->c_peer_domain = NULL; c->c_peer_name = NULL; c->c_sock_name = NULL; - c->c_ops = NULL; - c->c_pending_ops = NULL; + LDAP_STAILQ_INIT(&c->c_ops); + LDAP_STAILQ_INIT(&c->c_pending_ops); c->c_sasl_bind_mech = NULL; c->c_sasl_context = NULL; @@ -442,14 +454,16 @@ long connection_init( assert( c->c_struct_state == SLAP_C_UNUSED ); assert( c->c_authmech == NULL ); - assert( c->c_dn == NULL ); - assert( c->c_cdn == NULL ); + assert( c->c_dn.bv_val == NULL ); + assert( c->c_ndn.bv_val == NULL ); + assert( c->c_cdn.bv_val == NULL ); + assert( c->c_groups == NULL ); assert( c->c_listener_url == NULL ); assert( c->c_peer_domain == NULL ); assert( c->c_peer_name == NULL ); assert( c->c_sock_name == NULL ); - assert( c->c_ops == NULL ); - assert( c->c_pending_ops == NULL ); + assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); + assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); assert( c->c_sasl_bind_mech == NULL ); assert( c->c_sasl_context == NULL ); assert( c->c_sasl_extra == NULL ); @@ -472,20 +486,27 @@ long connection_init( /* set to zero until bind, implies LDAP_VERSION3 */ c->c_protocol = 0; - c->c_activitytime = c->c_starttime = slap_get_time(); +#ifdef SLAPD_MONITOR + c->c_activitytime = c->c_starttime = slap_get_time(); +#else + if( global_idletimeout > 0 ) { + c->c_activitytime = c->c_starttime = slap_get_time(); + } +#endif #ifdef LDAP_CONNECTIONLESS c->c_is_udp = 0; if (tls_udp_option == 2) { c->c_is_udp = 1; - c->c_protocol = LDAP_VERSION2; #ifdef LDAP_DEBUG ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_PROVIDER, (void*)"udp_" ); #endif ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_udp, LBER_SBIOD_LEVEL_PROVIDER, (void *)&s ); + ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); } else #endif { @@ -496,8 +517,6 @@ long connection_init( ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_tcp, LBER_SBIOD_LEVEL_PROVIDER, (void *)&s ); } - ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_readahead, - LBER_SBIOD_LEVEL_PROVIDER, NULL ); #ifdef LDAP_DEBUG ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, @@ -562,18 +581,36 @@ void connection2anonymous( Connection *c ) c->c_authmech = NULL; } - if(c->c_dn != NULL) { - free(c->c_dn); - c->c_dn = NULL; + if(c->c_dn.bv_val != NULL) { + free(c->c_dn.bv_val); + c->c_dn.bv_val = NULL; + } + c->c_dn.bv_len = 0; + if(c->c_ndn.bv_val != NULL) { + free(c->c_ndn.bv_val); + c->c_ndn.bv_val = NULL; } + c->c_ndn.bv_len = 0; - if(c->c_cdn != NULL) { - free(c->c_cdn); - c->c_cdn = NULL; + if(c->c_cdn.bv_val != NULL) { + free(c->c_cdn.bv_val); + c->c_cdn.bv_val = NULL; } + c->c_cdn.bv_len = 0; c->c_authc_backend = NULL; c->c_authz_backend = NULL; + + { + GroupAssertion *g, *n; + for (g = c->c_groups; g; g=n) + { + n = g->next; + free(g); + } + c->c_groups = NULL; + } + } static void @@ -586,7 +623,7 @@ connection_destroy( Connection *c ) assert( c != NULL ); assert( c->c_struct_state != SLAP_C_UNUSED ); assert( c->c_conn_state != SLAP_C_INVALID ); - assert( c->c_ops == NULL ); + assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); backend_connection_destroy(c); @@ -685,17 +722,16 @@ static void connection_abandon( Connection *c ) Operation *o; - for( o = c->c_ops; o != NULL; o = o->o_next ) { + LDAP_STAILQ_FOREACH(o, &c->c_ops, o_next) { ldap_pvt_thread_mutex_lock( &o->o_abandonmutex ); o->o_abandon = 1; ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex ); } /* remove pending operations */ - for( o = slap_op_pop( &c->c_pending_ops ); - o != NULL; - o = slap_op_pop( &c->c_pending_ops ) ) - { + while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) { + LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next ); + LDAP_STAILQ_NEXT(o, o_next) = NULL; slap_op_free( o ); } } @@ -749,7 +785,7 @@ static void connection_close( Connection *c ) /* note: connections_mutex and c_mutex should be locked by caller */ ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd ); - if( c->c_ops != NULL ) { + if( !LDAP_STAILQ_EMPTY(&c->c_ops) ) { #ifdef NEW_LOGGING LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1, "connection_close: conn %d deferring sd %d\n", @@ -952,7 +988,8 @@ operations_error: conn->c_n_ops_executing--; conn->c_n_ops_completed++; - slap_op_remove( &conn->c_ops, arg->co_op ); + LDAP_STAILQ_REMOVE( &conn->c_ops, arg->co_op, slap_op, o_next); + LDAP_STAILQ_NEXT(arg->co_op, o_next) = NULL; slap_op_free( arg->co_op ); arg->co_op = NULL; arg->co_conn = NULL; @@ -1039,8 +1076,10 @@ int connection_read(ber_socket_t s) if ( c->c_is_tls && c->c_needs_tls_accept ) { rc = ldap_pvt_tls_accept( c->c_sb, NULL ); if ( rc < 0 ) { +#if 0 /* required by next #if 0 */ struct timeval tv; fd_set rfd; +#endif #ifdef NEW_LOGGING LDAP_LOG(( "connection", LDAP_LEVEL_ERR, @@ -1200,6 +1239,8 @@ connection_input( char peername[sizeof("IP=255.255.255.255:65336")]; len = ber_int_sb_read(conn->c_sb, &peeraddr, sizeof(struct sockaddr)); + if (len != sizeof(struct sockaddr)) + return 1; sprintf( peername, "IP=%s:%d", inet_ntoa( peeraddr.sa_in_addr.sin_addr ), (unsigned) ntohs( peeraddr.sa_in_addr.sin_port ) ); @@ -1251,11 +1292,6 @@ connection_input( ber_free( ber, 1 ); return -1; } -#ifdef LDAP_CONNECTIONLESS - if (conn->c_is_udp) { - tag = ber_get_stringa( ber, &cdn ); - } -#endif if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) { /* log, close and send error */ @@ -1273,19 +1309,23 @@ connection_input( } #ifdef LDAP_CONNECTIONLESS - if (conn->c_is_udp && (tag != LDAP_REQ_ABANDON && - tag != LDAP_REQ_SEARCH)) - { + if (conn->c_is_udp) { + if (tag == LBER_OCTETSTRING) { + ber_get_stringa( ber, &cdn ); + tag = ber_peek_tag(ber, &len); + } + if (tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH) { #ifdef NEW_LOGGING - LDAP_LOG(( "connection", LDAP_LEVEL_ERR, - "connection_input: conn %d invalid req for UDP 0x%lx.\n", - conn->c_connid, tag )); + LDAP_LOG(( "connection", LDAP_LEVEL_ERR, + "connection_input: conn %d invalid req for UDP 0x%lx.\n", + conn->c_connid, tag )); #else - Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, - 0 ); + Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, + 0 ); #endif - ber_free( ber, 1 ); - return 0; + ber_free( ber, 1 ); + return 0; + } } #endif if(tag == LDAP_REQ_BIND) { @@ -1297,7 +1337,10 @@ connection_input( #ifdef LDAP_CONNECTIONLESS op->o_peeraddr = peeraddr; - op->o_dn = cdn; + if (cdn) { + op->o_dn = cdn; + op->o_protocol = LDAP_VERSION2; + } #endif if ( conn->c_conn_state == SLAP_C_BINDING || conn->c_conn_state == SLAP_C_CLOSING ) @@ -1310,7 +1353,7 @@ connection_input( Debug( LDAP_DEBUG_ANY, "deferring operation\n", 0, 0, 0 ); #endif conn->c_n_ops_pending++; - slap_op_add( &conn->c_pending_ops, op ); + LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next ); } else { conn->c_n_ops_executing++; @@ -1393,10 +1436,9 @@ connection_resched( Connection *conn ) return 0; } - for( op = slap_op_pop( &conn->c_pending_ops ); - op != NULL; - op = slap_op_pop( &conn->c_pending_ops ) ) - { + while ((op = LDAP_STAILQ_FIRST( &conn->c_pending_ops )) != NULL) { + LDAP_STAILQ_REMOVE_HEAD( &conn->c_pending_ops, o_next ); + LDAP_STAILQ_NEXT(op, o_next) = NULL; /* pending operations should not be marked for abandonment */ assert(!op->o_abandon); @@ -1426,21 +1468,24 @@ static int connection_op_activate( Connection *conn, Operation *op ) arg->co_conn = conn; arg->co_op = op; - if (!arg->co_op->o_dn) { + if (!arg->co_op->o_dn.bv_len) { arg->co_op->o_authz = conn->c_authz; - arg->co_op->o_dn = ch_strdup( conn->c_dn != NULL ? conn->c_dn : "" ); + arg->co_op->o_dn.bv_val = ch_strdup( conn->c_dn.bv_val ? + conn->c_dn.bv_val : "" ); + arg->co_op->o_ndn.bv_val = ch_strdup( conn->c_ndn.bv_val ? + conn->c_ndn.bv_val : "" ); } - arg->co_op->o_ndn = ch_strdup( arg->co_op->o_dn ); - (void) dn_normalize( arg->co_op->o_ndn ); 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_protocol = conn->c_protocol + if (!arg->co_op->o_protocol) { + arg->co_op->o_protocol = conn->c_protocol ? conn->c_protocol : LDAP_VERSION3; + } arg->co_op->o_connid = conn->c_connid; - slap_op_add( &conn->c_ops, arg->co_op ); + LDAP_STAILQ_INSERT_TAIL( &conn->c_ops, arg->co_op, o_next ); status = ldap_pvt_thread_pool_submit( &connection_pool, connection_operation, (void *) arg ); @@ -1538,13 +1583,13 @@ int connection_internal_open( Connection **conn, LDAP **ldp, const char *id ) /* A search operation, number 0 */ op = slap_op_alloc( NULL, 0, LDAP_REQ_SEARCH, 0); - op->o_ndn = ch_strdup( id ); + op->o_ndn.bv_val = ch_strdup( id ); + op->o_ndn.bv_len = strlen( id ); op->o_protocol = LDAP_VERSION3; (*conn) = connection_get( fd[1] ); - (*conn)->c_ops = op; - (*conn)->c_conn_state = SLAP_C_ACTIVE; - + LDAP_STAILQ_INSERT_HEAD( &(*conn)->c_ops, op, o_next); + (*conn)->c_conn_state = SLAP_C_ACTIVE; /* Create the client side of the connection */ rc = ldap_open_internal_connection( ldp, &(fd[0]) ); @@ -1562,9 +1607,10 @@ int connection_internal_open( Connection **conn, LDAP **ldp, const char *id ) void connection_internal_close( Connection *conn ) { - Operation *op = conn->c_ops; + Operation *op = LDAP_STAILQ_FIRST(&conn->c_ops); - slap_op_remove( &conn->c_ops, op ); + LDAP_STAILQ_REMOVE_HEAD(&conn->c_ops, o_next); + LDAP_STAILQ_NEXT(op, o_next) = NULL; slap_op_free( op ); connection_closing( conn ); connection_close( conn );