{ BER_BVC("modrdn="), SLAP_OP_MODRDN * sizeof( time_t ), 'u', 0, NULL },
{ BER_BVC("modify="), SLAP_OP_MODIFY * sizeof( time_t ), 'u', 0, NULL },
{ BER_BVC("compare="), SLAP_OP_COMPARE * sizeof( time_t ), 'u', 0, NULL },
-#if 0 /* uses timelimit instead */
{ BER_BVC("search="), SLAP_OP_SEARCH * sizeof( time_t ), 'u', 0, NULL },
-#endif
/* abandon makes little sense */
#if 0 /* not implemented yet */
{ BER_BVC("extended="), SLAP_OP_EXTENDED * sizeof( time_t ), 'u', 0, NULL },
}
}
+ /* if needed, initialize timeout */
+ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
+ if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) {
+ tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ];
+ tv.tv_usec = 0;
+ }
+ }
+
/* We pull apart the ber result, stuff it into a slapd entry, and
* let send_search_entry stuff it back into ber format. Slow & ugly,
* but this is necessary for version matching, and for ACL processing.
*/
- for ( rc = 0; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) )
+ for ( rc = -2; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) )
{
/* check for abandon */
if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( lc ) ) {
goto finish;
}
- if ( rc == 0 ) {
- LDAP_BACK_TV_SET( &tv );
+ if ( rc == 0 || rc == -2 ) {
ldap_pvt_thread_yield();
+ /* check timeout */
+ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
+ if ( rc == 0 ) {
+ (void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
+ rs->sr_text = "Operation timed out";
+ rc = rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
+ goto finish;
+ }
+
+ } else {
+ LDAP_BACK_TV_SET( &tv );
+ }
+
/* check time limit */
if ( op->ors_tlimit != SLAP_NO_LIMIT
&& slap_get_time() > stoptime )
rc = 0;
break;
}
+
+ /* if needed, restore timeout */
+ if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
+ if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) {
+ tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ];
+ tv.tv_usec = 0;
+ }
+ }
}
if ( rc == -1 && dont_retry == 0 ) {