X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fldapsync.c;h=7241f1318e862d017c624cf71ea0ad08fb269d4f;hb=9c5fe98a79afc5303a1e82a93fd759532f289d27;hp=a93d8e6ba31f2b955db51e9912392a3d5d1646a3;hpb=279760a4674c26b8d6b6a843c2fd20e630e3c7d6;p=openldap diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index a93d8e6ba3..7241f1318e 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -1,27 +1,18 @@ +/* ldapsync.c -- LDAP Content Sync Routines */ /* $OpenLDAP$ */ -/* - * LDAP Content Sync Routines - */ -/* - * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ -/* Copyright (c) 2003 by International Business Machines, Inc. +/* This work is part of OpenLDAP Software . + * + * Copyright 2003 The OpenLDAP Foundation. + * Portions Copyright 2003 IBM Corporation. + * All rights reserved. * - * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute this - * Software with or without fee, provided that the above copyright notice and - * all paragraphs of this notice appear in all copies, and that the name of IBM - * not be used in connection with the marketing of any product incorporating - * the Software or modifications thereof, without specific, written prior - * permission. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. * - * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN - * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ #include "portable.h" @@ -34,8 +25,16 @@ #include "ldap_pvt.h" #include "lutil.h" #include "slap.h" +#include "../../libraries/liblber/lber-int.h" /* get ber_strndup() */ #include "lutil_ldap.h" +#if 0 +struct sync_cookie *slap_sync_cookie = NULL; +#else +struct slap_sync_cookie_s slap_sync_cookie = + LDAP_STAILQ_HEAD_INITIALIZER( slap_sync_cookie ); +#endif + int slap_build_sync_state_ctrl( Operation *op, @@ -45,7 +44,7 @@ slap_build_sync_state_ctrl( LDAPControl **ctrls, int num_ctrls, int send_cookie, - struct berval *csn) + struct berval *cookie) { Attribute* a; int ret; @@ -58,19 +57,20 @@ slap_build_sync_state_ctrl( struct berval entryuuid_bv = { 0, NULL }; ber_init2( ber, 0, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); - ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); + ctrls[num_ctrls] = sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx ); for ( a = e->e_attrs; a != NULL; a = a->a_next ) { AttributeDescription *desc = a->a_desc; if ( desc == slap_schema.si_ad_entryUUID ) { - ber_dupbv( &entryuuid_bv, &a->a_vals[0] ); + ber_dupbv( &entryuuid_bv, &a->a_nvals[0] ); } } - if ( send_cookie && csn ) { + if ( send_cookie && cookie ) { ber_printf( ber, "{eOON}", - entry_sync_state, &entryuuid_bv, csn ); + entry_sync_state, &entryuuid_bv, cookie ); } else { ber_printf( ber, "{eON}", entry_sync_state, &entryuuid_bv ); @@ -107,23 +107,28 @@ slap_build_sync_done_ctrl( Operation *op, SlapReply *rs, LDAPControl **ctrls, - int num_ctrls, - int send_cookie, - struct berval *csn ) + int num_ctrls, + int send_cookie, + struct berval *cookie, + int refreshDeletes ) { int ret; BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); - if ( send_cookie && csn ) { - ber_printf( ber, "{ON}", csn ); - } else { - ber_printf( ber, "{N}" ); + ber_printf( ber, "{" ); + if ( send_cookie && cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) { + ber_printf( ber, "b", refreshDeletes ); } + ber_printf( ber, "N}" ); ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE; ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; @@ -158,7 +163,7 @@ slap_build_sync_state_ctrl_from_slog( LDAPControl **ctrls, int num_ctrls, int send_cookie, - struct berval *csn) + struct berval *cookie) { Attribute* a; int ret; @@ -170,15 +175,16 @@ slap_build_sync_state_ctrl_from_slog( struct berval entryuuid_bv = { 0, NULL }; - ber_init2( ber, 0, LBER_USE_DER ); + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid ); - if ( send_cookie && csn ) { + if ( send_cookie && cookie ) { ber_printf( ber, "{eOON}", - entry_sync_state, &entryuuid_bv, csn ); + entry_sync_state, &entryuuid_bv, cookie ); } else { ber_printf( ber, "{eON}", entry_sync_state, &entryuuid_bv ); @@ -210,28 +216,135 @@ slap_build_sync_state_ctrl_from_slog( return LDAP_SUCCESS; } +int +slap_send_syncinfo( + Operation *op, + SlapReply *rs, + int type, + struct berval *cookie, + int refreshDone, + BerVarray syncUUIDs, + int refreshDeletes ) +{ + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + struct berval rspdata; + + int ret; + + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + if ( type ) { + switch ( type ) { + case LDAP_TAG_SYNC_NEW_COOKIE: + ber_printf( ber, "tO", type, cookie ); + break; + case LDAP_TAG_SYNC_REFRESH_DELETE: + case LDAP_TAG_SYNC_REFRESH_PRESENT: + ber_printf( ber, "t{", type ); + if ( cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDone == 0 ) { + ber_printf( ber, "b", refreshDone ); + } + ber_printf( ber, "N}" ); + break; + case LDAP_TAG_SYNC_ID_SET: + ber_printf( ber, "t{", type ); + if ( cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDeletes == 1 ) { + ber_printf( ber, "b", refreshDeletes ); + } + ber_printf( ber, "[W]", syncUUIDs ); + ber_printf( ber, "N}" ); + break; + default: +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_send_syncinfo: invalid syncinfo type (%d)\n", + type, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_send_syncinfo: invalid syncinfo type (%d)\n", + type, 0, 0 ); +#endif + return LDAP_OTHER; + } + } + + ret = ber_flatten2( ber, &rspdata, 0 ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_send_syncinfo: ber_flatten2 failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_send_syncinfo: ber_flatten2 failed\n", + 0, 0, 0 ); +#endif + send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); + return ret; + } + + rs->sr_rspdata = &rspdata; + send_ldap_intermediate( op, rs ); + rs->sr_rspdata = NULL; + ber_free_buf( ber ); + + return LDAP_SUCCESS; +} + void slap_compose_sync_cookie( Operation *op, struct berval *cookie, struct berval *csn, - int sid ) + int sid, + int rid ) { - char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 10 ]; + char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 20 ]; if ( csn->bv_val == NULL ) { if ( sid == -1 ) { - cookiestr[0] = '\0'; + if ( rid == -1 ) { + cookiestr[0] = '\0'; + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, + "rid=%03d", rid ); + } } else { - snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, + if ( rid == -1 ) { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, "sid=%03d", sid ); + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, + "sid=%03d,rid=%03d", sid, rid ); + } } - } else if ( sid == -1 ) { - snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, - "csn=%s", csn->bv_val ); } else { - snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, + if ( sid == -1 ) { + if ( rid == -1 ) { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, + "csn=%s", csn->bv_val ); + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, + "csn=%s,rid=%03d", csn->bv_val, rid ); + } + } else { + if ( rid == -1 ) { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, "csn=%s,sid=%03d", csn->bv_val, sid ); + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20, + "csn=%s,sid=%03d,rid=%03d", csn->bv_val, sid, rid ); + } + } } ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie ); } @@ -269,8 +382,11 @@ slap_parse_sync_cookie( { char *csn_ptr; char *csn_str; + int csn_str_len; char *sid_ptr; char *sid_str; + char *rid_ptr; + char *rid_str; char *cval; struct berval *ctxcsn; @@ -278,11 +394,17 @@ slap_parse_sync_cookie( return -1; if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) { - csn_str = (char *) strndup( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE ); - if ( cval = strchr( csn_str, ',' )) { + csn_str = SLAP_STRNDUP( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE ); + if ( (cval = strchr( csn_str, ',' )) != NULL ) { *cval = '\0'; + csn_str_len = cval - csn_str - (sizeof("csn=") - 1); + } else { + csn_str_len = cookie->octet_str[0].bv_len - + (csn_ptr - cookie->octet_str[0].bv_val) - + (sizeof("csn=") - 1); } - ctxcsn = ber_str2bv( csn_str + 4, strlen(csn_str) - 4, 1, NULL ); + ctxcsn = ber_str2bv( csn_str + (sizeof("csn=")-1), + csn_str_len, 1, NULL ); ch_free( csn_str ); ber_bvarray_add( &cookie->ctxcsn, ctxcsn ); ch_free( ctxcsn ); @@ -291,15 +413,28 @@ slap_parse_sync_cookie( } if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) { - sid_str = (char *) strndup( sid_ptr, 7 ); - if ( cval = strchr( sid_str, ',' )) { + sid_str = SLAP_STRNDUP( sid_ptr, + SLAP_SYNC_SID_SIZE + sizeof("sid=") - 1 ); + if ( (cval = strchr( sid_str, ',' )) != NULL ) { *cval = '\0'; } - cookie->sid = atoi( sid_str+4 ); + cookie->sid = atoi( sid_str + sizeof("sid=") - 1 ); ch_free( sid_str ); } else { cookie->sid = -1; } + + if (( rid_ptr = strstr( cookie->octet_str->bv_val, "rid=" )) != NULL ) { + rid_str = SLAP_STRNDUP( rid_ptr, + SLAP_SYNC_RID_SIZE + sizeof("rid=") - 1 ); + if ( (cval = strchr( rid_str, ',' )) != NULL ) { + *cval = '\0'; + } + cookie->rid = atoi( rid_str + sizeof("rid=") - 1 ); + ch_free( rid_str ); + } else { + cookie->rid = -1; + } } int @@ -317,7 +452,7 @@ slap_init_sync_cookie_ctxcsn( return -1; octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4, - "csn=%4d%02d%02d%02d:%02d:%02dZ#0x%04x#%d#%04x", + "csn=%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x", 1900, 1, 1, 0, 0, 0, 0, 0, 0 ); octet_str.bv_val = csnbuf; build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL ); @@ -358,6 +493,7 @@ slap_dup_sync_cookie( } new->sid = src->sid; + new->rid = src->rid; if ( src->ctxcsn ) { for ( i=0; src->ctxcsn[i].bv_val; i++ ) { @@ -375,3 +511,27 @@ slap_dup_sync_cookie( return new; } + +int +slap_build_syncUUID_set( + Operation *op, + BerVarray *set, + Entry *e +) +{ + int ret; + Attribute* a; + + struct berval entryuuid_bv = { 0, NULL }; + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + AttributeDescription *desc = a->a_desc; + if ( desc == slap_schema.si_ad_entryUUID ) { + ber_dupbv_x( &entryuuid_bv, &a->a_nvals[0], op->o_tmpmemctx ); + } + } + + ret = ber_bvarray_add_x( set, &entryuuid_bv, op->o_tmpmemctx ); + + return ret; +}