1 /* ldapsync.c -- LDAP Content Sync Routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003 The OpenLDAP Foundation.
6 * Portions Copyright 2003 IBM Corporation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
22 #include <ac/string.h>
23 #include <ac/socket.h>
28 #include "../../libraries/liblber/lber-int.h" /* get ber_strndup() */
29 #include "lutil_ldap.h"
32 slap_build_sync_state_ctrl(
40 struct berval *cookie)
45 const char *text = NULL;
47 BerElementBuffer berbuf;
48 BerElement *ber = (BerElement *)&berbuf;
50 struct berval entryuuid_bv = { 0, NULL };
52 ber_init2( ber, 0, LBER_USE_DER );
53 ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
55 ctrls[num_ctrls] = sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx );
57 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
58 AttributeDescription *desc = a->a_desc;
59 if ( desc == slap_schema.si_ad_entryUUID ) {
60 ber_dupbv( &entryuuid_bv, &a->a_nvals[0] );
64 if ( send_cookie && cookie ) {
65 ber_printf( ber, "{eOON}",
66 entry_sync_state, &entryuuid_bv, cookie );
68 ber_printf( ber, "{eON}",
69 entry_sync_state, &entryuuid_bv );
72 ch_free( entryuuid_bv.bv_val );
73 entryuuid_bv.bv_val = NULL;
75 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
76 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
77 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
83 LDAP_LOG ( OPERATION, RESULTS,
84 "slap_build_sync_ctrl: ber_flatten2 failed\n",
87 Debug( LDAP_DEBUG_TRACE,
88 "slap_build_sync_ctrl: ber_flatten2 failed\n",
91 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
99 slap_build_sync_done_ctrl(
105 struct berval *cookie,
109 BerElementBuffer berbuf;
110 BerElement *ber = (BerElement *)&berbuf;
112 ber_init2( ber, NULL, LBER_USE_DER );
113 ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
115 ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
117 ber_printf( ber, "{" );
118 if ( send_cookie && cookie ) {
119 ber_printf( ber, "O", cookie );
121 if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) {
122 ber_printf( ber, "b", refreshDeletes );
124 ber_printf( ber, "N}" );
126 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
127 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
128 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
134 LDAP_LOG ( OPERATION, RESULTS,
135 "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
138 Debug( LDAP_DEBUG_TRACE,
139 "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
142 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
151 slap_build_sync_state_ctrl_from_slog(
154 struct slog_entry *slog_e,
155 int entry_sync_state,
159 struct berval *cookie)
164 const char *text = NULL;
166 BerElementBuffer berbuf;
167 BerElement *ber = (BerElement *)&berbuf;
169 struct berval entryuuid_bv = { 0, NULL };
171 ber_init2( ber, NULL, LBER_USE_DER );
172 ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
174 ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
176 ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid );
178 if ( send_cookie && cookie ) {
179 ber_printf( ber, "{eOON}",
180 entry_sync_state, &entryuuid_bv, cookie );
182 ber_printf( ber, "{eON}",
183 entry_sync_state, &entryuuid_bv );
186 ch_free( entryuuid_bv.bv_val );
187 entryuuid_bv.bv_val = NULL;
189 ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
190 ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
191 ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
197 LDAP_LOG ( OPERATION, RESULTS,
198 "slap_build_sync_ctrl: ber_flatten2 failed\n",
201 Debug( LDAP_DEBUG_TRACE,
202 "slap_build_sync_ctrl: ber_flatten2 failed\n",
205 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
217 struct berval *cookie,
222 BerElementBuffer berbuf;
223 BerElement *ber = (BerElement *)&berbuf;
224 struct berval rspdata;
228 ber_init2( ber, NULL, LBER_USE_DER );
229 ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
233 case LDAP_TAG_SYNC_NEW_COOKIE:
234 ber_printf( ber, "tO", type, cookie );
236 case LDAP_TAG_SYNC_REFRESH_DELETE:
237 case LDAP_TAG_SYNC_REFRESH_PRESENT:
238 ber_printf( ber, "t{", type );
240 ber_printf( ber, "O", cookie );
242 if ( refreshDone == 0 ) {
243 ber_printf( ber, "b", refreshDone );
245 ber_printf( ber, "N}" );
247 case LDAP_TAG_SYNC_ID_SET:
248 ber_printf( ber, "t{", type );
250 ber_printf( ber, "O", cookie );
252 if ( refreshDeletes == 1 ) {
253 ber_printf( ber, "b", refreshDeletes );
255 ber_printf( ber, "[W]", syncUUIDs );
256 ber_printf( ber, "N}" );
260 LDAP_LOG ( OPERATION, RESULTS,
261 "slap_send_syncinfo: invalid syncinfo type (%d)\n",
264 Debug( LDAP_DEBUG_TRACE,
265 "slap_send_syncinfo: invalid syncinfo type (%d)\n",
272 ret = ber_flatten2( ber, &rspdata, 0 );
276 LDAP_LOG ( OPERATION, RESULTS,
277 "slap_send_syncinfo: ber_flatten2 failed\n",
280 Debug( LDAP_DEBUG_TRACE,
281 "slap_send_syncinfo: ber_flatten2 failed\n",
284 send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
288 rs->sr_rspdata = &rspdata;
289 send_ldap_intermediate( op, rs );
290 rs->sr_rspdata = NULL;
297 slap_compose_sync_cookie(
299 struct berval *cookie,
304 char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 20 ];
306 if ( csn->bv_val == NULL ) {
311 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
316 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
319 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
320 "sid=%03d,rid=%03d", sid, rid );
326 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
327 "csn=%s", csn->bv_val );
329 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
330 "csn=%s,rid=%03d", csn->bv_val, rid );
334 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
335 "csn=%s,sid=%03d", csn->bv_val, sid );
337 snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
338 "csn=%s,sid=%03d,rid=%03d", csn->bv_val, sid, rid );
342 ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie );
346 slap_sync_cookie_free(
347 struct sync_cookie *cookie,
351 if ( cookie == NULL )
354 if ( cookie->ctxcsn ) {
355 ber_bvarray_free( cookie->ctxcsn );
356 cookie->ctxcsn = NULL;
359 if ( cookie->octet_str ) {
360 ber_bvarray_free( cookie->octet_str );
361 cookie->octet_str = NULL;
372 slap_parse_sync_cookie(
373 struct sync_cookie *cookie
384 struct berval *ctxcsn;
386 if ( cookie == NULL )
389 if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) {
390 csn_str = SLAP_STRNDUP( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE );
391 if ( (cval = strchr( csn_str, ',' )) != NULL ) {
393 csn_str_len = cval - csn_str - (sizeof("csn=") - 1);
395 csn_str_len = cookie->octet_str[0].bv_len -
396 (csn_ptr - cookie->octet_str[0].bv_val) -
397 (sizeof("csn=") - 1);
399 ctxcsn = ber_str2bv( csn_str + (sizeof("csn=")-1),
400 csn_str_len, 1, NULL );
402 ber_bvarray_add( &cookie->ctxcsn, ctxcsn );
405 cookie->ctxcsn = NULL;
408 if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) {
409 sid_str = SLAP_STRNDUP( sid_ptr,
410 SLAP_SYNC_SID_SIZE + sizeof("sid=") - 1 );
411 if ( (cval = strchr( sid_str, ',' )) != NULL ) {
414 cookie->sid = atoi( sid_str + sizeof("sid=") - 1 );
420 if (( rid_ptr = strstr( cookie->octet_str->bv_val, "rid=" )) != NULL ) {
421 rid_str = SLAP_STRNDUP( rid_ptr,
422 SLAP_SYNC_RID_SIZE + sizeof("rid=") - 1 );
423 if ( (cval = strchr( rid_str, ',' )) != NULL ) {
426 cookie->rid = atoi( rid_str + sizeof("rid=") - 1 );
434 slap_init_sync_cookie_ctxcsn(
435 struct sync_cookie *cookie
438 char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ];
439 struct berval octet_str = { 0, NULL };
440 struct berval ctxcsn = { 0, NULL };
441 struct berval ctxcsn_dup = { 0, NULL };
442 struct berval slap_syncCookie;
444 if ( cookie == NULL )
447 octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4,
448 "csn=%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x",
449 1900, 1, 1, 0, 0, 0, 0, 0, 0 );
450 octet_str.bv_val = csnbuf;
451 build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL );
452 ber_bvarray_free( cookie->octet_str );
453 cookie->octet_str = NULL;
454 ber_bvarray_add( &cookie->octet_str, &slap_syncCookie );
456 ber_dupbv( &ctxcsn, &octet_str );
459 ber_dupbv( &ctxcsn_dup, &ctxcsn );
460 ch_free( ctxcsn.bv_val );
461 ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup );
467 slap_dup_sync_cookie(
468 struct sync_cookie *dst,
469 struct sync_cookie *src
473 struct sync_cookie *new;
474 struct berval tmp_bv;
480 ber_bvarray_free( dst->ctxcsn );
481 ber_bvarray_free( dst->octet_str );
484 new = ( struct sync_cookie * )
485 ch_calloc( 1, sizeof( struct sync_cookie ));
492 for ( i=0; src->ctxcsn[i].bv_val; i++ ) {
493 ber_dupbv( &tmp_bv, &src->ctxcsn[i] );
494 ber_bvarray_add( &new->ctxcsn, &tmp_bv );
498 if ( src->octet_str ) {
499 for ( i=0; src->octet_str[i].bv_val; i++ ) {
500 ber_dupbv( &tmp_bv, &src->octet_str[i] );
501 ber_bvarray_add( &new->octet_str, &tmp_bv );
509 slap_build_syncUUID_set(
518 struct berval entryuuid_bv = { 0, NULL };
520 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
521 AttributeDescription *desc = a->a_desc;
522 if ( desc == slap_schema.si_ad_entryUUID ) {
523 ber_dupbv_x( &entryuuid_bv, &a->a_nvals[0], op->o_tmpmemctx );
527 ret = ber_bvarray_add_x( set, &entryuuid_bv, op->o_tmpmemctx );