+int
+ldap_sync_search(
+ syncinfo_t *si,
+ LDAP *ld,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls,
+ int *msgidp )
+{
+ BerElement *ber;
+ int timelimit;
+ ber_int_t id;
+
+ int rc;
+ BerElement *sync_ber = NULL;
+ struct berval *sync_bvalp = NULL;
+ LDAPControl c[2];
+ LDAPControl **ctrls;
+ int err;
+
+ /* setup LDAP SYNC control */
+ sync_ber = ber_alloc_t( LBER_USE_DER );
+ ber_set_option( sync_ber, LBER_OPT_BER_MEMCTX, NULL );
+
+ if ( si->syncCookie ) {
+ ber_printf( sync_ber, "{eO}", abs(si->type), si->syncCookie );
+ } else {
+ ber_printf( sync_ber, "{e}", abs(si->type) );
+ }
+
+ if ( ber_flatten( sync_ber, &sync_bvalp ) == LBER_ERROR ) {
+ ber_free( sync_ber, 1 );
+ return LBER_ERROR;
+ }
+ ber_free( sync_ber, 1 );
+
+ ctrls = (LDAPControl**) sl_calloc( 3, sizeof(LDAPControl*), NULL );
+
+ c[0].ldctl_oid = LDAP_CONTROL_SYNC;
+ c[0].ldctl_value = (*sync_bvalp);
+ c[0].ldctl_iscritical = si->type < 0;
+ ctrls[0] = &c[0];
+
+ if ( si->authzId ) {
+ c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+ c[1].ldctl_value.bv_val = si->authzId;
+ c[1].ldctl_value.bv_len = strlen( si->authzId );
+ c[1].ldctl_iscritical = 1;
+ ctrls[1] = &c[1];
+ } else {
+ ctrls[1] = NULL;
+ }
+
+ ctrls[2] = NULL;
+
+ err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
+
+ ber_bvfree( sync_bvalp );
+ ch_free( ctrls );
+
+ if ( err != LDAP_OPT_SUCCESS )
+ fprintf( stderr, "Could not set controls : %d\n", err );
+
+ rc = ldap_search_ext( ld, si->base, si->scope, si->filterstr,
+ si->attrs, si->attrsonly, sctrls, cctrls,
+ si->tlimit, si->slimit, msgidp );
+
+ return rc;
+}
+