]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/ldapsync.c
Add SLAP_MR_ORDERED_INDEX - support for inequality indexing. Currently
[openldap] / servers / slapd / ldapsync.c
index 55c80e43c32b28c6dc77adafccc67bd45aca0bf3..c0b916193666aa78780447c2de20611ae3e09564 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/>.
  *
- * 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.
+ * Copyright 2003-2004 The OpenLDAP Foundation.
+ * Portions Copyright 2003 IBM Corporation.
+ * All rights reserved.
  *
- * 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.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * 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"
 
+#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,
@@ -55,16 +53,17 @@ slap_build_sync_state_ctrl(
        BerElementBuffer berbuf;
        BerElement *ber = (BerElement *)&berbuf;
 
-       struct berval entryuuid_bv      = { 0, NULL };
+       struct berval entryuuid_bv      = BER_BVNULL;
 
        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] = slap_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] );
                }
        }
 
@@ -86,15 +85,9 @@ slap_build_sync_state_ctrl(
        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;
        }
@@ -117,6 +110,7 @@ slap_build_sync_done_ctrl(
        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 ) );
 
@@ -136,15 +130,9 @@ slap_build_sync_done_ctrl(
        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;
        }
@@ -172,9 +160,10 @@ slap_build_sync_state_ctrl_from_slog(
        BerElementBuffer berbuf;
        BerElement *ber = (BerElement *)&berbuf;
 
-       struct berval entryuuid_bv      = { 0, NULL };
+       struct berval entryuuid_bv      = BER_BVNULL;
 
-       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 ) );
 
@@ -198,15 +187,9 @@ slap_build_sync_state_ctrl_from_slog(
        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;
        }
@@ -231,6 +214,7 @@ slap_send_syncinfo(
        int ret;
 
        ber_init2( ber, NULL, LBER_USE_DER );
+       ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
 
        if ( type ) {
                switch ( type ) {
@@ -260,15 +244,9 @@ slap_send_syncinfo(
                        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;
                }
        }
@@ -276,15 +254,9 @@ slap_send_syncinfo(
        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;
        }
@@ -302,23 +274,46 @@ 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 );
 }
@@ -356,8 +351,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;
 
@@ -365,11 +363,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 );
@@ -378,15 +382,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
@@ -395,16 +413,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 );
@@ -445,6 +463,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++ ) {
@@ -462,3 +481,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      = BER_BVNULL;
+
+       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;
+}