]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/ldapsync.c
declare oc_bvfind_undef()
[openldap] / servers / slapd / ldapsync.c
index a93d8e6ba31f2b955db51e9912392a3d5d1646a3..9141f937d9fab5cee0c5a420c1593f0061edce9e 100644 (file)
@@ -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 <http://www.openldap.org/>.
+ *
+ * Copyright 2003-2004 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
+ * <http://www.OpenLDAP.org/license.html>.
  */
 
 #include "portable.h"
 #include <ac/string.h>
 #include <ac/socket.h>
 
-#include "ldap_pvt.h"
 #include "lutil.h"
 #include "slap.h"
+#include "../../libraries/liblber/lber-int.h" /* get ber_strndup() */
 #include "lutil_ldap.h"
 
-int
-slap_build_sync_state_ctrl(
-       Operation       *op,
-       SlapReply       *rs,
-       Entry           *e,
-       int                     entry_sync_state,
-       LDAPControl     **ctrls,
-       int                     num_ctrls,
-       int                     send_cookie,
-       struct berval   *csn)
-{
-       Attribute* a;
-       int ret;
-       int res;
-       const char *text = NULL;
-
-       BerElementBuffer berbuf;
-       BerElement *ber = (BerElement *)&berbuf;
-
-       struct berval entryuuid_bv      = { 0, NULL };
-
-       ber_init2( ber, 0, LBER_USE_DER );
-
-       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-       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] );
-               }
-       }
-
-       if ( send_cookie && csn ) {
-               ber_printf( ber, "{eOON}",
-                       entry_sync_state, &entryuuid_bv, csn );
-       } else {
-               ber_printf( ber, "{eON}",
-                       entry_sync_state, &entryuuid_bv );
-       }
-
-       ch_free( entryuuid_bv.bv_val );
-       entryuuid_bv.bv_val = NULL;
-
-       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
-       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
-       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-       ber_free_buf( ber );
-
-       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE,
-                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#endif
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return ret;
-       }
-
-       return LDAP_SUCCESS;
-}
-
-int
-slap_build_sync_done_ctrl(
-       Operation       *op,
-       SlapReply       *rs,
-       LDAPControl     **ctrls,
-       int             num_ctrls,
-       int             send_cookie,
-       struct berval   *csn )
-{
-       int ret;
-       BerElementBuffer berbuf;
-       BerElement *ber = (BerElement *)&berbuf;
-
-       ber_init2( ber, NULL, LBER_USE_DER );
-
-       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-       if ( send_cookie && csn ) {
-               ber_printf( ber, "{ON}", csn );
-       } else {
-               ber_printf( ber, "{N}" );
-       }
-
-       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
-       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
-       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-       ber_free_buf( ber );
-
-       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE,
-                       "slap_build_sync_done_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
-#endif
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return ret;
-       }
-
-       return LDAP_SUCCESS;
-}
-
-
-int
-slap_build_sync_state_ctrl_from_slog(
-       Operation       *op,
-       SlapReply       *rs,
-       struct slog_entry *slog_e,
-       int                     entry_sync_state,
-       LDAPControl     **ctrls,
-       int                     num_ctrls,
-       int                     send_cookie,
-       struct berval   *csn)
-{
-       Attribute* a;
-       int ret;
-       int res;
-       const char *text = NULL;
-
-       BerElementBuffer berbuf;
-       BerElement *ber = (BerElement *)&berbuf;
-
-       struct berval entryuuid_bv      = { 0, NULL };
-
-       ber_init2( ber, 0, LBER_USE_DER );
-
-       ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
-
-       ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid );
-
-       if ( send_cookie && csn ) {
-               ber_printf( ber, "{eOON}",
-                       entry_sync_state, &entryuuid_bv, csn );
-       } else {
-               ber_printf( ber, "{eON}",
-                       entry_sync_state, &entryuuid_bv );
-       }
-
-       ch_free( entryuuid_bv.bv_val );
-       entryuuid_bv.bv_val = NULL;
-
-       ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
-       ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
-       ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
-
-       ber_free_buf( ber );
-
-       if ( ret < 0 ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
+#if 0
+struct sync_cookie *slap_sync_cookie = NULL;
 #else
-               Debug( LDAP_DEBUG_TRACE,
-                       "slap_build_sync_ctrl: ber_flatten2 failed\n",
-                       0, 0, 0 );
+struct slap_sync_cookie_s slap_sync_cookie =
+       LDAP_STAILQ_HEAD_INITIALIZER( slap_sync_cookie );
 #endif
-               send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
-               return ret;
-       }
-
-       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 +116,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 +128,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 +147,29 @@ 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;
+       }
+       return 0;
 }
 
 int
@@ -308,16 +178,16 @@ slap_init_sync_cookie_ctxcsn(
 )
 {
        char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ];
-       struct berval octet_str = { 0, NULL };
-       struct berval ctxcsn = { 0, NULL };
-       struct berval ctxcsn_dup = { 0, NULL };
+       struct berval octet_str = BER_BVNULL;
+       struct berval ctxcsn = BER_BVNULL;
+       struct berval ctxcsn_dup = BER_BVNULL;
        struct berval slap_syncCookie;
 
        if ( cookie == NULL )
                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 );
@@ -325,11 +195,9 @@ slap_init_sync_cookie_ctxcsn(
        cookie->octet_str = NULL;
        ber_bvarray_add( &cookie->octet_str, &slap_syncCookie );
 
-       ber_dupbv( &ctxcsn, &octet_str );
-       ctxcsn.bv_val += 4;
-       ctxcsn.bv_len -= 4;
+       ctxcsn.bv_val = octet_str.bv_val + 4;
+       ctxcsn.bv_len = octet_str.bv_len - 4;
        ber_dupbv( &ctxcsn_dup, &ctxcsn );
-       ch_free( ctxcsn.bv_val );
        ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup );
 
        return 0;
@@ -358,6 +226,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 +244,4 @@ slap_dup_sync_cookie(
 
        return new;
 }
+