X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fresult.c;h=af4498bc9f41d300d220800eadb58c5f41a31842;hb=29b1e1f0babf07875ecb75a56cc6050ef4c82897;hp=0ef82a7b3e36e03f85a4a71a91040153fe182064;hpb=42e0d83cb3a1a1c5b25183f1ab74ce7edbe25de7;p=openldap diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 0ef82a7b3e..af4498bc9f 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -1,30 +1,18 @@ /* result.c - routines to send ldap results, errors, and referrals */ -#include -#include -#include -#include -#include -#include -#include -#include #include "portable.h" -#include "slap.h" -#ifndef SYSERRLIST_IN_STDIO -extern int sys_nerr; -extern char *sys_errlist[]; -#endif -extern int active_threads; -extern pthread_mutex_t active_threads_mutex; -extern pthread_mutex_t new_conn_mutex; -extern pthread_t listener_tid; -extern struct acl *acl_get_applicable(); -extern long num_entries_sent; -extern long num_bytes_sent; -extern pthread_mutex_t num_sent_mutex; +#include + +#include +#include +#include +#include +#include +#include /* get close() */ + +#include "slap.h" -void close_connection(); static void send_ldap_result2( @@ -40,6 +28,9 @@ send_ldap_result2( int rc, sd; unsigned long tag, bytes; + if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') ) + err = LDAP_NO_SUCH_OBJECT; + Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n", err, matched ? matched : "", text ? text : "" ); @@ -61,7 +52,7 @@ send_ldap_result2( break; } -#ifdef COMPAT30 +#ifdef LDAP_COMPAT30 if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER )) == NULLBER ) { #else @@ -71,13 +62,13 @@ send_ldap_result2( return; } -#ifdef CLDAP +#ifdef LDAP_CONNECTIONLESS if ( op->o_cldap ) { rc = ber_printf( ber, "{is{t{ess}}}", op->o_msgid, "", tag, err, matched ? matched : "", text ? text : "" ); } else #endif -#ifdef COMPAT30 +#ifdef LDAP_COMPAT30 if ( conn->c_version == 30 ) { rc = ber_printf( ber, "{it{{ess}}}", op->o_msgid, tag, err, matched ? matched : "", text ? text : "" ); @@ -121,8 +112,14 @@ send_ldap_result2( pthread_mutex_lock( &active_threads_mutex ); active_threads--; conn->c_writewaiter = 1; - pthread_kill( listener_tid, SIGUSR1 ); + + pthread_kill( listener_tid, LDAP_SIGUSR1 ); + pthread_cond_wait( &conn->c_wcv, &active_threads_mutex ); + + if( active_threads < 1 ) { + pthread_cond_signal(&active_threads_cond); + } pthread_mutex_unlock( &active_threads_mutex ); pthread_yield(); @@ -151,7 +148,7 @@ send_ldap_result( char *text ) { -#ifdef CLDAP +#ifdef LDAP_CONNECTIONLESS if ( op->o_cldap ) { SAFEMEMCPY( (char *)conn->c_sb.sb_useaddr, &op->o_clientaddr, sizeof( struct sockaddr )); @@ -192,54 +189,76 @@ send_search_entry( Attribute *a; int i, rc, bytes, sd; struct acl *acl; + char *edn; Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 ); - if ( ! access_allowed( be, conn, op, e, "entry", NULL, op->o_dn, - ACL_READ ) ) { + if ( ! access_allowed( be, conn, op, e, + "entry", NULL, ACL_READ ) ) + { Debug( LDAP_DEBUG_ACL, "acl: access to entry not allowed\n", 0, 0, 0 ); return( 1 ); } -#ifdef COMPAT30 + edn = e->e_ndn; + +#ifdef LDAP_COMPAT30 if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER )) - == NULLBER ) { + == NULLBER ) #else - if ( (ber = der_alloc()) == NULLBER ) { + if ( (ber = der_alloc()) == NULLBER ) #endif + { Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, - "ber_alloc" ); - return( 1 ); + "ber_alloc" ); + goto error_return; } -#ifdef COMPAT30 +#ifdef LDAP_COMPAT30 if ( conn->c_version == 30 ) { rc = ber_printf( ber, "{it{{s{", op->o_msgid, LDAP_RES_SEARCH_ENTRY, e->e_dn ); } else #endif + { rc = ber_printf( ber, "{it{s{", op->o_msgid, - LDAP_RES_SEARCH_ENTRY, e->e_dn ); + LDAP_RES_SEARCH_ENTRY, e->e_dn ); + } if ( rc == -1 ) { Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 ); ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf dn" ); - return( 1 ); + goto error_return; } for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + regmatch_t matches[MAXREMATCHES]; + if ( attrs != NULL && ! charray_inlist( attrs, a->a_type ) ) { continue; } - acl = acl_get_applicable( be, op, e, a->a_type ); + /* the lastmod attributes are ignored by ACL checking */ + if ( strcasecmp( a->a_type, "modifiersname" ) == 0 || + strcasecmp( a->a_type, "modifytimestamp" ) == 0 || + strcasecmp( a->a_type, "creatorsname" ) == 0 || + strcasecmp( a->a_type, "createtimestamp" ) == 0 ) + { + Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access DEFAULT\n", + a->a_type, 0, 0 ); + acl = NULL; + } else { + acl = acl_get_applicable( be, op, e, a->a_type, + MAXREMATCHES, matches ); + } - if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, - ACL_READ ) ) { + if ( ! acl_access_allowed( acl, be, conn, e, + NULL, op, ACL_READ, edn, matches ) ) + { continue; } @@ -248,14 +267,14 @@ send_search_entry( ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf type" ); - return( 1 ); + goto error_return; } if ( ! attrsonly ) { for ( i = 0; a->a_vals[i] != NULL; i++ ) { - if ( a->a_syntax & SYNTAX_DN && - ! acl_access_allowed( acl, be, conn, e, - a->a_vals[i], op, ACL_READ ) ) + if ( a->a_syntax & SYNTAX_DN && + ! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op, + ACL_READ, edn, matches) ) { continue; } @@ -270,7 +289,7 @@ send_search_entry( send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf value" ); - return( 1 ); + goto error_return; } } } @@ -280,11 +299,11 @@ send_search_entry( ber_free( ber, 1 ); send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, "ber_printf type end" ); - return( 1 ); + goto error_return; } } -#ifdef COMPAT30 +#ifdef LDAP_COMPAT30 if ( conn->c_version == 30 ) { rc = ber_printf( ber, "}}}}" ); } else @@ -328,8 +347,12 @@ send_search_entry( pthread_mutex_lock( &active_threads_mutex ); active_threads--; conn->c_writewaiter = 1; - pthread_kill( listener_tid, SIGUSR1 ); + pthread_kill( listener_tid, LDAP_SIGUSR1 ); pthread_cond_wait( &conn->c_wcv, &active_threads_mutex ); + + if( active_threads < 1 ) { + pthread_cond_signal(&active_threads_cond); + } pthread_mutex_unlock( &active_threads_mutex ); pthread_yield(); @@ -356,6 +379,9 @@ send_search_entry( Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 ); return( rc ); + +error_return:; + return( 1 ); } int @@ -429,6 +455,7 @@ close_connection( Connection *conn, int opconnid, int opid ) close( conn->c_sb.sb_sd ); conn->c_sb.sb_sd = -1; conn->c_version = 0; + conn->c_protocol = 0; } pthread_mutex_unlock( &new_conn_mutex ); }