]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8116 Outline SyncInfo intermediate response
authorOndřej Kuzník <ondra@openldap.org>
Tue, 31 Oct 2017 16:47:35 +0000 (16:47 +0000)
committerOndřej Kuzník <ondra@openldap.org>
Fri, 19 Oct 2018 12:08:09 +0000 (13:08 +0100)
clients/tools/common.c
clients/tools/ldapsearch.c

index b1edffdaf6db4b79008d7a57fc2e7c1df4b1b92f..23829eada072ada88fc4e696f968d9f561a1ec26 100644 (file)
@@ -153,6 +153,8 @@ static int print_deref( LDAP *ld, LDAPControl *ctrl );
 #ifdef LDAP_CONTROL_X_WHATFAILED
 static int print_whatfailed( LDAP *ld, LDAPControl *ctrl );
 #endif
+static int print_syncstate( LDAP *ld, LDAPControl *ctrl );
+static int print_syncdone( LDAP *ld, LDAPControl *ctrl );
 
 static struct tool_ctrls_t {
        const char      *oid;
@@ -177,6 +179,8 @@ static struct tool_ctrls_t {
 #ifdef LDAP_CONTROL_X_WHATFAILED
        { LDAP_CONTROL_X_WHATFAILED,                    TOOL_ALL,       print_whatfailed },
 #endif
+       { LDAP_CONTROL_SYNC_STATE,                      TOOL_SEARCH,    print_syncstate },
+       { LDAP_CONTROL_SYNC_DONE,                       TOOL_SEARCH,    print_syncdone },
        { NULL,                                         0,              NULL }
 };
 
@@ -2335,6 +2339,135 @@ print_whatfailed( LDAP *ld, LDAPControl *ctrl )
 }
 #endif
 
+static int
+print_syncstate( LDAP *ld, LDAPControl *ctrl )
+{
+       struct berval syncUUID, syncCookie = BER_BVNULL;
+       char buf[LDAP_LUTIL_UUIDSTR_BUFSIZE], *uuidstr = "(UUID malformed)";
+       BerElement *ber;
+       ber_tag_t tag;
+       ber_len_t len;
+       ber_int_t state;
+       int rc;
+
+       if ( ldif ) {
+               return 0;
+       }
+
+       /* Create a BerElement from the berval returned in the control. */
+       ber = ber_init( &ctrl->ldctl_value );
+
+       if ( ber == NULL ) {
+               return LDAP_NO_MEMORY;
+       }
+
+       if ( ber_scanf( ber, "{em", &state, &syncUUID ) == LBER_ERROR ) {
+               ber_free( ber, 1 );
+               return 1;
+       }
+
+       tag = ber_get_stringbv( ber, &syncCookie, 0 );
+
+       rc = lutil_uuidstr_from_normalized(
+                       syncUUID.bv_val, syncUUID.bv_len,
+                       buf, LDAP_LUTIL_UUIDSTR_BUFSIZE );
+
+       if ( rc > 0 && rc < LDAP_LUTIL_UUIDSTR_BUFSIZE ) {
+               uuidstr = buf;
+       }
+
+       switch ( state ) {
+               case LDAP_SYNC_PRESENT:
+                       printf(_("# SyncState control, UUID %s present\n"), uuidstr);
+                       break;
+               case LDAP_SYNC_ADD:
+                       printf(_("# SyncState control, UUID %s added\n"), uuidstr);
+                       break;
+               case LDAP_SYNC_MODIFY:
+                       printf(_("# SyncState control, UUID %s modified\n"), uuidstr);
+                       break;
+               case LDAP_SYNC_DELETE:
+                       printf(_("# SyncState control, UUID %s deleted\n"), uuidstr);
+                       break;
+               default:
+                       ber_free( ber, 1 );
+                       return 1;
+       }
+
+       if ( tag != LBER_ERROR ) {
+               if ( ldif_is_not_printable( syncCookie.bv_val, syncCookie.bv_len ) ) {
+                       struct berval bv;
+
+                       bv.bv_len = LUTIL_BASE64_ENCODE_LEN( syncCookie.bv_len ) + 1;
+                       bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                       bv.bv_len = lutil_b64_ntop(
+                                       (unsigned char *) syncCookie.bv_val, syncCookie.bv_len,
+                                       bv.bv_val, bv.bv_len );
+
+                       printf(_("# cookie:: %s\n"), bv.bv_val );
+                       ber_memfree( bv.bv_val );
+               } else {
+                       printf(_("# cookie: %s\n"), syncCookie.bv_val );
+               }
+       }
+
+       ber_free( ber, 1 );
+       return 0;
+}
+
+static int
+print_syncdone( LDAP *ld, LDAPControl *ctrl )
+{
+       BerElement *ber;
+       struct berval cookie = BER_BVNULL;
+       ber_tag_t tag;
+       ber_len_t len;
+       ber_int_t refreshDeletes = 0;
+
+       if ( ldif ) {
+               return 0;
+       }
+
+       /* Create a BerElement from the berval returned in the control. */
+       ber = ber_init( &ctrl->ldctl_value );
+
+       if ( ber == NULL ) {
+               return LDAP_NO_MEMORY;
+       }
+
+       ber_skip_tag( ber, &len );
+       if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
+               ber_scanf( ber, "m", &cookie );
+       }
+       if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
+               ber_scanf( ber, "b", &refreshDeletes );
+       }
+
+       printf(_("# SyncDone control refreshDeletes=%d\n"), refreshDeletes ? 1 : 0 );
+
+       if ( !BER_BVISNULL( &cookie ) ) {
+               if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
+                       struct berval bv;
+
+                       bv.bv_len = LUTIL_BASE64_ENCODE_LEN( cookie.bv_len ) + 1;
+                       bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                       bv.bv_len = lutil_b64_ntop(
+                                       (unsigned char *) cookie.bv_val, cookie.bv_len,
+                                       bv.bv_val, bv.bv_len );
+
+                       printf(_("# cookie:: %s\n"), bv.bv_val );
+                       ber_memfree( bv.bv_val );
+               } else {
+                       printf(_("# cookie: %s\n"), cookie.bv_val );
+               }
+       }
+
+       ber_free( ber, 1 );
+       return 0;
+}
+
 #ifdef LDAP_CONTROL_AUTHZID_RESPONSE
 static int
 print_authzid( LDAP *ld, LDAPControl *ctrl )
index ed44ada74c9260748d56f5617bf8f8fd6c03af2e..4fd08f1728754d19270d6917e27c76bc65297069 100644 (file)
@@ -173,6 +173,9 @@ static void print_extended(
        LDAP *ld,
        LDAPMessage *extended );
 
+static void print_syncinfo(
+       BerValue *info );
+
 static void print_partial(
        LDAP *ld,
        LDAPMessage *partial );
@@ -1521,7 +1524,11 @@ static int dosearch(
                                nresponses_psearch = 0;
 
                                if ( strcmp( retoid, LDAP_SYNC_INFO ) == 0 ) {
-                                       printf(_("SyncInfo Received\n"));
+                                       if ( ldif < 1 ) {
+                                               print_syncinfo( retdata );
+                                       } else if ( ldif < 2 ) {
+                                               printf(_("# SyncInfo Received\n"));
+                                       }
                                        ldap_memfree( retoid );
                                        ber_bvfree( retdata );
                                        break;
@@ -1776,6 +1783,167 @@ static void print_extended(
        print_result( ld, extended, 0 );
 }
 
+static void print_syncinfo(
+       BerValue *data )
+{
+       BerElement *syncinfo;
+       struct berval bv, cookie;
+       ber_tag_t tag;
+       ber_len_t len;
+
+       if ( (syncinfo = ber_alloc()) == NULL ) {
+               return;
+       }
+       ber_init2( syncinfo, data, 0 );
+
+       printf(_("# SyncInfo Received: "));
+       tag = ber_skip_tag( syncinfo, &len );
+       switch (tag) {
+               case LDAP_TAG_SYNC_NEW_COOKIE: {
+                       printf(_("new cookie\n"));
+                       ber_scanf( syncinfo, "m", &cookie );
+
+                       if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
+                               bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
+                                               cookie.bv_len ) + 1;
+                               bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                               bv.bv_len = lutil_b64_ntop(
+                                               (unsigned char *) cookie.bv_val,
+                                               cookie.bv_len,
+                                               bv.bv_val, bv.bv_len );
+
+                               printf(_("# cookie:: %s\n"), bv.bv_val );
+                               ber_memfree( bv.bv_val );
+                       } else {
+                               printf(_("# cookie: %s\n"), cookie.bv_val );
+                       }
+                       } break;
+               case LDAP_TAG_SYNC_REFRESH_DELETE: {
+                       ber_int_t done = 1;
+                       printf(_("refresh delete\n"));
+                       tag = ber_peek_tag( syncinfo, &len );
+                       if ( tag == LDAP_TAG_SYNC_COOKIE ) {
+                               ber_scanf( syncinfo, "m", &cookie );
+
+                               if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
+                                       bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
+                                                       cookie.bv_len ) + 1;
+                                       bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                                       bv.bv_len = lutil_b64_ntop(
+                                                       (unsigned char *) cookie.bv_val,
+                                                       cookie.bv_len,
+                                                       bv.bv_val, bv.bv_len );
+
+                                       printf(_("# cookie:: %s\n"), bv.bv_val );
+                                       ber_memfree( bv.bv_val );
+                               } else {
+                                       printf(_("# cookie: %s\n"), cookie.bv_val );
+                               }
+
+                               tag = ber_peek_tag( syncinfo, &len );
+                       }
+                       if ( tag == LDAP_TAG_REFRESHDONE ) {
+                               ber_get_boolean( syncinfo, &done );
+                       }
+                       if ( done )
+                               printf(_("# refresh done, switching to persist stage\n"));
+                       } break;
+               case LDAP_TAG_SYNC_REFRESH_PRESENT: {
+                       ber_int_t done = 1;
+                       printf(_("refresh present\n"));
+                       tag = ber_peek_tag( syncinfo, &len );
+                       if ( tag == LDAP_TAG_SYNC_COOKIE ) {
+                               ber_scanf( syncinfo, "m", &cookie );
+
+                               if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
+                                       bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
+                                                       cookie.bv_len ) + 1;
+                                       bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                                       bv.bv_len = lutil_b64_ntop(
+                                                       (unsigned char *) cookie.bv_val,
+                                                       cookie.bv_len,
+                                                       bv.bv_val, bv.bv_len );
+
+                                       printf(_("# cookie:: %s\n"), bv.bv_val );
+                                       ber_memfree( bv.bv_val );
+                               } else {
+                                       printf(_("# cookie: %s\n"), cookie.bv_val );
+                               }
+
+                               tag = ber_peek_tag( syncinfo, &len );
+                       }
+                       if ( tag == LDAP_TAG_REFRESHDONE ) {
+                               ber_get_boolean( syncinfo, &done );
+                       }
+                       if ( done )
+                               printf(_("# refresh done, switching to persist stage\n"));
+                       } break;
+               case LDAP_TAG_SYNC_ID_SET: {
+                       ber_int_t refreshDeletes = 0;
+                       BerVarray uuids;
+
+                       printf(_("ID Set\n"));
+                       tag = ber_peek_tag( syncinfo, &len );
+                       if ( tag == LDAP_TAG_SYNC_COOKIE ) {
+                               ber_scanf( syncinfo, "m", &cookie );
+
+                               if ( ldif_is_not_printable( cookie.bv_val, cookie.bv_len ) ) {
+                                       bv.bv_len = LUTIL_BASE64_ENCODE_LEN(
+                                                       cookie.bv_len ) + 1;
+                                       bv.bv_val = ber_memalloc( bv.bv_len + 1 );
+
+                                       bv.bv_len = lutil_b64_ntop(
+                                                       (unsigned char *) cookie.bv_val,
+                                                       cookie.bv_len,
+                                                       bv.bv_val, bv.bv_len );
+
+                                       printf(_("# cookie:: %s\n"), bv.bv_val );
+                                       ber_memfree( bv.bv_val );
+                               } else {
+                                       printf(_("# cookie: %s\n"), cookie.bv_val );
+                               }
+
+                               tag = ber_peek_tag( syncinfo, &len );
+                       }
+                       if ( tag == LDAP_TAG_REFRESHDELETES ) {
+                               ber_get_boolean( syncinfo, &refreshDeletes );
+                               tag = ber_peek_tag( syncinfo, &len );
+                       }
+                       if ( refreshDeletes ) {
+                               printf(_("# following UUIDs no longer match the search\n"));
+                       }
+
+                       printf(_("# syncUUIDs:\n"));
+                       ber_scanf( syncinfo, "[W]", &uuids );
+                       if ( uuids ) {
+                               char buf[LDAP_LUTIL_UUIDSTR_BUFSIZE];
+                               int i;
+
+                               for ( i=0; !BER_BVISNULL( &uuids[i] ); i++ ) {
+                                       int rc = lutil_uuidstr_from_normalized(
+                                                       uuids[i].bv_val, uuids[i].bv_len,
+                                                       buf, LDAP_LUTIL_UUIDSTR_BUFSIZE );
+                                       if ( rc <= 0 || rc >= LDAP_LUTIL_UUIDSTR_BUFSIZE ) {
+                                               printf(_("#\t(UUID malformed)\n"));
+                                       } else {
+                                               printf(_("#\t%s\n"), buf);
+                                       }
+                               }
+                               ber_bvarray_free( uuids );
+                       }
+                       } break;
+               case LBER_DEFAULT:
+                       printf(_("empty SyncInfoValue\n"));
+               default:
+                       printf(_("SyncInfoValue unknown\n"));
+                       break;
+       }
+       ber_free( syncinfo, 0 );
+}
+
 static void print_partial(
        LDAP *ld,
        LDAPMessage *partial )