LDAPMod **attrs;
struct berval mdn = BER_BVNULL, mapped;
dncookie dc;
+ int msgid;
int do_retry = 1;
Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",
attrs[ i ] = NULL;
retry:;
-#if 0
rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
attrs, op->o_ctrls, NULL, &msgid );
- rs->sr_err = meta_back_op_result( op, rs, &mc->mc_conns[ candidate ], msgid, LDAP_BACK_SENDERR );
-#endif
- rs->sr_err = ldap_add_ext_s( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
- attrs, op->o_ctrls, NULL );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
+
+ } else if ( rs->sr_err == LDAP_SUCCESS ) {
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *res = NULL;
+
+ if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_ADD ];
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
+ msgid, LDAP_MSG_ONE, tvp, &res );
+ switch ( rs->sr_err ) {
+ case -1:
+ rs->sr_err = LDAP_OTHER;
+ send_ldap_result( op, rs );
+ goto cleanup;
+
+ case 0:
+ ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
+ msgid, NULL, NULL );
+ rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
+ LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
+ send_ldap_result( op, rs );
+ goto cleanup;
+
+ default:
+ ldap_msgfree( res );
+ break;
+ }
}
+ (void)meta_back_op_result( mc, op, rs, candidate );
+
+cleanup:;
for ( --i; i >= 0; --i ) {
free( attrs[ i ]->mod_bvalues );
free( attrs[ i ] );
BER_BVZERO( &mdn );
}
- (void)meta_back_op_result( mc, op, rs, candidate );
-
done:;
meta_back_release_conn( op, mc );
* in one block with the metaconn_t structure */
} metaconn_t;
+enum {
+ META_OP_ADD = 0,
+ META_OP_DELETE,
+ META_OP_MODIFY,
+ META_OP_MODRDN,
+ META_OP_LAST
+};
+
typedef struct metatarget_t {
char *mt_uri;
unsigned mt_flags;
int mt_version;
+ time_t mt_timeout[ META_OP_LAST ];
} metatarget_t;
typedef struct metadncache_t {
#define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) )
int mi_version;
+ time_t mi_timeout[ META_OP_LAST ];
} metainfo_t;
typedef enum meta_op_type {
LDAPURLDesc *ludp, *tmpludp;
struct berval dn;
int rc;
+ int c;
if ( argc != 2 ) {
fprintf( stderr,
mi->mi_targets[ i ].mt_flags = mi->flags;
mi->mi_targets[ i ].mt_version = mi->mi_version;
+ for ( c = 0; c < META_OP_LAST; c++ ) {
+ mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
+ }
+
/*
* uri MUST be legal!
*/
return 1;
}
+ } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
+ char *sep, *next;
+ time_t *tv = mi->mi_ntargets ?
+ &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
+ : &mi->mi_timeout;
+ int c;
+
+ if ( argc < 2 ) {
+ fprintf( stderr,
+ "%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
+ fname, lineno );
+ return( 1 );
+ }
+
+ for ( c = 1; c < argc; c++ ) {
+ time_t *t = NULL, val;
+
+ sep = strchr( argv[ c ], '=' );
+ if ( sep != NULL ) {
+ size_t len = sep - argv[ c ];
+
+ if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
+ t = &tv[ META_OP_ADD ];
+ } else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
+ t = &tv[ META_OP_DELETE ];
+ } else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
+ t = &tv[ META_OP_MODIFY ];
+ } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
+ t = &tv[ META_OP_MODRDN ];
+ } else {
+ fprintf( stderr,
+ "%s: line %d: unknown operation \"%s\" for timeout #%d.\n",
+ fname, lineno, argv[ c ], c );
+ return 1;
+ }
+ sep++;
+
+ } else {
+ sep = argv[ c ];
+ }
+
+ val = strtoul( sep, &next, 10 );
+ if ( next == sep || next[ 0 ] != '\0' ) {
+ fprintf( stderr,
+ "%s: line %d: unable to parse value \"%s\" for timeout.\n",
+ fname, lineno, sep );
+ return 1;
+ }
+
+ if ( t ) {
+ *t = val;
+
+ } else {
+ int i;
+
+ for ( i = 0; i < META_OP_LAST; i++ ) {
+ tv[ i ] = val;
+ }
+ }
+ }
+
/* name to use as pseudo-root dn */
} else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
int i = mi->mi_ntargets - 1;
int candidate = -1;
struct berval mdn = BER_BVNULL;
dncookie dc;
+ int msgid;
int do_retry = 1;
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
}
retry:;
- rs->sr_err = ldap_delete_ext_s( mc->mc_conns[ candidate ].msc_ld,
- mdn.bv_val, op->o_ctrls, NULL );
+ rs->sr_err = ldap_delete_ext( mc->mc_conns[ candidate ].msc_ld,
+ mdn.bv_val, op->o_ctrls, NULL, &msgid );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
+
+ } else if ( rs->sr_err == LDAP_SUCCESS ) {
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *res = NULL;
+
+ if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_DELETE ];
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
+ msgid, LDAP_MSG_ONE, tvp, &res );
+ switch ( rs->sr_err ) {
+ case -1:
+ rs->sr_err = LDAP_OTHER;
+ send_ldap_result( op, rs );
+ goto cleanup;
+
+ case 0:
+ ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
+ msgid, NULL, NULL );
+ rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
+ LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
+ send_ldap_result( op, rs );
+ goto cleanup;
+
+ default:
+ ldap_msgfree( res );
+ break;
+ }
}
+ rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
+
+cleanup:;
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
free( mdn.bv_val );
BER_BVZERO( &mdn );
}
- rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
-
done:;
meta_back_release_conn( op, mc );
struct berval mdn = BER_BVNULL;
struct berval mapped;
dncookie dc;
+ int msgid;
int do_retry = 1;
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
modv[ i ] = 0;
retry:;
- rs->sr_err = ldap_modify_ext_s( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
- modv, op->o_ctrls, NULL );
+ rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
+ modv, op->o_ctrls, NULL, &msgid );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
+
+ } else if ( rs->sr_err == LDAP_SUCCESS ) {
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *res = NULL;
+
+ if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODIFY ];
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
+ msgid, LDAP_MSG_ONE, tvp, &res );
+ switch ( rs->sr_err ) {
+ case -1:
+ rs->sr_err = LDAP_OTHER;
+ rc = -1;
+ break;
+
+ case 0:
+ ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
+ msgid, NULL, NULL );
+ rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
+ LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
+ rc = -1;
+ break;
+
+ default:
+ ldap_msgfree( res );
+ break;
+ }
}
cleanup:;
int
meta_back_modrdn( Operation *op, SlapReply *rs )
{
- metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metaconn_t *mc;
- int candidate = -1;
- struct berval mdn = BER_BVNULL,
- mnewSuperior = BER_BVNULL;
- dncookie dc;
- int do_retry = 1;
+ metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
+ metaconn_t *mc;
+ int candidate = -1;
+ struct berval mdn = BER_BVNULL,
+ mnewSuperior = BER_BVNULL;
+ dncookie dc;
+ int msgid;
+ int do_retry = 1;
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
}
retry:;
- rs->sr_err = ldap_rename_s( mc->mc_conns[ candidate ].msc_ld,
+ rs->sr_err = ldap_rename( mc->mc_conns[ candidate ].msc_ld,
mdn.bv_val, op->orr_newrdn.bv_val,
mnewSuperior.bv_val, op->orr_deleteoldrdn,
- op->o_ctrls, NULL );
+ op->o_ctrls, NULL, &msgid );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
+
+ } else if ( rs->sr_err == LDAP_SUCCESS ) {
+ struct timeval tv, *tvp = NULL;
+ LDAPMessage *res = NULL;
+
+ if ( mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ] != 0 ) {
+ tv.tv_sec = mi->mi_targets[ candidate ].mt_timeout[ META_OP_MODRDN ];
+ tv.tv_usec = 0;
+ tvp = &tv;
+ }
+
+ rs->sr_err = ldap_result( mc->mc_conns[ candidate ].msc_ld,
+ msgid, LDAP_MSG_ONE, tvp, &res );
+ switch ( rs->sr_err ) {
+ case -1:
+ rs->sr_err = LDAP_OTHER;
+ break;
+
+ case 0:
+ ldap_abandon_ext( mc->mc_conns[ candidate ].msc_ld,
+ msgid, NULL, NULL );
+ rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
+ LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR;
+ break;
+
+ default:
+ ldap_msgfree( res );
+ break;
+ }
}
cleanup:;