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_vals[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
362 struct berval *ctxcsn;
364 if ( cookie == NULL )
367 if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) {
368 csn_str = (char *) strndup( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE );
369 if ( cval = strchr( csn_str, ',' )) {
372 ctxcsn = ber_str2bv( csn_str + 4, strlen(csn_str) - 4, 1, NULL );
374 ber_bvarray_add( &cookie->ctxcsn, ctxcsn );
377 cookie->ctxcsn = NULL;
380 if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) {
381 sid_str = (char *) strndup( sid_ptr, 7 );
382 if ( cval = strchr( sid_str, ',' )) {
385 cookie->sid = atoi( sid_str+4 );
393 slap_init_sync_cookie_ctxcsn(
394 struct sync_cookie *cookie
397 char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ];
398 struct berval octet_str = { 0, NULL };
399 struct berval ctxcsn = { 0, NULL };
400 struct berval ctxcsn_dup = { 0, NULL };
401 struct berval slap_syncCookie;
403 if ( cookie == NULL )
406 octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4,
407 "csn=%4d%02d%02d%02d:%02d:%02dZ#0x%04x#%d#%04x",
408 1900, 1, 1, 0, 0, 0, 0, 0, 0 );
409 octet_str.bv_val = csnbuf;
410 build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL );
411 ber_bvarray_free( cookie->octet_str );
412 cookie->octet_str = NULL;
413 ber_bvarray_add( &cookie->octet_str, &slap_syncCookie );
415 ber_dupbv( &ctxcsn, &octet_str );
418 ber_dupbv( &ctxcsn_dup, &ctxcsn );
419 ch_free( ctxcsn.bv_val );
420 ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup );
426 slap_dup_sync_cookie(
427 struct sync_cookie *dst,
428 struct sync_cookie *src
432 struct sync_cookie *new;
433 struct berval tmp_bv;
439 ber_bvarray_free( dst->ctxcsn );
440 ber_bvarray_free( dst->octet_str );
443 new = ( struct sync_cookie * )
444 ch_calloc( 1, sizeof( struct sync_cookie ));
450 for ( i=0; src->ctxcsn[i].bv_val; i++ ) {
451 ber_dupbv( &tmp_bv, &src->ctxcsn[i] );
452 ber_bvarray_add( &new->ctxcsn, &tmp_bv );
456 if ( src->octet_str ) {
457 for ( i=0; src->octet_str[i].bv_val; i++ ) {
458 ber_dupbv( &tmp_bv, &src->octet_str[i] );
459 ber_bvarray_add( &new->octet_str, &tmp_bv );