From: Jong Hyuk Choi Date: Sat, 14 Sep 2002 00:29:06 +0000 (+0000) Subject: LCUP Response Control Code X-Git-Tag: NO_SLAP_OP_BLOCKS~977 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1509e321de84cdb40053a4ec4c5423f8e6ac373b;p=openldap LCUP Response Control Code --- diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 1635bbd87c..12b2bb202e 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -59,8 +59,9 @@ bdb_search( #ifdef LDAP_CLIENT_UPDATE Filter lcupf, csnfnot, csnfeq, csnfand, csnfge; AttributeAssertion aa_ge, aa_eq; - LDAPControl ctrl; int entry_count = 0; + struct berval entrycsn_bv = { 0, NULL }; + struct berval latest_entrycsn_bv = { 0, NULL }; #endif /* LDAP_CLIENT_UPDATE */ struct slap_limits_set *limit = NULL; @@ -352,7 +353,7 @@ dn2entry_retry: csnfeq.f_choice = LDAP_FILTER_EQUALITY; csnfeq.f_ava = &aa_eq; csnfeq.f_av_desc = slap_schema.si_ad_entryCSN; - ber_dupbv(&csnfeq.f_av_value, op->o_clientupdate_state); + ber_dupbv( &csnfeq.f_av_value, &op->o_clientupdate_state ); csnfand.f_choice = LDAP_FILTER_AND; csnfand.f_and = &csnfge; @@ -361,7 +362,7 @@ dn2entry_retry: csnfge.f_choice = LDAP_FILTER_GE; csnfge.f_ava = &aa_ge; csnfge.f_av_desc = slap_schema.si_ad_entryCSN; - ber_dupbv(&csnfge.f_av_value, op->o_clientupdate_state); + ber_dupbv( &csnfge.f_av_value, &op->o_clientupdate_state ); csnfge.f_next = filter; } #endif /* LDAP_CLIENT_UPDATE */ @@ -625,9 +626,111 @@ id2entry_retry: result = 0; } else { #endif - result = send_search_entry( be, conn, op, - e, attrs, attrsonly, NULL); +#ifdef LDAP_CLIENT_UPDATE + if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) { + Attribute* a; + int ret; + int res; + const char *text = NULL; + LDAPControl *ctrls[2]; + struct berval *bv; + + BerElement *ber = ber_alloc_t( LBER_USE_DER ); + if ( ber == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: ber_alloc_t failed\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_alloc_t failed\n", + 0, 0, 0 ); +#endif + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + goto done; + } + + entry_count++; + + ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) ); + ctrls[1] = NULL; + + if ( entry_count % op->o_clientupdate_interval == 0 ) { + /* Send cookie */ + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + AttributeDescription *desc = a->a_desc; + if ( !strcmp( desc->ad_cname.bv_val, "entryCSN" ) ) { + ber_dupbv( &entrycsn_bv, &a->a_vals[0] ); + if ( latest_entrycsn_bv.bv_val == NULL ) { + ber_dupbv( &latest_entrycsn_bv, &entrycsn_bv ); + } else { + res = value_match( &ret, desc, desc->ad_type->sat_ordering, SLAP_MR_ASSERTION_SYNTAX_MATCH, &entrycsn_bv, &latest_entrycsn_bv, &text ); + if ( res != LDAP_SUCCESS ) { + ret = 0; +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: value_match failed\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_search: value_match failed\n", + 0, 0, 0 ); +#endif + } + + if ( ret > 0 ) { + ch_free( latest_entrycsn_bv.bv_val ); + latest_entrycsn_bv.bv_val = NULL; + ber_dupbv( &latest_entrycsn_bv, &entrycsn_bv ); + } + } + } + } + + ber_printf( ber, "{{b}" /*}*/, SLAP_LCUP_STATE_UPDATE_FALSE ); + ber_printf( ber, "{b}", SLAP_LCUP_ENTRY_DELETED_FALSE ); + ber_printf( ber, "{sO" /*}*/, LCUP_COOKIE_OID, &entrycsn_bv ); + ber_printf( ber, /*{{*/ "N}N}" ); + + ch_free( entrycsn_bv.bv_val ); + entrycsn_bv.bv_val = NULL; + } else { + /* Do not send cookie */ + ber_printf( ber, "{{b}" /*}*/, SLAP_LCUP_STATE_UPDATE_FALSE ); + ber_printf( ber, /*{*/ "{b}N}", SLAP_LCUP_ENTRY_DELETED_FALSE ); + } + + ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE; + ctrls[0]->ldctl_iscritical = op->o_clientupdate; + ret = ber_flatten( ber, &bv ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: ber_flatten failed\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_flatten failed\n", + 0, 0, 0 ); +#endif + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + goto done; + } + + ber_dupbv( &ctrls[0]->ldctl_value, bv ); + + result = send_search_entry( be, conn, op, + e, attrs, attrsonly, ctrls); + + ch_free( ctrls[0]->ldctl_value.bv_val ); + ch_free( ctrls[0] ); + ber_free( ber, 1 ); + ber_bvfree( bv ); + } else { +#endif /* LDAP_CLIENT_UPDATE */ + result = send_search_entry( be, conn, op, + e, attrs, attrsonly, NULL); +#ifdef LDAP_CLIENT_UPDATE + } +#endif /* LDAP_CLIENT_UPDATE */ #if 0 } #endif @@ -676,10 +779,69 @@ loop_continue: ldap_pvt_thread_yield(); } +#ifdef LDAP_CLIENT_UPDATE + if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) { + int ret; + LDAPControl *ctrls[2]; + BerElement *ber = ber_alloc_t( LBER_USE_DER ); + struct berval *bv; + + if ( ber == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: ber_alloc_t failed\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_alloc_t failed\n", + 0, 0, 0 ); +#endif + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + goto done; + } + + ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) ); + ctrls[1] = NULL; + + ber_printf( ber, "{sO", LCUP_COOKIE_OID, &latest_entrycsn_bv ); + ber_printf( ber, "N}" ); - send_search_result( conn, op, - v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL, - NULL, NULL, v2refs, NULL, nentries ); + ctrls[0]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE; + ctrls[0]->ldctl_iscritical = op->o_clientupdate; + ret = ber_flatten( ber, &bv ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: ber_flatten failed\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_flatten failed\n", + 0, 0, 0 ); +#endif + send_ldap_result( conn, op, rc=LDAP_OTHER, + NULL, "internal error", NULL, NULL ); + goto done; + } + + ber_dupbv( &ctrls[0]->ldctl_value, bv ); + + send_search_result( conn, op, + v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL, + NULL, NULL, v2refs, ctrls, nentries ); + + ch_free( latest_entrycsn_bv.bv_val ); + latest_entrycsn_bv.bv_val = NULL; + ch_free( ctrls[0]->ldctl_value.bv_val ); + ch_free( ctrls[0] ); + ber_free( ber, 1 ); + ber_bvfree( bv ); + } else { +#endif /* LDAP_CLIENT_UPDATE */ + send_search_result( conn, op, + v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL, + NULL, NULL, v2refs, NULL, nentries ); +#ifdef LDAP_CLIENT_UPDATE + } +#endif /* LDAP_CLIENT_UPDATE */ rc = 0; @@ -689,6 +851,14 @@ done: bdb_cache_return_entry_r ( bdb->bi_dbenv, &bdb->bi_cache, e, &lock ); } + if ( csnfeq.f_av_value.bv_val != NULL ) { + ch_free( csnfeq.f_av_value.bv_val ); + } + + if ( csnfge.f_av_value.bv_val != NULL ) { + ch_free( csnfge.f_av_value.bv_val ); + } + LOCK_ID_FREE (bdb->bi_dbenv, locker ); if( v2refs ) ber_bvarray_free( v2refs ); diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 45ef4efd4e..7489fb66a4 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -90,7 +90,7 @@ static struct slap_control { { LDAP_CONTROL_CLIENT_UPDATE, SLAP_CTRL_SEARCH, NULL, parseClientUpdate }, -#endif +#endif /* LDAP_CLIENT_UPDATE */ { NULL } }; @@ -714,7 +714,7 @@ static int parseClientUpdate ( } #endif - op->o_clientupdate_state = ber_dupbv(NULL, &cookie); + ber_dupbv( &op->o_clientupdate_state, &cookie ); (void) ber_free( ber, 1 ); @@ -727,4 +727,4 @@ static int parseClientUpdate ( return LDAP_SUCCESS; } -#endif +#endif /* LDAP_CLIENT_UPDATE */ diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c index 49c1a7b58c..59fc1b9cd7 100644 --- a/servers/slapd/operation.c +++ b/servers/slapd/operation.c @@ -36,6 +36,12 @@ slap_op_free( Operation *op ) ldap_controls_free( op->o_ctrls ); } +#ifdef LDAP_CLIENT_UPDATE + if ( op->o_clientupdate_state.bv_val != NULL ) { + free( op->o_clientupdate_state.bv_val ); + } +#endif /* LDAP_CLIENT_UPDATE */ + free( (char *) op ); } diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 8df2efcb1b..425db124c5 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -224,7 +224,9 @@ send_ldap_response( return; } +#ifndef LDAP_CLIENT_UPDATE assert( ctrls == NULL ); /* ctrls not implemented */ +#endif /* LDAP_CLIENT_UPDATE */ ber_init_w_nullc( ber, LBER_USE_DER ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 2d4a1eeaec..d018a3e836 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -215,6 +215,10 @@ typedef struct slap_ssf_set { #define SLAP_SYNTAX_ATTRIBUTETYPES_OID "1.3.6.1.4.1.1466.115.121.1.3" #define SLAP_SYNTAX_OBJECTCLASSES_OID "1.3.6.1.4.1.1466.115.121.1.37" +#ifdef LDAP_CLIENT_UPDATE +#define LCUP_COOKIE_OID "1.3.6.1.4.1.4203.666.10.1" +#endif /* LDAP_CLIENT_UPDATE */ + /* * represents schema information for a database */ @@ -1593,8 +1597,8 @@ typedef struct slap_op { #define SLAP_LCUP_PERSIST (0x2) #define SLAP_LCUP_SYNC_AND_PERSIST (0x3) ber_int_t o_clientupdate_interval; - struct berval* o_clientupdate_state; -#endif + struct berval o_clientupdate_state; +#endif /* LDAP_CLIENT_UPDATE */ #ifdef LDAP_CONNECTIONLESS Sockaddr o_peeraddr; /* UDP peer address */ @@ -1750,6 +1754,16 @@ enum { #define SLAP_LDAPDN_PRETTY 0x1 #define SLAP_LDAPDN_MAXLEN 8192 +/* + * Macros for LCUP + */ +#ifdef LDAP_CLIENT_UPDATE +#define SLAP_LCUP_STATE_UPDATE_TRUE 1 +#define SLAP_LCUP_STATE_UPDATE_FALSE 0 +#define SLAP_LCUP_ENTRY_DELETED_TRUE 1 +#define SLAP_LCUP_ENTRY_DELETED_FALSE 0 +#endif /* LDAP_CLIENT_UPDATE */ + LDAP_END_DECL #include "proto-slap.h"