]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/ldap_sync.c
Merge branch 'mdb.master' of ssh://git-master.openldap.org/~git/git/openldap
[openldap] / libraries / libldap / ldap_sync.c
index 0957baaeddb0c939751cd0cd81bc4449b170d317..b7247a2d7d0dbbc45d03938fe3fc3a43bbea7f01 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2006-2007 The OpenLDAP Foundation.
+ * Copyright 2006-2011 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include "ldap-int.h"
 
 #ifdef LDAP_SYNC_TRACE
-/*
- * used for debug purposes
- */
-static char *
-print_UUID( char *buf, size_t len, unsigned char *UUID )
-{
-       snprintf( buf, len,
-               "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-               "%02x%02x-%02x%02x%02x%02x%02x%02x",
-               UUID[0],
-               UUID[1],
-               UUID[2],
-               UUID[3],
-               UUID[4],
-               UUID[5],
-               UUID[6],
-               UUID[7],
-               UUID[8],
-               UUID[9],
-               UUID[10],
-               UUID[11],
-               UUID[12],
-               UUID[13],
-               UUID[14],
-               UUID[15] );
-       return buf;
-}
-
 static const char *
 ldap_sync_state2str( int state )
 {
@@ -156,14 +128,14 @@ static int
 ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
 {
        LDAPControl             **ctrls = NULL;
-       int                     rc = LDAP_SUCCESS,
+       int                     rc = LDAP_OTHER,
                                i;
        BerElement              *ber = NULL;
        struct berval           entryUUID = { 0 },
                                cookie = { 0 };
        int                     state = -1;
        ber_len_t               len;
-       ldap_sync_refresh_t     phase = ls->ls_refreshPhase;
+       ldap_sync_refresh_t     phase;
 
 #ifdef LDAP_SYNC_TRACE
        fprintf( stderr, "\tgot LDAP_RES_SEARCH_ENTRY\n" );
@@ -172,6 +144,8 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
        assert( ls != NULL );
        assert( res != NULL );
 
+       phase = ls->ls_refreshPhase;
+
        /* OK */
 
        /* extract:
@@ -187,7 +161,6 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
        /* extract controls */
        ldap_get_entry_controls( ls->ls_ld, res, &ctrls );
        if ( ctrls == NULL ) {
-               rc = LDAP_OTHER;
                goto done;
        }
 
@@ -200,22 +173,26 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
 
        /* control must be present; there might be other... */
        if ( ctrls[ i ] == NULL ) {
-               rc = LDAP_OTHER;
                goto done;
        }
 
        /* extract data */
        ber = ber_init( &ctrls[ i ]->ldctl_value );
+       if ( ber == NULL ) {
+               goto done;
+       }
        /* scan entryUUID in-place ("m") */
-       ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID );
-       if ( entryUUID.bv_len == 0 ) {
-               rc = LDAP_OTHER;
+       if ( ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID ) == LBER_ERROR
+               || entryUUID.bv_len == 0 )
+       {
                goto done;
        }
 
        if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
                /* scan cookie in-place ("m") */
-               ber_scanf( ber, /*"{"*/ "m}", &cookie );
+               if ( ber_scanf( ber, /*"{"*/ "m}", &cookie ) == LBER_ERROR ) {
+                       goto done;
+               }
                if ( cookie.bv_val != NULL ) {
                        ber_bvreplace( &ls->ls_cookie, &cookie );
                }
@@ -240,16 +217,15 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res )
                break;
 
        default:
-               rc = LDAP_OTHER;
 #ifdef LDAP_SYNC_TRACE
                fprintf( stderr, "\t\tgot unknown syncState=%d\n", state );
 #endif /* LDAP_SYNC_TRACE */
                goto done;
        }
 
-       if ( ls->ls_search_entry ) {
-               rc = ls->ls_search_entry( ls, res, &entryUUID, phase );
-       }
+       rc = ls->ls_search_entry
+               ? ls->ls_search_entry( ls, res, &entryUUID, phase )
+               : LDAP_SUCCESS;
 
 done:;
        if ( ber != NULL ) {
@@ -330,9 +306,10 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
                ber_len_t       len;
                struct berval   cookie = { 0 };
 
+               rc = LDAP_OTHER;
+
                /* deal with control; then fallthru to handler */
                if ( ctrls == NULL ) {
-                       rc = LDAP_OTHER;
                        goto done;
                }
 
@@ -347,16 +324,22 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
 
                /* control must be present; there might be other... */
                if ( ctrls[ i ] == NULL ) {
-                       rc = LDAP_OTHER;
                        goto done;
                }
 
                /* extract data */
                ber = ber_init( &ctrls[ i ]->ldctl_value );
+               if ( ber == NULL ) {
+                       goto done;
+               }
 
-               ber_scanf( ber, "{" /*"}"*/);
+               if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) {
+                       goto ber_done;
+               }
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
-                       ber_scanf( ber, "m", &cookie );
+                       if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
+                               goto ber_done;
+                       }
                        if ( cookie.bv_val != NULL ) {
                                ber_bvreplace( &ls->ls_cookie, &cookie );
                        }
@@ -368,17 +351,23 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
 
                refreshDeletes = 0;
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
-                       ber_scanf( ber, "b", &refreshDeletes );
+                       if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) {
+                               goto ber_done;
+                       }
                        if ( refreshDeletes ) {
                                refreshDeletes = 1;
                        }
                }
 
-               ber_scanf( ber, /*"{"*/ "}" );
+               if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) {
+                       rc = LDAP_SUCCESS;
+               }
 
-               /* NOTE: if any goto/return between ber_init() and here
-                * is introduced, don't forget to ber_free() */
+       ber_done:;
                ber_free( ber, 1 );
+               if ( rc != LDAP_SUCCESS ) {
+                       break;
+               }
 
 #ifdef LDAP_SYNC_TRACE
                fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
@@ -407,9 +396,6 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
                        err = ls->ls_search_result( ls, res, refreshDeletes );
                }
                break;
-
-       default:
-               break;
        }
 
 done:;
@@ -441,8 +427,7 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
         struct berval          *retdata = NULL;
        BerElement              *ber = NULL;
        ber_len_t               len;
-       ber_tag_t               tag,
-                               syncinfo_tag;
+       ber_tag_t               syncinfo_tag;
        struct berval           cookie;
        int                     refreshDeletes = 0;
        BerVarray               syncUUIDs = NULL;
@@ -472,8 +457,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
                goto done;
        }
 
+       rc = LDAP_OTHER;
+
        if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) {
-               rc = LDAP_OTHER;
                goto done;
        }
 
@@ -486,7 +472,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
        syncinfo_tag = ber_peek_tag( ber, &len );
        switch ( syncinfo_tag ) {
        case LDAP_TAG_SYNC_NEW_COOKIE:
-               ber_scanf( ber, "tm", &tag, &cookie );
+               if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
+                       goto done;
+               }
                if ( cookie.bv_val != NULL ) {
                        ber_bvreplace( &ls->ls_cookie, &cookie );
                }
@@ -510,7 +498,6 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
 
                        default:
                                /* TODO: impossible; handle */
-                               rc = LDAP_OTHER;
                                goto done;
                        }
 
@@ -525,14 +512,17 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
 
                        default:
                                /* TODO: impossible; handle */
-                               rc = LDAP_OTHER;
                                goto done;
                        }
                }
 
-               ber_scanf( ber, "t{" /*"}"*/, &tag );
+               if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) {
+                       goto done;
+               }
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
-                       ber_scanf( ber, "m", &cookie );
+                       if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
+                               goto done;
+                       }
                        if ( cookie.bv_val != NULL ) {
                                ber_bvreplace( &ls->ls_cookie, &cookie );
                        }
@@ -544,7 +534,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
 
                *refreshDone = 1;
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) {
-                       ber_scanf( ber, "b", refreshDone );
+                       if ( ber_scanf( ber, "b", refreshDone ) == LBER_ERROR ) {
+                               goto done;
+                       }
                }
 
 #ifdef LDAP_SYNC_TRACE
@@ -552,7 +544,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
                        *refreshDone ? "TRUE" : "FALSE" );
 #endif /* LDAP_SYNC_TRACE */
 
-               ber_scanf( ber, /*"{"*/ "}" );
+               if ( ber_scanf( ber, /*"{"*/ "}" ) == LBER_ERROR ) {
+                       goto done;
+               }
 
                if ( *refreshDone ) {
                        ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;
@@ -568,9 +562,13 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
 #ifdef LDAP_SYNC_TRACE
                fprintf( stderr, "\t\tgot syncIdSet\n" );
 #endif /* LDAP_SYNC_TRACE */
-               ber_scanf( ber, "t{" /*"}"*/, &tag );
+               if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) {
+                       goto done;
+               }
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
-                       ber_scanf( ber, "m", &cookie );
+                       if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
+                               goto done;
+                       }
                        if ( cookie.bv_val != NULL ) {
                                ber_bvreplace( &ls->ls_cookie, &cookie );
                        }
@@ -581,13 +579,14 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
                }
 
                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
-                       ber_scanf( ber, "b", &refreshDeletes );
+                       if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) {
+                               goto done;
+                       }
                }
 
-               ber_scanf( ber, "[W]", &syncUUIDs );
-               ber_scanf( ber, /*"{"*/ "}" );
-               if ( syncUUIDs == NULL ) {
-                       rc = LDAP_OTHER;
+               if ( ber_scanf( ber, /*"{"*/ "[W]}", &syncUUIDs ) == LBER_ERROR
+                       || syncUUIDs == NULL )
+               {
                        goto done;
                }
 
@@ -600,8 +599,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
                        for ( i = 0; syncUUIDs[ i ].bv_val != NULL; i++ ) {
                                char    buf[ BUFSIZ ];
                                fprintf( stderr, "\t\t%s\n", 
-                                       print_UUID( buf, sizeof( buf ),
-                                               (unsigned char *)syncUUIDs[ i ].bv_val ) );
+                                       lutil_uuidstr_from_normalized(
+                                               syncUUIDs[ i ].bv_val, syncUUIDs[ i ].bv_len,
+                                               buf, sizeof( buf ) ) );
                        }
                }
 #endif /* LDAP_SYNC_TRACE */
@@ -628,6 +628,8 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo
                goto done;
        }
 
+       rc = LDAP_SUCCESS;
+
 done:;
        if ( ber != NULL ) {
                ber_free( ber, 1 );
@@ -697,6 +699,7 @@ ldap_sync_init( ldap_sync_t *ls, int mode )
                ber == NULL ? "=" : "!" );
 #endif /* LDAP_SYNC_TRACE */
        if ( ber == NULL ) {
+               rc = LDAP_NO_MEMORY;
                goto done;
        }
 
@@ -717,7 +720,7 @@ ldap_sync_init( ldap_sync_t *ls, int mode )
                rc ? "!!! " : "",
                rc );
 #endif /* LDAP_SYNC_TRACE */
-       if ( rc == LBER_ERROR ) {
+       if ( rc < 0 ) {
                rc = LDAP_OTHER;
                 goto done;
         }
@@ -925,4 +928,3 @@ done_search:;
 done:;
        return rc;
 }
-