diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c
index 494898a762f35f7eb5fe97f2768d25c6579090dd..8bcbb9b767feaed9b9690367b33665ed250906ed 100644
--- a/clients/tools/ldapsearch.c
+++ b/clients/tools/ldapsearch.c
@@ -1404,6 +1404,8 @@ static int dosearch(
 	struct berval		*retdata = NULL;
 	int			nresponses_psearch = -1;
 	int			cancel_msgid = -1;
+	struct timeval tv, *tvp = NULL;
+	struct timeval tv_timelimit, *tv_timelimitp = NULL;
 
 	if( filtpatt != NULL ) {
 		size_t max_fsize = strlen( filtpatt ) + strlen( value ) + 1, outlen;
@@ -1439,8 +1441,14 @@ static int dosearch(
 		return LDAP_SUCCESS;
 	}
 
+	if ( timelimit > 0 ) {
+		tv_timelimit.tv_sec = timelimit;
+		tv_timelimit.tv_usec = 0;
+		tv_timelimitp = &tv_timelimit;
+	}
+
 	rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
-		sctrls, cctrls, timeout, sizelimit, &msgid );
+		sctrls, cctrls, tv_timelimitp, sizelimit, &msgid );
 
 	if ( filtpatt != NULL ) {
 		free( filter );
@@ -1456,9 +1464,16 @@ static int dosearch(
 
 	res = NULL;
 
+	if ( timelimit > 0 ) {
+		/* disable timeout */
+		tv.tv_sec = -1;
+		tv.tv_usec = 0;
+		tvp = &tv;
+	}
+
 	while ((rc = ldap_result( ld, LDAP_RES_ANY,
 		sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE,
-		NULL, &res )) > 0 )
+		tvp, &res )) > 0 )
 	{
 		rc = tool_check_abandon( ld, msgid );
 		if ( rc ) {
@@ -1554,7 +1569,11 @@ static int dosearch(
 	}
 
 done:
-	if ( rc == -1 ) {
+	if ( tvp == NULL && rc == 0 ) {
+		ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&rc );
+	}
+
+	if ( rc != 0 ) {
 		tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
 		return( rc );
 	}