3 * LDAP Content Sync Routines
6 * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved.
7 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
9 /* Copyright (c) 2003 by International Business Machines, Inc.
11 * International Business Machines, Inc. (hereinafter called IBM) grants
12 * permission under its copyrights to use, copy, modify, and distribute this
13 * Software with or without fee, provided that the above copyright notice and
14 * all paragraphs of this notice appear in all copies, and that the name of IBM
15 * not be used in connection with the marketing of any product incorporating
16 * the Software or modifications thereof, without specific, written prior
19 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
22 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
24 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 #include <ac/string.h>
32 #include <ac/socket.h>
37 #include "lutil_ldap.h"
40 slap_build_sync_state_ctrl(
48 struct berval *cookie)
53 const char *text = NULL;
55 BerElementBuffer berbuf;
56 BerElement *ber = (BerElement *)&berbuf;
58 struct berval entryuuid_bv = { 0, NULL };
60 ber_init2( ber, 0, LBER_USE_DER );
62 ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
64 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
65 AttributeDescription *desc = a->a_desc;
66 if ( desc == slap_schema.si_ad_entryUUID ) {
67 ber_dupbv( &entryuuid_bv, &a->a_nvals[0] );
71 if ( send_cookie && cookie ) {
72 ber_printf( ber, "{eOON}",
73 entry_sync_state, &entryuuid_bv, cookie );
75 ber_printf( ber, "{eON}",
76 entry_sync_state, &entryuuid_bv );
79 ch_free( entryuuid_bv.bv_val );
80 entryuuid_bv.bv_val = NULL;
82 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
83 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
84 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
90 LDAP_LOG ( OPERATION, RESULTS,
91 "slap_build_sync_ctrl: ber_flatten2 failed\n",
94 Debug( LDAP_DEBUG_TRACE,
95 "slap_build_sync_ctrl: ber_flatten2 failed\n",
98 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
106 slap_build_sync_done_ctrl(
112 struct berval *cookie,
116 BerElementBuffer berbuf;
117 BerElement *ber = (BerElement *)&berbuf;
119 ber_init2( ber, NULL, LBER_USE_DER );
121 ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
123 ber_printf( ber, "{" );
124 if ( send_cookie && cookie ) {
125 ber_printf( ber, "O", cookie );
127 if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) {
128 ber_printf( ber, "b", refreshDeletes );
130 ber_printf( ber, "N}" );
132 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
133 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
134 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
140 LDAP_LOG ( OPERATION, RESULTS,
141 "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
144 Debug( LDAP_DEBUG_TRACE,
145 "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
148 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
157 slap_build_sync_state_ctrl_from_slog(
160 struct slog_entry *slog_e,
161 int entry_sync_state,
165 struct berval *cookie)
170 const char *text = NULL;
172 BerElementBuffer berbuf;
173 BerElement *ber = (BerElement *)&berbuf;
175 struct berval entryuuid_bv = { 0, NULL };
177 ber_init2( ber, 0, LBER_USE_DER );
179 ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
181 ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid );
183 if ( send_cookie && cookie ) {
184 ber_printf( ber, "{eOON}",
185 entry_sync_state, &entryuuid_bv, cookie );
187 ber_printf( ber, "{eON}",
188 entry_sync_state, &entryuuid_bv );
191 ch_free( entryuuid_bv.bv_val );
192 entryuuid_bv.bv_val = NULL;
194 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
195 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
196 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
202 LDAP_LOG ( OPERATION, RESULTS,
203 "slap_build_sync_ctrl: ber_flatten2 failed\n",
206 Debug( LDAP_DEBUG_TRACE,
207 "slap_build_sync_ctrl: ber_flatten2 failed\n",
210 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
222 struct berval *cookie,
227 BerElementBuffer berbuf;
228 BerElement *ber = (BerElement *)&berbuf;
229 struct berval rspdata;
233 ber_init2( ber, NULL, LBER_USE_DER );
237 case LDAP_TAG_SYNC_NEW_COOKIE:
238 ber_printf( ber, "tO", type, cookie );
240 case LDAP_TAG_SYNC_REFRESH_DELETE:
241 case LDAP_TAG_SYNC_REFRESH_PRESENT:
242 ber_printf( ber, "t{", type );
244 ber_printf( ber, "O", cookie );
246 if ( refreshDone == 0 ) {
247 ber_printf( ber, "b", refreshDone );
249 ber_printf( ber, "N}" );
251 case LDAP_TAG_SYNC_ID_SET:
252 ber_printf( ber, "t{", type );
254 ber_printf( ber, "O", cookie );
256 if ( refreshDeletes == 1 ) {
257 ber_printf( ber, "b", refreshDeletes );
259 ber_printf( ber, "[W]", syncUUIDs );
260 ber_printf( ber, "N}" );
264 LDAP_LOG ( OPERATION, RESULTS,
265 "slap_send_syncinfo: invalid syncinfo type (%d)\n",
268 Debug( LDAP_DEBUG_TRACE,
269 "slap_send_syncinfo: invalid syncinfo type (%d)\n",
276 ret = ber_flatten2( ber, &rspdata, 0 );
280 LDAP_LOG ( OPERATION, RESULTS,
281 "slap_send_syncinfo: ber_flatten2 failed\n",
284 Debug( LDAP_DEBUG_TRACE,
285 "slap_send_syncinfo: ber_flatten2 failed\n",
288 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
292 rs->sr_rspdata = &rspdata;
293 send_ldap_intermediate( op, rs );
294 rs->sr_rspdata = NULL;
301 slap_compose_sync_cookie(
303 struct berval *cookie,
307 char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 10 ];
309 if ( csn->bv_val == NULL ) {
313 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
316 } else if ( sid == -1 ) {
317 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
318 "csn=%s", csn->bv_val );
320 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10,
321 "csn=%s,sid=%03d", csn->bv_val, sid );
323 ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie );
327 slap_sync_cookie_free(
328 struct sync_cookie *cookie,
332 if ( cookie == NULL )
335 if ( cookie->ctxcsn ) {
336 ber_bvarray_free( cookie->ctxcsn );
337 cookie->ctxcsn = NULL;
340 if ( cookie->octet_str ) {
341 ber_bvarray_free( cookie->octet_str );
342 cookie->octet_str = NULL;
353 slap_parse_sync_cookie(
354 struct sync_cookie *cookie
363 struct berval *ctxcsn;
365 if ( cookie == NULL )
368 if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) {
369 csn_str = (char *) SLAP_STRNDUP( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE );
370 if ( cval = strchr( csn_str, ',' )) {
372 csn_str_len = cval - csn_str - (sizeof("csn=") - 1);
374 csn_str_len = cookie->octet_str[0].bv_len -
375 (csn_ptr - cookie->octet_str[0].bv_val) -
376 (sizeof("csn=") - 1);
378 ctxcsn = ber_str2bv( csn_str + (sizeof("csn=")-1),
379 csn_str_len, 1, NULL );
381 ber_bvarray_add( &cookie->ctxcsn, ctxcsn );
384 cookie->ctxcsn = NULL;
387 if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) {
388 sid_str = (char *) SLAP_STRNDUP( sid_ptr,
389 SLAP_SYNC_SID_SIZE + sizeof("sid=") - 1 );
390 if ( cval = strchr( sid_str, ',' )) {
393 cookie->sid = atoi( sid_str + sizeof("sid=") - 1 );
401 slap_init_sync_cookie_ctxcsn(
402 struct sync_cookie *cookie
405 char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ];
406 struct berval octet_str = { 0, NULL };
407 struct berval ctxcsn = { 0, NULL };
408 struct berval ctxcsn_dup = { 0, NULL };
409 struct berval slap_syncCookie;
411 if ( cookie == NULL )
414 octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4,
415 "csn=%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x",
416 1900, 1, 1, 0, 0, 0, 0, 0, 0 );
417 octet_str.bv_val = csnbuf;
418 build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL );
419 ber_bvarray_free( cookie->octet_str );
420 cookie->octet_str = NULL;
421 ber_bvarray_add( &cookie->octet_str, &slap_syncCookie );
423 ber_dupbv( &ctxcsn, &octet_str );
426 ber_dupbv( &ctxcsn_dup, &ctxcsn );
427 ch_free( ctxcsn.bv_val );
428 ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup );
434 slap_dup_sync_cookie(
435 struct sync_cookie *dst,
436 struct sync_cookie *src
440 struct sync_cookie *new;
441 struct berval tmp_bv;
447 ber_bvarray_free( dst->ctxcsn );
448 ber_bvarray_free( dst->octet_str );
451 new = ( struct sync_cookie * )
452 ch_calloc( 1, sizeof( struct sync_cookie ));
458 for ( i=0; src->ctxcsn[i].bv_val; i++ ) {
459 ber_dupbv( &tmp_bv, &src->ctxcsn[i] );
460 ber_bvarray_add( &new->ctxcsn, &tmp_bv );
464 if ( src->octet_str ) {
465 for ( i=0; src->octet_str[i].bv_val; i++ ) {
466 ber_dupbv( &tmp_bv, &src->octet_str[i] );
467 ber_bvarray_add( &new->octet_str, &tmp_bv );