mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-18 15:20:35 +08:00
LDAP Sync Operation (draft-zeilenga-ldup-sync) as a groundwork for an LDAP replication design
This commit is contained in:
parent
1b4401ff53
commit
85b1783d5c
@ -76,6 +76,10 @@ usage( void )
|
||||
* " sp/<cint>/<cookie>/<slimit>\n"
|
||||
* */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
" [!]sync= ro[/<cookie>] (ldap sync - refreshOnly)\n"
|
||||
" rp[/<cookie>][/<slimit>] (ldap sync - refreshAndPersist)\n"
|
||||
#endif
|
||||
" -F prefix URL prefix for files (default: %s)\n"
|
||||
" -l limit time limit (in seconds) for search\n"
|
||||
" -L print responses in LDIFv1 format\n"
|
||||
@ -147,11 +151,20 @@ static int includeufn, vals2tmp = 0, ldif = 0;
|
||||
static int subentries = 0, valuesReturnFilter = 0;
|
||||
static char *vrFilter = NULL;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
static int lcup = 0;
|
||||
static int ldapsync = 0;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
static int lcup_cint = 0;
|
||||
static struct berval lcup_cookie = { 0, NULL };
|
||||
static int lcup_slimit = 0;
|
||||
static int lcup_slimit = -1;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
static struct berval sync_cookie = { 0, NULL };
|
||||
static int sync_slimit = -1;
|
||||
#endif
|
||||
|
||||
static int pagedResults = 0;
|
||||
@ -290,29 +303,35 @@ handle_private_option( int i )
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
} else if ( strcasecmp( control, "lcup" ) == 0 ) {
|
||||
char *cookiep;
|
||||
char *slimitp;
|
||||
if ( lcup ) {
|
||||
fprintf( stderr, "client update control previously specified\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( cvalue == NULL ) {
|
||||
fprintf( stderr,
|
||||
"missing specification of client update control\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( strncasecmp( cvalue, "p", 1 ) == 0 ) {
|
||||
lcup = LDAP_CUP_PERSIST_ONLY;
|
||||
cvalue += 2;
|
||||
cookiep = strchr( cvalue, '/' );
|
||||
*cookiep++ = '\0';
|
||||
lcup_cint = atoi( cvalue );
|
||||
cvalue = cookiep;
|
||||
slimitp = strchr( cvalue, '/' );
|
||||
*slimitp++ = '\0';
|
||||
ber_str2bv( cookiep, 0, 0, &lcup_cookie );
|
||||
lcup_slimit = atoi( slimitp );
|
||||
} else if ( strcasecmp( control, "lcup" ) == 0 ) {
|
||||
char *cookiep;
|
||||
char *slimitp;
|
||||
if ( lcup ) {
|
||||
fprintf( stderr, "client update control previously specified\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( ldapsync != -1 ) {
|
||||
fprintf( stderr, "ldap sync control previously specified\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( cvalue == NULL ) {
|
||||
fprintf( stderr,
|
||||
"missing specification of client update control\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( strncasecmp( cvalue, "p", 1 ) == 0 ) {
|
||||
lcup = LDAP_CUP_PERSIST_ONLY;
|
||||
cvalue = strchr( cvalue, '/' );
|
||||
cvalue++;
|
||||
cookiep = strchr( cvalue, '/' );
|
||||
*cookiep++ = '\0';
|
||||
lcup_cint = atoi( cvalue );
|
||||
cvalue = cookiep;
|
||||
slimitp = strchr( cvalue, '/' );
|
||||
*slimitp++ = '\0';
|
||||
while ( isspace( *cookiep ) ) cookiep++;
|
||||
ber_str2bv( cookiep, 0, 0, &lcup_cookie );
|
||||
lcup_slimit = atoi( slimitp );
|
||||
/*
|
||||
} else if ( strncasecmp( cvalue, "s", 1 ) == 0 ) {
|
||||
lcup = LDAP_CUP_SYNC_ONLY;
|
||||
@ -342,6 +361,56 @@ handle_private_option( int i )
|
||||
if ( crit ) lcup *= -1;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
} else if ( strcasecmp( control, "sync" ) == 0 ) {
|
||||
char *cookiep;
|
||||
char *slimitp;
|
||||
if ( ldapsync ) {
|
||||
fprintf( stderr, "ldap sync control previously specified\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( lcup ) {
|
||||
fprintf( stderr, "client update control previously specified\n" );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( cvalue == NULL ) {
|
||||
fprintf( stderr,
|
||||
"missing specification of ldap sync control\n");
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( strncasecmp( cvalue, "ro", 2 ) == 0 ) {
|
||||
ldapsync = LDAP_SYNC_REFRESH_ONLY;
|
||||
cookiep = strchr( cvalue, '/' );
|
||||
if ( cookiep != NULL ) {
|
||||
cookiep++;
|
||||
if ( *cookiep != '\0' ) {
|
||||
ber_str2bv( cookiep, 0, 0, &sync_cookie );
|
||||
}
|
||||
}
|
||||
} else if ( strncasecmp( cvalue, "rp", 2 ) == 0 ) {
|
||||
ldapsync = LDAP_SYNC_REFRESH_AND_PERSIST;
|
||||
cookiep = strchr( cvalue, '/' );
|
||||
if ( cookiep != NULL ) {
|
||||
*cookiep++ = '\0';
|
||||
cvalue = cookiep;
|
||||
}
|
||||
slimitp = strchr( cvalue, '/' );
|
||||
if ( slimitp != NULL ) {
|
||||
*slimitp++ = '\0';
|
||||
}
|
||||
if ( cookiep != NULL && *cookiep != '\0' )
|
||||
ber_str2bv( cookiep, 0, 0, &sync_cookie );
|
||||
if ( slimitp != NULL && *slimitp != '\0' )
|
||||
sync_slimit = atoi( slimitp );
|
||||
} else {
|
||||
fprintf( stderr,
|
||||
"ldap sync control value \"%s\" invalid\n",
|
||||
cvalue );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
if ( crit ) ldapsync *= -1;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
fprintf( stderr, "Invalid control name: %s\n", control );
|
||||
usage();
|
||||
@ -434,6 +503,11 @@ main( int argc, char **argv )
|
||||
struct berval *cubvalp = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
BerElement *syncber = NULL;
|
||||
struct berval *syncbvalp = NULL;
|
||||
#endif
|
||||
|
||||
npagedresponses = npagedentries = npagedreferences =
|
||||
npagedextended = npagedpartial = 0;
|
||||
|
||||
@ -530,7 +604,10 @@ getNextPage:
|
||||
|| valuesReturnFilter || pageSize
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
|| lcup
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
|| ldapsync
|
||||
#endif
|
||||
) {
|
||||
int err;
|
||||
int i=0;
|
||||
@ -560,25 +637,61 @@ getNextPage:
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( lcup ) {
|
||||
if (( cuber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
|
||||
if ( lcup ) {
|
||||
if (( cuber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ( lcup_cookie.bv_len == 0 ) {
|
||||
err = ber_printf( cuber, "{ei}", abs(lcup), lcup_cint );
|
||||
} else {
|
||||
err = ber_printf( cuber, "{ei{sO}}", abs(lcup), lcup_cint,
|
||||
LDAP_LCUP_COOKIE_OID, &lcup_cookie );
|
||||
}
|
||||
|
||||
if ( err == LBER_ERROR ) {
|
||||
ber_free( cuber, 1 );
|
||||
fprintf( stderr, "client update control encoding error!\n" );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ( ber_flatten( cuber, &cubvalp ) == LBER_ERROR ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
c[i].ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE;
|
||||
c[i].ldctl_value = (*cubvalp);
|
||||
c[i].ldctl_iscritical = lcup < 0;
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
if ( ldapsync ) {
|
||||
if (( syncber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
err = ber_printf( cuber, "{ei{sO}}", abs(lcup), lcup_cint,
|
||||
LDAP_CLIENT_UPDATE_COOKIE, &lcup_cookie);
|
||||
|
||||
if ( sync_cookie.bv_len == 0 ) {
|
||||
err = ber_printf( syncber, "{e}", abs(ldapsync) );
|
||||
} else {
|
||||
err = ber_printf( syncber, "{eO}", abs(ldapsync),
|
||||
&sync_cookie );
|
||||
}
|
||||
|
||||
if ( err == LBER_ERROR ) {
|
||||
ber_free( cuber, 1 );
|
||||
fprintf( stderr, "client update control encoding error!\n" );
|
||||
ber_free( syncber, 1 );
|
||||
fprintf( stderr, "ldap sync control encoding error!\n" );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ( ber_flatten( cuber, &cubvalp ) == LBER_ERROR ) {
|
||||
if ( ber_flatten( syncber, &syncbvalp ) == LBER_ERROR ) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
c[i].ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE;
|
||||
c[i].ldctl_value=(*cubvalp);
|
||||
c[i].ldctl_iscritical = lcup < 0;
|
||||
c[i].ldctl_oid = LDAP_CONTROL_SYNC;
|
||||
c[i].ldctl_value = (*syncbvalp);
|
||||
c[i].ldctl_iscritical = ldapsync < 0;
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
@ -776,7 +889,13 @@ static int dosearch(
|
||||
int nextended;
|
||||
int npartial;
|
||||
LDAPMessage *res, *msg;
|
||||
ber_int_t msgid;
|
||||
ber_int_t msgid;
|
||||
#ifdef LDAP_SYNC
|
||||
char *retoid = NULL;
|
||||
struct berval *retdata = NULL;
|
||||
int nresponses_psearch = -1;
|
||||
int cancel_msgid = -1;
|
||||
#endif
|
||||
|
||||
if( filtpatt != NULL ) {
|
||||
filter = malloc( strlen( filtpatt ) + strlen( value ) );
|
||||
@ -806,6 +925,8 @@ static int dosearch(
|
||||
rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
|
||||
sctrls, cctrls, timeout, sizelimit, &msgid );
|
||||
|
||||
printf("msgid = %d\n", msgid);
|
||||
|
||||
if ( filtpatt != NULL ) {
|
||||
free( filter );
|
||||
}
|
||||
@ -833,7 +954,11 @@ static int dosearch(
|
||||
msg != NULL;
|
||||
msg = ldap_next_message( ld, msg ) )
|
||||
{
|
||||
if( nresponses++ ) putchar('\n');
|
||||
if ( nresponses++ ) putchar('\n');
|
||||
#if LDAP_SYNC
|
||||
if ( nresponses_psearch >= 0 )
|
||||
nresponses_psearch++;
|
||||
#endif
|
||||
|
||||
switch( ldap_msgtype( msg ) ) {
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
@ -854,6 +979,16 @@ static int dosearch(
|
||||
/* unsolicited extended operation */
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
if ( cancel_msgid != -1 &&
|
||||
cancel_msgid == ldap_msgid( msg ) ) {
|
||||
printf("Cancelled \n");
|
||||
printf("cancel_msgid = %d\n", cancel_msgid);
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case LDAP_RES_EXTENDED_PARTIAL:
|
||||
@ -866,14 +1001,62 @@ static int dosearch(
|
||||
if ( pageSize != 0 ) {
|
||||
rc = parse_page_control( ld, msg, &cookie );
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( nresponses >= lcup_slimit ) {
|
||||
if ( lcup == LDAP_CUP_PERSIST_ONLY ||
|
||||
lcup == LDAP_CUP_SYNC_AND_PERSIST ) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
goto done;
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
case LDAP_RES_INTERMEDIATE_RESP:
|
||||
ldap_parse_intermediate_resp_result( ld, msg, &retoid, &retdata, 0 );
|
||||
nresponses_psearch = 0;
|
||||
|
||||
if ( strcmp( retoid, LDAP_SYNC_INFO ) ) {
|
||||
printf("Unexpected Intermediate Response\n");
|
||||
ldap_memfree( retoid );
|
||||
ber_bvfree( retdata );
|
||||
goto done;
|
||||
} else {
|
||||
printf("SyncInfo Received\n");
|
||||
ldap_memfree( retoid );
|
||||
ber_bvfree( retdata );
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( lcup && lcup_slimit != -1 && nresponses >= lcup_slimit ) {
|
||||
ldap_abandon (ld, ldap_msgid(msg));
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( ldapsync && sync_slimit != -1 &&
|
||||
nresponses_psearch >= sync_slimit ) {
|
||||
BerElement *msgidber = NULL;
|
||||
struct berval *msgidvalp = NULL;
|
||||
msgidber = ber_alloc_t(LBER_USE_DER);
|
||||
ber_printf(msgidber, "{i}", msgid);
|
||||
ber_flatten(msgidber, &msgidvalp);
|
||||
ldap_extended_operation(ld, LDAP_EXOP_X_CANCEL,
|
||||
msgidvalp, NULL, NULL, &cancel_msgid);
|
||||
nresponses_psearch = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -205,11 +205,29 @@ typedef struct ldapcontrol {
|
||||
|
||||
/*
|
||||
#define LDAP_CLIENT_UPDATE 1
|
||||
#define LDAP_SYNC 2
|
||||
*/
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#define LDAP_CONTROL_CLIENT_UPDATE "1.3.6.1.4.1.4203.666.5.3"
|
||||
#define LDAP_CONTROL_ENTRY_UPDATE "1.3.6.1.4.1.4203.666.5.4"
|
||||
#define LDAP_CONTROL_CLIENT_UPDATE_DONE "1.3.6.1.4.1.4203.666.5.5"
|
||||
#define LDAP_CONTROL_CLIENT_UPDATE_DONE "1.3.6.1.4.1.4203.666.5.5"
|
||||
#define LDAP_LCUP_COOKIE_OID "1.3.6.1.4.1.4203.666.10.1"
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
#define LDAP_CONTROL_SYNC "1.3.6.1.4.1.4203.666.5.TBD1"
|
||||
#define LDAP_CONTROL_SYNC_STATE "1.3.6.1.4.1.4203.666.5.TBD2"
|
||||
#define LDAP_CONTROL_SYNC_DONE "1.3.6.1.4.1.4203.666.5.TBD3"
|
||||
#define LDAP_SYNC_INFO "1.3.6.1.4.1.4203.666.5.TBD4"
|
||||
|
||||
#define LDAP_SYNC_REFRESH_DONE 0
|
||||
#define LDAP_SYNC_NEW_COOKIE 1
|
||||
|
||||
#define LDAP_SYNC_PRESENT 0
|
||||
#define LDAP_SYNC_ADD 1
|
||||
#define LDAP_SYNC_MODIFY 2
|
||||
#define LDAP_SYNC_DELETE 3
|
||||
#endif
|
||||
|
||||
#define LDAP_CONTROL_SORTREQUEST "1.2.840.113556.1.4.473"
|
||||
@ -278,8 +296,12 @@ typedef struct ldapcontrol {
|
||||
#define LDAP_TAG_LDAPCRED ((ber_tag_t) 0x04U) /* octet string */
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#define LDAP_TAG_COOKIE ((ber_tag_t) 0x30U) /* sequence */
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#define LDAP_LCUP_TAG_COOKIE ((ber_tag_t) 0x30U) /* sequence */
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
#define LDAP_SYNC_TAG_COOKIE ((ber_tag_t) 0x04U) /* octet string */
|
||||
#endif
|
||||
|
||||
#define LDAP_TAG_CONTROLS ((ber_tag_t) 0xa0U) /* context specific + constructed + 0 */
|
||||
#define LDAP_TAG_REFERRAL ((ber_tag_t) 0xa3U) /* context specific + constructed + 3 */
|
||||
@ -477,15 +499,7 @@ typedef struct ldapcontrol {
|
||||
#define LDAP_CUP_UNSUPPORTED_SCHEME 0x65
|
||||
#define LDAP_CUP_CLIENT_DISCONNECT 0x66
|
||||
#define LDAP_CUP_RELOAD_REQUIRED 0x67
|
||||
|
||||
/* LCUP update type */
|
||||
#define LDAP_CUP_SYNC_ONLY 0x00
|
||||
#define LDAP_CUP_SYNC_AND_PERSIST 0x01
|
||||
#define LDAP_CUP_PERSIST_ONLY 0x02
|
||||
|
||||
/* LCUP default cookie interval */
|
||||
#define LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL 0x01
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
/* resultCode for Cancel Response */
|
||||
#define LDAP_CANCELLED 0x68
|
||||
@ -498,6 +512,24 @@ typedef struct ldapcontrol {
|
||||
#define LDAP_CANCEL_ACK 0x02
|
||||
#define LDAP_CANCEL_DONE 0x03
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
/* LCUP update type */
|
||||
#define LDAP_CUP_NONE 0x00
|
||||
#define LDAP_CUP_SYNC_ONLY 0x01
|
||||
#define LDAP_CUP_PERSIST_ONLY 0x02
|
||||
#define LDAP_CUP_SYNC_AND_PERSIST 0x03
|
||||
|
||||
/* LCUP default cookie interval */
|
||||
#define LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL 0x01
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
|
||||
/* LDAP SYNC request type */
|
||||
#ifdef LDAP_SYNC
|
||||
#define LDAP_SYNC_NONE 0x00
|
||||
#define LDAP_SYNC_REFRESH_ONLY 0x01
|
||||
#define LDAP_SYNC_REFRESH_AND_PERSIST 0x03
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure represents both ldap messages and ldap responses.
|
||||
* These are really the same, except in the case of search responses,
|
||||
|
@ -92,6 +92,18 @@ static struct ldaperror ldap_builtin_errlist[] = {
|
||||
{LDAP_MORE_RESULTS_TO_RETURN, "More results to return" },
|
||||
{LDAP_CLIENT_LOOP, "Client Loop" },
|
||||
{LDAP_REFERRAL_LIMIT_EXCEEDED, "Referral Limit Exceeded" },
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
{LDAP_CUP_RESOURCES_EXHAUSTED, "LDAP Client Update Resource Exhausted" },
|
||||
{LDAP_CUP_SECURITY_VIOLATION, "LDAP Client Update Security Violation" },
|
||||
{LDAP_CUP_INVALID_COOKIE, "LDAP Client Update Invalid Cookie" },
|
||||
{LDAP_CUP_UNSUPPORTED_SCHEME, "LDAP Client Update Unsupported Scheme" },
|
||||
{LDAP_CUP_CLIENT_DISCONNECT, "LDAP Client Update Client Disconnect" },
|
||||
{LDAP_CUP_RELOAD_REQUIRED, "LDAP Client Update Reload Required" },
|
||||
#endif
|
||||
{LDAP_CANCELLED, "LDAP Cancelled" },
|
||||
{LDAP_NO_SUCH_OPERATION, "LDAP No Operation to Cancel" },
|
||||
{LDAP_TOO_LATE, "LDAP Too Late to Cancel" },
|
||||
{LDAP_CANNOT_CANCEL, "LDAP Cannot Cancel" },
|
||||
|
||||
{-1, NULL}
|
||||
};
|
||||
|
@ -109,7 +109,7 @@ do_abandon(
|
||||
|
||||
done:
|
||||
|
||||
#if LDAP_CLIENT_UPDATE
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
for ( i = 0; i < nbackends; i++ ) {
|
||||
if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
|
||||
if ( bdb_abandon( &backends[i], conn, id ) == LDAP_SUCCESS ) {
|
||||
|
@ -42,7 +42,7 @@ bdb_add(
|
||||
#endif
|
||||
int noop = 0;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
Operation* ps_list;
|
||||
#endif
|
||||
|
||||
@ -547,10 +547,10 @@ return_results:
|
||||
send_ldap_result( conn, op, rc,
|
||||
NULL, text, NULL, NULL );
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !noop ) {
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_ADD );
|
||||
bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_ADD );
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
|
@ -132,7 +132,7 @@ struct bdb_info {
|
||||
|
||||
ID bi_lastid;
|
||||
ldap_pvt_thread_mutex_t bi_lastid_mutex;
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
LDAP_LIST_HEAD(pl, slap_op) psearch_list;
|
||||
#endif
|
||||
#ifdef SLAP_IDL_CACHE
|
||||
|
@ -44,7 +44,7 @@ bdb_delete(
|
||||
|
||||
int noop = 0;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
Operation* ps_list;
|
||||
#endif
|
||||
|
||||
@ -493,13 +493,13 @@ retry: /* transaction retry */
|
||||
return_results:
|
||||
send_ldap_result( conn, op, rc, NULL, text, NULL, NULL );
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !noop ) {
|
||||
LDAP_LIST_FOREACH( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_DELETE );
|
||||
bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_DELETE );
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
if(rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
|
||||
ldap_pvt_thread_yield();
|
||||
|
@ -95,7 +95,7 @@ bdb_db_init( BackendDB *be )
|
||||
bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
|
||||
bdb->bi_search_stack = NULL;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
LDAP_LIST_INIT (&bdb->psearch_list);
|
||||
#endif
|
||||
|
||||
|
@ -13,20 +13,25 @@
|
||||
#include "idl.h"
|
||||
#include "external.h"
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
|
||||
#define IS_BDB_REPLACE (( psearch_type == LDAP_PSEARCH_BY_DELETE ) || \
|
||||
( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT ))
|
||||
#define IS_BDB_LCUP_REPLACE (( protocol == LDAP_CLIENT_UPDATE ) && IS_BDB_REPLACE )
|
||||
|
||||
static int psearch_base_candidate(
|
||||
BackendDB *be,
|
||||
Entry *e,
|
||||
Entry *e,
|
||||
ID *ids );
|
||||
|
||||
static int psearch_candidates(
|
||||
BackendDB *be,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
Filter *filter,
|
||||
int scope,
|
||||
int deref,
|
||||
ID *ids );
|
||||
BackendDB *be,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
Filter *filter,
|
||||
int scope,
|
||||
int deref,
|
||||
ID *ids );
|
||||
|
||||
int
|
||||
bdb_abandon(
|
||||
@ -50,6 +55,39 @@ bdb_abandon(
|
||||
return LDAP_UNAVAILABLE;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_cancel(
|
||||
BackendDB *be,
|
||||
Connection *conn,
|
||||
ber_int_t id )
|
||||
{
|
||||
Operation *ps_list;
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
if ( ps_list->o_connid == conn->c_connid ) {
|
||||
if ( ps_list->o_msgid == id ) {
|
||||
ps_list->o_cancel = LDAP_CANCEL_DONE;
|
||||
LDAP_LIST_REMOVE( ps_list, link );
|
||||
|
||||
#if 0
|
||||
bdb_build_sync_done_ctrl( conn, ps_list, ps_list->ctrls, 1, &latest_entrycsn_bv );
|
||||
send_search_result( conn, ps_list, LDAP_CANCELLED,
|
||||
NULL, NULL, NULL, ps_list->ctrls, ps_list->nentries);
|
||||
#endif
|
||||
send_search_result( conn, ps_list, LDAP_CANCELLED,
|
||||
NULL, NULL, NULL, NULL, 0);
|
||||
|
||||
|
||||
|
||||
slap_op_free ( ps_list );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return LDAP_UNAVAILABLE;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_add_psearch_spec(
|
||||
BackendDB *be,
|
||||
@ -64,30 +102,33 @@ bdb_add_psearch_spec(
|
||||
Filter *filter,
|
||||
struct berval *fstr,
|
||||
AttributeName *attrs,
|
||||
int attrsonly )
|
||||
int attrsonly,
|
||||
int protocol )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec) = (struct lcup_search_spec *)
|
||||
calloc ( 1, sizeof ( struct lcup_search_spec ) );
|
||||
LDAP_LIST_FIRST( &op->psearch_spec ) = (struct ldap_psearch_spec *)
|
||||
calloc ( 1, sizeof ( struct ldap_psearch_spec ) );
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->op = op;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->op = op;
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->base = ber_dupbv(NULL, base);
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->nbase = ber_dupbv(NULL, nbase);
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->base = ber_dupbv(NULL, base);
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->nbase = ber_dupbv(NULL, nbase);
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->scope = scope;
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->deref = deref;
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->slimit = slimit;
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->tlimit = tlimit;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->scope = scope;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->deref = deref;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->slimit = slimit;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->tlimit = tlimit;
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->filter = filter;
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->filterstr = ber_dupbv(NULL, fstr);
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->attrs = attrs;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->filter = filter;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->filterstr = ber_dupbv(NULL, fstr);
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->attrs = attrs;
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->attrsonly = attrsonly;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->attrsonly = attrsonly;
|
||||
|
||||
LDAP_LIST_FIRST(&op->psearch_spec)->entry_count = 0;
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->entry_count = 0;
|
||||
|
||||
LDAP_LIST_FIRST( &op->psearch_spec )->protocol = protocol;
|
||||
|
||||
LDAP_LIST_INSERT_HEAD( &bdb->psearch_list, op, link );
|
||||
}
|
||||
@ -99,26 +140,29 @@ bdb_psearch(
|
||||
Operation *op,
|
||||
Operation *ps_op,
|
||||
Entry *entry,
|
||||
int psearch_type )
|
||||
int psearch_type )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
const char *text = NULL;
|
||||
time_t stoptime;
|
||||
unsigned cursor;
|
||||
ID id;
|
||||
ID candidates[BDB_IDL_UM_SIZE];
|
||||
Entry *e = NULL;
|
||||
BerVarray v2refs = NULL;
|
||||
Entry *matched = NULL;
|
||||
BerVarray v2refs = NULL;
|
||||
Entry *matched = NULL;
|
||||
struct berval realbase = { 0, NULL };
|
||||
int nentries = 0;
|
||||
int manageDSAit;
|
||||
|
||||
Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
|
||||
AttributeAssertion aa_ge, aa_eq;
|
||||
struct berval entrycsn_bv = { 0, NULL };
|
||||
struct berval latest_entrycsn_bv = { 0, NULL };
|
||||
Filter cookief, csnfnot, csnfeq, csnfand, csnfge;
|
||||
AttributeAssertion aa_ge, aa_eq;
|
||||
struct berval entrycsn_bv = { 0, NULL };
|
||||
struct berval latest_entrycsn_bv = { 0, NULL };
|
||||
|
||||
LDAPControl *ctrls[SLAP_SEARCH_MAX_CTRLS];
|
||||
int num_ctrls = 0;
|
||||
|
||||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
@ -128,31 +172,18 @@ bdb_psearch(
|
||||
DB_LOCK lock;
|
||||
|
||||
Connection *ps_conn = ps_op->o_conn;
|
||||
struct berval *base = LDAP_LIST_FIRST(&ps_op->psearch_spec)->base;
|
||||
struct berval *nbase = LDAP_LIST_FIRST(&ps_op->psearch_spec)->nbase;
|
||||
int scope = LDAP_LIST_FIRST(&ps_op->psearch_spec)->scope;
|
||||
int deref = LDAP_LIST_FIRST(&ps_op->psearch_spec)->deref;
|
||||
int slimit = LDAP_LIST_FIRST(&ps_op->psearch_spec)->slimit;
|
||||
int tlimit = LDAP_LIST_FIRST(&ps_op->psearch_spec)->tlimit;
|
||||
Filter *filter = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filter;
|
||||
struct berval *filterstr = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filterstr;
|
||||
int attrsonly = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrsonly;
|
||||
struct berval *base = LDAP_LIST_FIRST( &ps_op->psearch_spec )->base;
|
||||
struct berval *nbase = LDAP_LIST_FIRST( &ps_op->psearch_spec )->nbase;
|
||||
int scope = LDAP_LIST_FIRST( &ps_op->psearch_spec )->scope;
|
||||
int deref = LDAP_LIST_FIRST( &ps_op->psearch_spec )->deref;
|
||||
int slimit = LDAP_LIST_FIRST( &ps_op->psearch_spec )->slimit;
|
||||
int tlimit = LDAP_LIST_FIRST( &ps_op->psearch_spec )->tlimit;
|
||||
Filter *filter = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filter;
|
||||
struct berval *filterstr = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filterstr;
|
||||
int attrsonly = LDAP_LIST_FIRST( &ps_op->psearch_spec )->attrsonly;
|
||||
int protocol = LDAP_LIST_FIRST( &ps_op->psearch_spec )->protocol;
|
||||
AttributeName uuid_attr[2];
|
||||
AttributeName *attrs = uuid_attr;
|
||||
|
||||
if ( psearch_type != LCUP_PSEARCH_BY_DELETE &&
|
||||
psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
{
|
||||
attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
|
||||
} else {
|
||||
attrs[0].an_desc = slap_schema.si_ad_entryUUID;
|
||||
attrs[0].an_oc = NULL;
|
||||
ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
|
||||
attrs[1].an_desc = NULL;
|
||||
attrs[1].an_oc = NULL;
|
||||
attrs[1].an_name.bv_len = 0;
|
||||
attrs[1].an_name.bv_val = NULL;
|
||||
}
|
||||
AttributeName *attrs;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
|
||||
@ -170,10 +201,41 @@ bdb_psearch(
|
||||
default:
|
||||
send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
return rc;
|
||||
}
|
||||
|
||||
for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
|
||||
ctrls[num_ctrls] = NULL;
|
||||
num_ctrls = 0;
|
||||
|
||||
if ( !IS_BDB_REPLACE ) {
|
||||
attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
|
||||
} else {
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( protocol == LDAP_CLIENT_UPDATE ) {
|
||||
attrs = uuid_attr;
|
||||
attrs[0].an_desc = slap_schema.si_ad_entryUUID;
|
||||
attrs[0].an_oc = NULL;
|
||||
ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
|
||||
attrs[1].an_desc = NULL;
|
||||
attrs[1].an_oc = NULL;
|
||||
attrs[1].an_name.bv_len = 0;
|
||||
attrs[1].an_name.bv_val = NULL;
|
||||
} else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if (protocol == LDAP_SYNC ) {
|
||||
attrs = uuid_attr;
|
||||
attrs[0].an_desc = NULL;
|
||||
attrs[0].an_oc = NULL;
|
||||
attrs[0].an_name.bv_len = 0;
|
||||
attrs[0].an_name.bv_val = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rc = 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if ( nbase->bv_len == 0 ) {
|
||||
@ -209,9 +271,10 @@ dn2entry_retry:
|
||||
send_ldap_result( ps_conn, ps_op, LDAP_BUSY,
|
||||
NULL, "ldap server busy", NULL, NULL );
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( IS_BDB_LCUP_REPLACE )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
#endif
|
||||
return LDAP_BUSY;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
@ -228,9 +291,10 @@ dn2entry_retry:
|
||||
send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( IS_BDB_LCUP_REPLACE )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -267,9 +331,10 @@ dn2entry_retry:
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
if ( refs ) ber_bvarray_free( refs );
|
||||
if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( IS_BDB_LCUP_REPLACE )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -307,9 +372,10 @@ dn2entry_retry:
|
||||
LOCK_ID_FREE( bdb->bi_dbenv, locker );
|
||||
ber_bvarray_free( refs );
|
||||
ber_memfree( matched_dn.bv_val );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( IS_BDB_LCUP_REPLACE )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -444,28 +510,61 @@ dn2entry_retry:
|
||||
}
|
||||
}
|
||||
|
||||
lcupf.f_choice = LDAP_FILTER_AND;
|
||||
lcupf.f_and = &csnfnot;
|
||||
lcupf.f_next = NULL;
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( protocol == LDAP_CLIENT_UPDATE ) {
|
||||
cookief.f_choice = LDAP_FILTER_AND;
|
||||
cookief.f_and = &csnfnot;
|
||||
cookief.f_next = NULL;
|
||||
|
||||
csnfnot.f_choice = LDAP_FILTER_NOT;
|
||||
csnfnot.f_not = &csnfeq;
|
||||
csnfnot.f_next = &csnfand;
|
||||
|
||||
csnfnot.f_choice = LDAP_FILTER_NOT;
|
||||
csnfnot.f_not = &csnfeq;
|
||||
csnfnot.f_next = &csnfand;
|
||||
csnfeq.f_choice = LDAP_FILTER_EQUALITY;
|
||||
csnfeq.f_ava = &aa_eq;
|
||||
csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
|
||||
|
||||
csnfeq.f_choice = LDAP_FILTER_EQUALITY;
|
||||
csnfeq.f_ava = &aa_eq;
|
||||
csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
|
||||
csnfand.f_choice = LDAP_FILTER_AND;
|
||||
csnfand.f_and = &csnfge;
|
||||
csnfand.f_next = NULL;
|
||||
|
||||
csnfge.f_choice = LDAP_FILTER_GE;
|
||||
csnfge.f_ava = &aa_ge;
|
||||
csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
|
||||
csnfge.f_next = filter;
|
||||
}
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( protocol == LDAP_SYNC ) {
|
||||
cookief.f_choice = LDAP_FILTER_AND;
|
||||
cookief.f_and = &csnfnot;
|
||||
cookief.f_next = NULL;
|
||||
|
||||
csnfnot.f_choice = LDAP_FILTER_NOT;
|
||||
csnfnot.f_not = &csnfeq;
|
||||
csnfnot.f_next = &csnfand;
|
||||
|
||||
csnfand.f_choice = LDAP_FILTER_AND;
|
||||
csnfand.f_and = &csnfge;
|
||||
csnfand.f_next = NULL;
|
||||
csnfeq.f_choice = LDAP_FILTER_EQUALITY;
|
||||
csnfeq.f_ava = &aa_eq;
|
||||
csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfeq.f_av_value, &ps_op->o_sync_state );
|
||||
|
||||
csnfge.f_choice = LDAP_FILTER_GE;
|
||||
csnfge.f_ava = &aa_ge;
|
||||
csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
|
||||
csnfge.f_next = filter;
|
||||
csnfand.f_choice = LDAP_FILTER_AND;
|
||||
csnfand.f_and = &csnfge;
|
||||
csnfand.f_next = NULL;
|
||||
|
||||
csnfge.f_choice = LDAP_FILTER_GE;
|
||||
csnfge.f_ava = &aa_ge;
|
||||
csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfge.f_av_value, &ps_op->o_sync_state );
|
||||
csnfge.f_next = filter;
|
||||
}
|
||||
#endif
|
||||
|
||||
id = entry->e_id;
|
||||
|
||||
@ -604,8 +703,8 @@ dn2entry_retry:
|
||||
goto test_done;
|
||||
}
|
||||
|
||||
if ( psearch_type != LCUP_PSEARCH_BY_SCOPEOUT ) {
|
||||
rc = test_filter( be, ps_conn, ps_op, e, &lcupf );
|
||||
if ( psearch_type != LDAP_PSEARCH_BY_SCOPEOUT ) {
|
||||
rc = test_filter( be, ps_conn, ps_op, e, &cookief );
|
||||
} else {
|
||||
rc = LDAP_COMPARE_TRUE;
|
||||
}
|
||||
@ -647,144 +746,87 @@ dn2entry_retry:
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_ADD ||
|
||||
psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_MODIFY ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_SYNC
|
||||
int premodify_found = 0;
|
||||
int entry_sync_state;
|
||||
#endif
|
||||
|
||||
if ( psearch_type == LDAP_PSEARCH_BY_ADD ||
|
||||
psearch_type == LDAP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LDAP_PSEARCH_BY_MODIFY ||
|
||||
psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
|
||||
{
|
||||
Attribute* a;
|
||||
int ret;
|
||||
int res;
|
||||
const char *text = NULL;
|
||||
LDAPControl *ctrls[2];
|
||||
struct berval *bv;
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
ber_init2( ber, NULL, LBER_USE_DER );
|
||||
|
||||
LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count++;
|
||||
|
||||
ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
|
||||
ctrls[1] = NULL;
|
||||
|
||||
if ( LDAP_LIST_FIRST(
|
||||
&ps_op->psearch_spec)->entry_count %
|
||||
ps_op->o_clientupdate_interval == 0 )
|
||||
{
|
||||
/* Send cookie */
|
||||
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
|
||||
AttributeDescription *desc = a->a_desc;
|
||||
if ( desc == slap_schema.si_ad_entryCSN ) {
|
||||
ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
|
||||
if ( latest_entrycsn_bv.bv_val == NULL ) {
|
||||
ber_dupbv( &latest_entrycsn_bv,
|
||||
&entrycsn_bv );
|
||||
} else {
|
||||
res = value_match( &ret, desc,
|
||||
desc->ad_type->sat_ordering,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
&entrycsn_bv, &latest_entrycsn_bv,
|
||||
&text );
|
||||
if ( res != LDAP_SUCCESS ) {
|
||||
ret = 0;
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: "
|
||||
"value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: "
|
||||
"value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ret > 0 ) {
|
||||
ch_free(latest_entrycsn_bv.bv_val);
|
||||
latest_entrycsn_bv.bv_val = NULL;
|
||||
ber_dupbv( &latest_entrycsn_bv,
|
||||
&entrycsn_bv );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
{
|
||||
ber_printf( ber, "{bb{sON}N}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_FALSE,
|
||||
LCUP_COOKIE_OID, &entrycsn_bv );
|
||||
} else {
|
||||
ber_printf( ber, "{bb{sON}N}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_TRUE,
|
||||
LCUP_COOKIE_OID, &entrycsn_bv );
|
||||
}
|
||||
|
||||
ch_free( entrycsn_bv.bv_val );
|
||||
entrycsn_bv.bv_val = NULL;
|
||||
|
||||
} else {
|
||||
/* Do not send cookie */
|
||||
if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
{
|
||||
ber_printf( ber, "{bbN}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_FALSE );
|
||||
} else {
|
||||
ber_printf( ber, "{bbN}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
|
||||
ctrls[0]->ldctl_iscritical = ps_op->o_clientupdate;
|
||||
ret = ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
ber_free_buf( ber );
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = send_search_entry( be, ps_conn, ps_op,
|
||||
e, attrs, attrsonly, ctrls);
|
||||
|
||||
ber_free_buf( ber );
|
||||
ch_free( ctrls[0] );
|
||||
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_MODIFY ) {
|
||||
if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
|
||||
struct psid_entry* psid_e;
|
||||
LDAP_LIST_FOREACH( psid_e, &op->premodify_list,
|
||||
link)
|
||||
LDAP_LIST_FOREACH( psid_e, &op->premodify_list, link)
|
||||
{
|
||||
if( psid_e->ps ==
|
||||
LDAP_LIST_FIRST(&ps_op->psearch_spec))
|
||||
if( psid_e->ps == LDAP_LIST_FIRST(&ps_op->psearch_spec))
|
||||
{
|
||||
#ifdef LDAP_SYNC
|
||||
premodify_found = 1;
|
||||
#endif
|
||||
LDAP_LIST_REMOVE(psid_e, link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (psid_e != NULL) free (psid_e);
|
||||
}
|
||||
#ifdef LDAP_SYNC
|
||||
if ( psearch_type == LDAP_PSEARCH_BY_ADD )
|
||||
entry_sync_state = LDAP_SYNC_ADD;
|
||||
else if ( psearch_type == LDAP_PSEARCH_BY_DELETE )
|
||||
entry_sync_state = LDAP_SYNC_DELETE;
|
||||
else if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
|
||||
if ( premodify_found )
|
||||
entry_sync_state = LDAP_SYNC_MODIFY;
|
||||
else
|
||||
entry_sync_state = LDAP_SYNC_ADD;
|
||||
} else if ( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
|
||||
entry_sync_state = LDAP_SYNC_DELETE;
|
||||
else {
|
||||
rc = 1;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if ( psearch_type == LCUP_PSEARCH_BY_PREMODIFY ) {
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( protocol == LDAP_CLIENT_UPDATE ) {
|
||||
int entry_count = ++(LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count);
|
||||
if ( IS_BDB_REPLACE ) {
|
||||
rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
|
||||
num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_TRUE );
|
||||
} else {
|
||||
rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
|
||||
num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
|
||||
}
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
goto done;
|
||||
result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
} else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( protocol == LDAP_SYNC ) {
|
||||
rc = bdb_build_sync_state_ctrl( ps_conn, ps_op, e, entry_sync_state, ctrls,
|
||||
num_ctrls++, 1, &latest_entrycsn_bv );
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
goto done;
|
||||
result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rc = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
} else if ( psearch_type == LDAP_PSEARCH_BY_PREMODIFY ) {
|
||||
struct psid_entry* psid_e;
|
||||
psid_e = (struct psid_entry *) calloc (1,
|
||||
sizeof(struct psid_entry));
|
||||
@ -844,9 +886,10 @@ done:
|
||||
|
||||
if( v2refs ) ber_bvarray_free( v2refs );
|
||||
if( realbase.bv_val ) ch_free( realbase.bv_val );
|
||||
if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
|
||||
psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( IS_BDB_LCUP_REPLACE )
|
||||
ch_free( attrs[0].an_name.bv_val );
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -1034,4 +1077,4 @@ static int psearch_candidates(
|
||||
}
|
||||
|
||||
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
@ -277,7 +277,7 @@ bdb_modify(
|
||||
|
||||
int noop = 0;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
Operation* ps_list;
|
||||
struct psid_entry* pm_list;
|
||||
struct psid_entry* pm_prev;
|
||||
@ -302,7 +302,7 @@ retry: /* transaction retry */
|
||||
"bdb_modify: retrying...\n", 0, 0, 0);
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
@ -423,13 +423,13 @@ retry: /* transaction retry */
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
|
||||
bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
/* Modify the entry */
|
||||
rc = bdb_modify_internal( be, conn, op, ltid, modlist, e,
|
||||
@ -518,23 +518,23 @@ return_results:
|
||||
send_ldap_result( conn, op, rc,
|
||||
NULL, text, NULL, NULL );
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
|
||||
/* Loop through in-scope entries for each psearch spec */
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
|
||||
bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
|
||||
}
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
bdb_psearch(be, conn, op, pm_list->ps->op,
|
||||
e, LCUP_PSEARCH_BY_SCOPEOUT);
|
||||
e, LDAP_PSEARCH_BY_SCOPEOUT);
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
pm_prev = pm_list;
|
||||
pm_list = LDAP_LIST_NEXT ( pm_list, link );
|
||||
free (pm_prev);
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
|
||||
ldap_pvt_thread_yield();
|
||||
@ -544,7 +544,7 @@ return_results:
|
||||
|
||||
done:
|
||||
if( ltid != NULL ) {
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
|
@ -62,7 +62,7 @@ bdb_modrdn(
|
||||
|
||||
int noop = 0;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
Operation* ps_list;
|
||||
struct psid_entry* pm_list;
|
||||
struct psid_entry* pm_prev;
|
||||
@ -95,7 +95,7 @@ retry: /* transaction retry */
|
||||
Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
@ -731,13 +731,13 @@ retry: /* transaction retry */
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
|
||||
bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
/* modify entry */
|
||||
rc = bdb_modify_internal( be, conn, op, ltid, &mod[0], e,
|
||||
@ -833,23 +833,23 @@ return_results:
|
||||
send_ldap_result( conn, op, rc,
|
||||
NULL, text, NULL, NULL );
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
|
||||
/* Loop through in-scope entries for each psearch spec */
|
||||
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
|
||||
bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
|
||||
bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
|
||||
}
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
bdb_psearch(be, conn, op, pm_list->ps->op,
|
||||
e, LCUP_PSEARCH_BY_SCOPEOUT);
|
||||
e, LDAP_PSEARCH_BY_SCOPEOUT);
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
pm_prev = pm_list;
|
||||
pm_list = LDAP_LIST_NEXT ( pm_list, link );
|
||||
free (pm_prev);
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
|
||||
ldap_pvt_thread_yield();
|
||||
@ -893,7 +893,7 @@ done:
|
||||
}
|
||||
|
||||
if( ltid != NULL ) {
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
|
||||
while ( pm_list != NULL ) {
|
||||
LDAP_LIST_REMOVE ( pm_list, link );
|
||||
|
@ -364,13 +364,19 @@ int bdb_cache_delete_entry(
|
||||
);
|
||||
void bdb_cache_release_all( Cache *cache );
|
||||
|
||||
/*
|
||||
* lcup.c
|
||||
*/
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
int bdb_abandon(
|
||||
BackendDB *be,
|
||||
Connection *conn,
|
||||
ber_int_t id
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
int bdb_add_psearch_spec(
|
||||
BackendDB *be,
|
||||
Connection *conn,
|
||||
@ -384,7 +390,8 @@ int bdb_add_psearch_spec(
|
||||
Filter *filter,
|
||||
struct berval *fstr,
|
||||
AttributeName *attrs,
|
||||
int attrsonly
|
||||
int attrsonly,
|
||||
int protocol
|
||||
);
|
||||
|
||||
int bdb_psearch(
|
||||
@ -395,7 +402,66 @@ int bdb_psearch(
|
||||
Entry *entry,
|
||||
int psearch_type
|
||||
);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* search.c
|
||||
*/
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
int
|
||||
bdb_build_lcup_update_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
int entry_count,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
struct berval *latest_entrycsn_bv,
|
||||
int isdeleted );
|
||||
|
||||
int
|
||||
bdb_build_lcup_done_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
struct berval *latest_entrycsn_bv );
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
int
|
||||
bdb_build_sync_state_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
int entry_sync_state,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
int send_cookie,
|
||||
struct berval *latest_entrycsn_bv );
|
||||
|
||||
int
|
||||
bdb_build_sync_done_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
int send_cookie,
|
||||
struct berval *latest_entrycsn_bv );
|
||||
|
||||
int
|
||||
bdb_send_ldap_intermediate(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
ber_int_t err,
|
||||
const char *matched,
|
||||
const char *text,
|
||||
BerVarray refs,
|
||||
const char *rspoid,
|
||||
int state,
|
||||
struct berval *cookie,
|
||||
LDAPControl **ctrls );
|
||||
#endif
|
||||
|
||||
#ifdef BDB_REUSE_LOCKERS
|
||||
|
@ -65,13 +65,20 @@ bdb_search(
|
||||
int tentries = 0;
|
||||
ID lastid = NOID;
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
Filter cookief, csnfnot, csnfeq, csnfand, csnfge;
|
||||
AttributeAssertion aa_ge, aa_eq;
|
||||
int entry_count = 0;
|
||||
struct berval entrycsn_bv = { 0, NULL };
|
||||
struct berval latest_entrycsn_bv = { 0, NULL };
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
struct berval latest_entrycsn_bv = { 0, NULL };
|
||||
LDAPControl *ctrls[SLAP_SEARCH_MAX_CTRLS];
|
||||
int num_ctrls = 0;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
int rc_sync = 0;
|
||||
int entry_sync_state;
|
||||
AttributeName null_attr;
|
||||
#endif
|
||||
|
||||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
@ -88,11 +95,32 @@ bdb_search(
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) {
|
||||
bdb_add_psearch_spec( be, conn, op, base, base, scope,
|
||||
deref, slimit, tlimit, filter, filterstr, attrs, attrsonly );
|
||||
bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
|
||||
tlimit, filter, filterstr, attrs, attrsonly, LDAP_CLIENT_UPDATE );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
/* psearch needs to be registered before refresh begins */
|
||||
/* psearch and refresh transmission is serialized in send_ldap_ber() */
|
||||
if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
|
||||
bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
|
||||
tlimit, filter, filterstr, attrs, attrsonly, LDAP_SYNC );
|
||||
}
|
||||
null_attr.an_desc = NULL;
|
||||
null_attr.an_oc = NULL;
|
||||
null_attr.an_name.bv_len = 0;
|
||||
null_attr.an_name.bv_val = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
|
||||
ctrls[num_ctrls] = NULL;
|
||||
num_ctrls = 0;
|
||||
#endif
|
||||
|
||||
|
||||
manageDSAit = get_manageDSAit( op );
|
||||
@ -394,9 +422,9 @@ dn2entry_retry:
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
|
||||
lcupf.f_choice = LDAP_FILTER_AND;
|
||||
lcupf.f_and = &csnfnot;
|
||||
lcupf.f_next = NULL;
|
||||
cookief.f_choice = LDAP_FILTER_AND;
|
||||
cookief.f_and = &csnfnot;
|
||||
cookief.f_next = NULL;
|
||||
|
||||
csnfnot.f_choice = LDAP_FILTER_NOT;
|
||||
csnfnot.f_not = &csnfeq;
|
||||
@ -417,7 +445,36 @@ dn2entry_retry:
|
||||
ber_dupbv( &csnfge.f_av_value, &op->o_clientupdate_state );
|
||||
csnfge.f_next = filter;
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
|
||||
cookief.f_choice = LDAP_FILTER_AND;
|
||||
cookief.f_and = &csnfnot;
|
||||
cookief.f_next = NULL;
|
||||
|
||||
csnfnot.f_choice = LDAP_FILTER_NOT;
|
||||
csnfnot.f_not = &csnfeq;
|
||||
csnfnot.f_next = &csnfand;
|
||||
|
||||
csnfeq.f_choice = LDAP_FILTER_EQUALITY;
|
||||
csnfeq.f_ava = &aa_eq;
|
||||
csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfeq.f_av_value, &op->o_sync_state );
|
||||
|
||||
csnfand.f_choice = LDAP_FILTER_AND;
|
||||
csnfand.f_and = &csnfge;
|
||||
csnfand.f_next = NULL;
|
||||
|
||||
csnfge.f_choice = LDAP_FILTER_GE;
|
||||
csnfge.f_ava = &aa_ge;
|
||||
csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
|
||||
ber_dupbv( &csnfge.f_av_value, &op->o_sync_state );
|
||||
csnfge.f_next = filter;
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( id = bdb_idl_first( candidates, &cursor );
|
||||
id != NOID;
|
||||
@ -601,9 +658,22 @@ id2entry_retry:
|
||||
/* if it matches the filter and scope, send it */
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
|
||||
rc = test_filter( be, conn, op, e, &lcupf );
|
||||
rc = test_filter( be, conn, op, e, &cookief );
|
||||
} else
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
|
||||
rc_sync = test_filter( be, conn, op, e, &cookief );
|
||||
rc = test_filter( be, conn, op, e, filter );
|
||||
if ( rc == LDAP_COMPARE_TRUE ) {
|
||||
if ( rc_sync == LDAP_COMPARE_TRUE ) {
|
||||
entry_sync_state = LDAP_SYNC_ADD;
|
||||
} else {
|
||||
entry_sync_state = LDAP_SYNC_PRESENT;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rc = test_filter( be, conn, op, e, filter );
|
||||
}
|
||||
@ -658,100 +728,41 @@ id2entry_retry:
|
||||
{
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
|
||||
Attribute* a;
|
||||
int ret;
|
||||
int res;
|
||||
const char *text = NULL;
|
||||
LDAPControl *ctrls[2];
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
ber_init2( ber, 0, LBER_USE_DER );
|
||||
|
||||
entry_count++;
|
||||
|
||||
ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
|
||||
ctrls[1] = NULL;
|
||||
|
||||
if ( entry_count % op->o_clientupdate_interval == 0 ) {
|
||||
/* Send cookie */
|
||||
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
|
||||
AttributeDescription *desc = a->a_desc;
|
||||
if ( desc == slap_schema.si_ad_entryCSN ) {
|
||||
ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
|
||||
if ( latest_entrycsn_bv.bv_val == NULL ) {
|
||||
ber_dupbv( &latest_entrycsn_bv, &entrycsn_bv );
|
||||
} else {
|
||||
res = value_match( &ret, desc,
|
||||
desc->ad_type->sat_ordering,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
&entrycsn_bv, &latest_entrycsn_bv, &text );
|
||||
if ( res != LDAP_SUCCESS ) {
|
||||
ret = 0;
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ret > 0 ) {
|
||||
ch_free( latest_entrycsn_bv.bv_val );
|
||||
latest_entrycsn_bv.bv_val = NULL;
|
||||
ber_dupbv( &latest_entrycsn_bv,
|
||||
&entrycsn_bv );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ber_printf( ber,
|
||||
"{bb{sON}N}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_FALSE,
|
||||
LCUP_COOKIE_OID, &entrycsn_bv );
|
||||
|
||||
ch_free( entrycsn_bv.bv_val );
|
||||
entrycsn_bv.bv_val = NULL;
|
||||
|
||||
} else {
|
||||
/* Do not send cookie */
|
||||
ber_printf( ber,
|
||||
"{bbN}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
SLAP_LCUP_ENTRY_DELETED_FALSE );
|
||||
}
|
||||
|
||||
ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
|
||||
ctrls[0]->ldctl_iscritical = op->o_clientupdate;
|
||||
ret = ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 );
|
||||
if ( ret < 0 ) {
|
||||
ber_free_buf( ber );
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
rc = bdb_build_lcup_update_ctrl( conn, op, e, ++entry_count, ctrls,
|
||||
num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
goto done;
|
||||
result = send_search_entry( be, conn, op,
|
||||
e, attrs, attrsonly, ctrls);
|
||||
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
} else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
|
||||
rc = bdb_build_sync_state_ctrl( conn, op, e, entry_sync_state, ctrls,
|
||||
num_ctrls++, 0, &latest_entrycsn_bv );
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
goto done;
|
||||
|
||||
if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
|
||||
result = send_search_entry( be, conn, op,
|
||||
e, attrs, attrsonly, ctrls);
|
||||
} else { /* PRESENT */
|
||||
result = send_search_entry( be, conn, op,
|
||||
e, &null_attr, attrsonly, ctrls);
|
||||
}
|
||||
|
||||
result = send_search_entry( be, conn, op,
|
||||
e, attrs, attrsonly, ctrls);
|
||||
|
||||
ber_free_buf( ber );
|
||||
ch_free( ctrls[0] );
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
} else
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
{
|
||||
result = send_search_entry( be, conn, op,
|
||||
e, attrs, attrsonly, NULL);
|
||||
@ -806,47 +817,44 @@ loop_continue:
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
|
||||
int ret;
|
||||
LDAPControl *ctrls[2];
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
ber_init2( ber, NULL, LBER_USE_DER );
|
||||
|
||||
ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
|
||||
ctrls[1] = NULL;
|
||||
|
||||
ber_printf( ber, "{sO", LCUP_COOKIE_OID, &latest_entrycsn_bv );
|
||||
ber_printf( ber, "N}" );
|
||||
|
||||
ctrls[0]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
|
||||
ctrls[0]->ldctl_iscritical = op->o_clientupdate;
|
||||
ret = ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
ber_free_buf( ber );
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: ber_flatten2 failed\n", 0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
goto done;
|
||||
}
|
||||
bdb_build_lcup_done_ctrl( conn, op, ctrls, num_ctrls++, &latest_entrycsn_bv );
|
||||
|
||||
send_search_result( conn, op,
|
||||
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
|
||||
NULL, NULL, v2refs, ctrls, nentries );
|
||||
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
|
||||
NULL, NULL, v2refs, ctrls, nentries );
|
||||
|
||||
ch_free( latest_entrycsn_bv.bv_val );
|
||||
latest_entrycsn_bv.bv_val = NULL;
|
||||
ch_free( ctrls[0] );
|
||||
ber_free_buf( ber );
|
||||
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
} else
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
|
||||
if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
|
||||
/* refreshAndPersist mode */
|
||||
bdb_send_ldap_intermediate( conn, op,
|
||||
LDAP_SUCCESS, NULL, NULL, NULL, LDAP_SYNC_INFO,
|
||||
LDAP_SYNC_REFRESH_DONE, &latest_entrycsn_bv, NULL );
|
||||
} else {
|
||||
/* refreshOnly mode */
|
||||
bdb_build_sync_done_ctrl( conn, op, ctrls, num_ctrls++, 1, &latest_entrycsn_bv );
|
||||
send_search_result( conn, op,
|
||||
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
|
||||
NULL, NULL, v2refs, ctrls, nentries );
|
||||
if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
|
||||
ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
|
||||
ch_free( ctrls[--num_ctrls] );
|
||||
ctrls[num_ctrls] = NULL;
|
||||
}
|
||||
|
||||
ch_free( latest_entrycsn_bv.bv_val );
|
||||
latest_entrycsn_bv.bv_val = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
send_search_result( conn, op,
|
||||
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
|
||||
@ -871,7 +879,21 @@ done:
|
||||
ch_free( csnfge.f_av_value.bv_val );
|
||||
}
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
|
||||
if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
|
||||
ch_free( csnfeq.f_av_value.bv_val );
|
||||
}
|
||||
|
||||
if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
|
||||
ch_free( csnfge.f_av_value.bv_val );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
|
||||
@ -1159,3 +1181,333 @@ done:
|
||||
(void) ber_free_buf( ber );
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
int
|
||||
bdb_build_lcup_update_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
int entry_count,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
struct berval *latest_entrycsn_bv,
|
||||
int isdeleted )
|
||||
{
|
||||
Attribute* a;
|
||||
int ret;
|
||||
int res;
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
struct berval entrycsn_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_entryCSN ) {
|
||||
ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
|
||||
if ( latest_entrycsn_bv->bv_val == NULL ) {
|
||||
ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
|
||||
} else {
|
||||
res = value_match( &ret, desc,
|
||||
desc->ad_type->sat_ordering,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
&entrycsn_bv, latest_entrycsn_bv, &text );
|
||||
if ( res != LDAP_SUCCESS ) {
|
||||
ret = 0;
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( ret > 0 ) {
|
||||
ch_free( latest_entrycsn_bv->bv_val );
|
||||
latest_entrycsn_bv->bv_val = NULL;
|
||||
ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( entry_count % op->o_clientupdate_interval == 0 )
|
||||
ber_printf( ber,
|
||||
"{bb{sON}N}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
isdeleted,
|
||||
LDAP_LCUP_COOKIE_OID, &entrycsn_bv );
|
||||
else /* Do not send cookie */
|
||||
ber_printf( ber,
|
||||
"{bbN}",
|
||||
SLAP_LCUP_STATE_UPDATE_FALSE,
|
||||
isdeleted );
|
||||
|
||||
ch_free( entrycsn_bv.bv_val );
|
||||
entrycsn_bv.bv_val = NULL;
|
||||
|
||||
ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
|
||||
ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
|
||||
ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
|
||||
|
||||
ber_free_buf( ber );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_build_lcup_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_build_lcup_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_build_lcup_done_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
struct berval *latest_entrycsn_bv )
|
||||
{
|
||||
int ret, rc;
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
ber_init2( ber, NULL, LBER_USE_DER );
|
||||
|
||||
ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
|
||||
|
||||
ber_printf( ber, "{sO", LDAP_LCUP_COOKIE_OID, latest_entrycsn_bv );
|
||||
ber_printf( ber, "N}" );
|
||||
|
||||
ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
|
||||
ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
|
||||
ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
|
||||
|
||||
ber_free_buf( ber );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
int
|
||||
bdb_build_sync_state_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
Entry *e,
|
||||
int entry_sync_state,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
int send_cookie,
|
||||
struct berval *latest_entrycsn_bv )
|
||||
{
|
||||
Attribute* a;
|
||||
int ret;
|
||||
int res;
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
struct berval entryuuid_bv = { 0, NULL };
|
||||
struct berval entrycsn_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_entryCSN ) {
|
||||
ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
|
||||
if ( latest_entrycsn_bv->bv_val == NULL ) {
|
||||
ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
|
||||
} else {
|
||||
res = value_match( &ret, desc,
|
||||
desc->ad_type->sat_ordering,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
&entrycsn_bv, latest_entrycsn_bv, &text );
|
||||
if ( res != LDAP_SUCCESS ) {
|
||||
ret = 0;
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: value_match failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
}
|
||||
if ( ret > 0 ) {
|
||||
ch_free( latest_entrycsn_bv->bv_val );
|
||||
latest_entrycsn_bv->bv_val = NULL;
|
||||
ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
|
||||
}
|
||||
}
|
||||
} else if ( desc == slap_schema.si_ad_entryUUID ) {
|
||||
ber_dupbv( &entryuuid_bv, &a->a_vals[0] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( send_cookie )
|
||||
ber_printf( ber, "{eOON}", entry_sync_state, &entryuuid_bv, &entrycsn_bv );
|
||||
else
|
||||
ber_printf( ber, "{eON}", entry_sync_state, &entryuuid_bv );
|
||||
|
||||
ch_free( entrycsn_bv.bv_val );
|
||||
entrycsn_bv.bv_val = NULL;
|
||||
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,
|
||||
"bdb_build_sync_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_build_sync_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_build_sync_done_ctrl(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
LDAPControl **ctrls,
|
||||
int num_ctrls,
|
||||
int send_cookie,
|
||||
struct berval *latest_entrycsn_bv )
|
||||
{
|
||||
int ret,rc;
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
|
||||
ber_init2( ber, NULL, LBER_USE_DER );
|
||||
|
||||
ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
|
||||
|
||||
if ( send_cookie ) {
|
||||
ber_printf( ber, "{ON}", latest_entrycsn_bv );
|
||||
} 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,
|
||||
"bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_send_ldap_intermediate(
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
ber_int_t err,
|
||||
const char *matched,
|
||||
const char *text,
|
||||
BerVarray refs,
|
||||
const char *rspoid,
|
||||
int state,
|
||||
struct berval *cookie,
|
||||
LDAPControl **ctrls )
|
||||
{
|
||||
char berbuf[LBER_ELEMENT_SIZEOF];
|
||||
BerElement *ber = (BerElement *)berbuf;
|
||||
struct berval rspdata;
|
||||
|
||||
int ret, rc;
|
||||
|
||||
ber_init2( ber, NULL, LBER_USE_DER );
|
||||
|
||||
if ( cookie == NULL )
|
||||
ber_printf( ber, "{eN}", state );
|
||||
else
|
||||
ber_printf( ber, "{eON}", state, cookie );
|
||||
|
||||
ret = ber_flatten2( ber, &rspdata, 0 );
|
||||
|
||||
if ( ret < 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
send_ldap_result( conn, op, rc=LDAP_OTHER,
|
||||
NULL, "internal error", NULL, NULL );
|
||||
return ret;
|
||||
}
|
||||
|
||||
send_ldap_intermediate_resp( conn, op, err, matched, text, refs, rspoid, &rspdata, ctrls );
|
||||
|
||||
ber_free_buf( ber );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@ int cancel_extop(
|
||||
int found = 0;
|
||||
int opid;
|
||||
BerElement *ber;
|
||||
int i;
|
||||
|
||||
assert( reqoid != NULL );
|
||||
assert( strcmp( LDAP_EXOP_X_CANCEL, reqoid ) == 0 );
|
||||
@ -86,9 +87,22 @@ int cancel_extop(
|
||||
}
|
||||
|
||||
if ( !found ) {
|
||||
#ifdef LDAP_SYNC
|
||||
for ( i = 0; i < nbackends; i++ ) {
|
||||
if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
if ( bdb_cancel( &backends[i], conn, opid ) == LDAP_SUCCESS ) {
|
||||
return LDAP_SUCCESS;
|
||||
} else {
|
||||
*text = "message ID not found";
|
||||
return LDAP_NO_SUCH_OPERATION;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*text = "message ID not found";
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
return LDAP_NO_SUCH_OPERATION;
|
||||
return LDAP_NO_SUCH_OPERATION;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( op->o_cancel != LDAP_CANCEL_NONE ) {
|
||||
@ -114,3 +128,4 @@ int cancel_extop(
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1040,12 +1040,26 @@ operations_error:
|
||||
|
||||
LDAP_STAILQ_REMOVE( &conn->c_ops, arg->co_op, slap_op, o_next);
|
||||
LDAP_STAILQ_NEXT(arg->co_op, o_next) = NULL;
|
||||
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
if ( arg->co_op->o_cancel == LDAP_CANCEL_ACK )
|
||||
goto co_op_free;
|
||||
#endif
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( !( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
{
|
||||
slap_op_free( arg->co_op );
|
||||
}
|
||||
if ( ( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
|
||||
goto no_co_op_free;
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( ( arg->co_op->o_sync_mode & SLAP_SYNC_PERSIST ) )
|
||||
goto no_co_op_free;
|
||||
#endif
|
||||
|
||||
co_op_free:
|
||||
|
||||
slap_op_free( arg->co_op );
|
||||
|
||||
no_co_op_free:
|
||||
|
||||
arg->co_op = NULL;
|
||||
arg->co_conn = NULL;
|
||||
free( (char *) arg );
|
||||
|
@ -58,6 +58,9 @@ static SLAP_CTRL_PARSE_FN parseSubentries;
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
static SLAP_CTRL_PARSE_FN parseClientUpdate;
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
static SLAP_CTRL_PARSE_FN parseLdupSync;
|
||||
#endif
|
||||
|
||||
#undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
|
||||
|
||||
@ -108,7 +111,12 @@ static struct slap_control {
|
||||
{ LDAP_CONTROL_CLIENT_UPDATE,
|
||||
SLAP_CTRL_SEARCH, NULL,
|
||||
parseClientUpdate },
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
{ LDAP_CONTROL_SYNC,
|
||||
SLAP_CTRL_SEARCH, NULL,
|
||||
parseLdupSync },
|
||||
#endif
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
@ -829,6 +837,13 @@ static int parseClientUpdate (
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync != SLAP_NO_CONTROL ) {
|
||||
*text = "LDAP Client Update and Sync controls used together";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( ctrl->ldctl_value.bv_len == 0 ) {
|
||||
*text = "LCUP client update control value is empty (or absent)";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
@ -897,7 +912,7 @@ static int parseClientUpdate (
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if ( tag == LDAP_TAG_COOKIE ) {
|
||||
if ( tag == LDAP_LCUP_TAG_COOKIE ) {
|
||||
if ( (tag = ber_scanf( ber, /*{*/ "{mm}}",
|
||||
&scheme, &cookie )) == LBER_ERROR ) {
|
||||
*text = "LCUP client update control : decoding error";
|
||||
@ -931,4 +946,113 @@ static int parseClientUpdate (
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
static int parseLdupSync (
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
LDAPControl *ctrl,
|
||||
const char **text )
|
||||
{
|
||||
ber_tag_t tag;
|
||||
BerElement *ber;
|
||||
ber_int_t mode;
|
||||
ber_len_t len;
|
||||
struct berval cookie = { 0, NULL };
|
||||
|
||||
if ( op->o_sync != SLAP_NO_CONTROL ) {
|
||||
*text = "LDAP Sync control specified multiple times";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( op->o_clientupdate != SLAP_NO_CONTROL ) {
|
||||
*text = "LDAP Sync and LDAP Client Update controls used together";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( ctrl->ldctl_value.bv_len == 0 ) {
|
||||
*text = "LDAP Sync control value is empty (or absent)";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Parse the control value
|
||||
* syncRequestValue ::= SEQUENCE {
|
||||
* mode ENUMERATED {
|
||||
* -- 0 unused
|
||||
* refreshOnly (1),
|
||||
* -- 2 reserved
|
||||
* refreshAndPersist (3)
|
||||
* },
|
||||
* cookie syncCookie OPTIONAL
|
||||
* }
|
||||
*/
|
||||
|
||||
ber = ber_init( &ctrl->ldctl_value );
|
||||
if( ber == NULL ) {
|
||||
*text = "internal error";
|
||||
return LDAP_OTHER;
|
||||
}
|
||||
|
||||
if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
|
||||
*text = "LDAP Sync control : mode decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
switch( mode ) {
|
||||
case LDAP_SYNC_REFRESH_ONLY:
|
||||
mode = SLAP_SYNC_REFRESH;
|
||||
break;
|
||||
case LDAP_SYNC_REFRESH_AND_PERSIST:
|
||||
mode = SLAP_SYNC_REFRESH_AND_PERSIST;
|
||||
break;
|
||||
default:
|
||||
*text = "LDAP Sync control : unknown update mode";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
tag = ber_peek_tag( ber, &len );
|
||||
|
||||
if ( tag == LDAP_SYNC_TAG_COOKIE ) {
|
||||
if (( ber_scanf( ber, /*{*/ "m}",
|
||||
&cookie )) == LBER_ERROR ) {
|
||||
*text = "LDAP Sync control : cookie decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
|
||||
*text = "LDAP Sync control : decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
cookie.bv_len = 0;
|
||||
cookie.bv_val = NULL;
|
||||
}
|
||||
|
||||
/* TODO : Cookie Scheme Validation */
|
||||
#if 0
|
||||
if ( lcup_cookie_scheme_validate(scheme) != LDAP_SUCCESS ) {
|
||||
*text = "Unsupported LCUP cookie scheme";
|
||||
return LCUP_UNSUPPORTED_SCHEME;
|
||||
}
|
||||
|
||||
if ( lcup_cookie_validate(scheme, cookie) != LDAP_SUCCESS ) {
|
||||
*text = "Invalid LCUP cookie";
|
||||
return LCUP_INVALID_COOKIE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ber_dupbv( &op->o_sync_state, &cookie );
|
||||
|
||||
(void) ber_free( ber, 1 );
|
||||
|
||||
op->o_sync_mode = (char) mode;
|
||||
|
||||
op->o_sync = ctrl->ldctl_iscritical
|
||||
? SLAP_CRITICAL_CONTROL
|
||||
: SLAP_NONCRITICAL_CONTROL;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
@ -46,7 +46,12 @@ slap_op_free( Operation *op )
|
||||
if ( op->o_clientupdate_state.bv_val != NULL ) {
|
||||
free( op->o_clientupdate_state.bv_val );
|
||||
}
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( op->o_sync_state.bv_val != NULL ) {
|
||||
free( op->o_sync_state.bv_val );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( LDAP_SLAPI )
|
||||
if ( op->o_pb != NULL ) {
|
||||
|
@ -415,20 +415,28 @@ do_search(
|
||||
#endif /* LDAP_SLAPI */
|
||||
|
||||
return_results:;
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( !( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
{
|
||||
if( pbase.bv_val != NULL) free( pbase.bv_val );
|
||||
if( nbase.bv_val != NULL) free( nbase.bv_val );
|
||||
|
||||
if( fstr.bv_val != NULL) free( fstr.bv_val );
|
||||
if( filter != NULL) filter_free( filter );
|
||||
if( an != NULL ) free( an );
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
if ( ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
|
||||
return rc;
|
||||
#endif
|
||||
#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
|
||||
else
|
||||
#endif
|
||||
#ifdef LDAP_SYNC
|
||||
if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
if( pbase.bv_val != NULL) free( pbase.bv_val );
|
||||
if( nbase.bv_val != NULL) free( nbase.bv_val );
|
||||
|
||||
if( fstr.bv_val != NULL) free( fstr.bv_val );
|
||||
if( filter != NULL) filter_free( filter );
|
||||
if( an != NULL ) free( an );
|
||||
#ifdef LDAP_SLAPI
|
||||
if( attrs != NULL) ch_free( attrs );
|
||||
if( attrs != NULL) ch_free( attrs );
|
||||
#endif /* LDAP_SLAPI */
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1615,14 +1615,14 @@ typedef struct slap_paged_state {
|
||||
} PagedResultsState;
|
||||
|
||||
|
||||
#ifdef LDAP_CLIENT_UPDATE
|
||||
#define LCUP_PSEARCH_BY_ADD 0x01
|
||||
#define LCUP_PSEARCH_BY_DELETE 0x02
|
||||
#define LCUP_PSEARCH_BY_PREMODIFY 0x03
|
||||
#define LCUP_PSEARCH_BY_MODIFY 0x04
|
||||
#define LCUP_PSEARCH_BY_SCOPEOUT 0x05
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
#define LDAP_PSEARCH_BY_ADD 0x01
|
||||
#define LDAP_PSEARCH_BY_DELETE 0x02
|
||||
#define LDAP_PSEARCH_BY_PREMODIFY 0x03
|
||||
#define LDAP_PSEARCH_BY_MODIFY 0x04
|
||||
#define LDAP_PSEARCH_BY_SCOPEOUT 0x05
|
||||
|
||||
struct lcup_search_spec {
|
||||
struct ldap_psearch_spec {
|
||||
struct slap_op *op;
|
||||
struct berval *base;
|
||||
struct berval *nbase;
|
||||
@ -1634,17 +1634,16 @@ struct lcup_search_spec {
|
||||
struct berval *filterstr;
|
||||
AttributeName *attrs;
|
||||
int attrsonly;
|
||||
struct lcup_entry *elist;
|
||||
ldap_pvt_thread_mutex_t elist_mutex;
|
||||
int protocol;
|
||||
int entry_count;
|
||||
LDAP_LIST_ENTRY(lcup_search_spec) link;
|
||||
LDAP_LIST_ENTRY(ldap_psearch_spec) link;
|
||||
};
|
||||
|
||||
struct psid_entry {
|
||||
struct lcup_search_spec* ps;
|
||||
struct ldap_psearch_spec* ps;
|
||||
LDAP_LIST_ENTRY(psid_entry) link;
|
||||
};
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@ -1691,13 +1690,26 @@ typedef struct slap_op {
|
||||
#define SLAP_LCUP_NONE (0x0)
|
||||
#define SLAP_LCUP_SYNC (0x1)
|
||||
#define SLAP_LCUP_PERSIST (0x2)
|
||||
#define SLAP_LCUP_SYNC_AND_PERSIST (0x3)
|
||||
#define SLAP_LCUP_SYNC_AND_PERSIST (0x3)
|
||||
ber_int_t o_clientupdate_interval;
|
||||
struct berval o_clientupdate_state;
|
||||
LDAP_LIST_HEAD(lss, lcup_search_spec) psearch_spec;
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_SYNC
|
||||
char o_sync;
|
||||
char o_sync_mode;
|
||||
#define SLAP_SYNC_NONE (0x0)
|
||||
#define SLAP_SYNC_REFRESH (0x1)
|
||||
#define SLAP_SYNC_PERSIST (0x2)
|
||||
#define SLAP_SYNC_REFRESH_AND_PERSIST (0x3)
|
||||
struct berval o_sync_state;
|
||||
#endif
|
||||
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
LDAP_LIST_HEAD(lss, ldap_psearch_spec) psearch_spec;
|
||||
LDAP_LIST_HEAD(pe, psid_entry) premodify_list;
|
||||
LDAP_LIST_ENTRY(slap_op) link;
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_CONNECTIONLESS
|
||||
Sockaddr o_peeraddr; /* UDP peer address */
|
||||
@ -1997,6 +2009,10 @@ enum {
|
||||
#define SLAP_LCUP_ENTRY_DELETED_FALSE 0
|
||||
#endif /* LDAP_CLIENT_UPDATE */
|
||||
|
||||
#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
|
||||
#define SLAP_SEARCH_MAX_CTRLS 10
|
||||
#endif
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#include "proto-slap.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user