瀏覽代碼

Resolves: 470611
Summary: Enhanced rsearch to allow user filter and password to be configurable (contributed by [email protected]).

Nathan Kinder 17 年之前
父節點
當前提交
c5314042ff

+ 29 - 5
ldap/servers/slapd/tools/rsearch/rsearch.c

@@ -54,6 +54,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
+#include <string.h>
 #ifdef XP_UNIX
 #include <unistd.h>
 #endif
@@ -104,6 +106,8 @@ void usage()
 	   "-C num    -- take num samples, then stop\n"
 	   "-R num    -- drop connection & reconnect every num searches\n"
 	   "-x        -- Use -B file for binding; ignored if -B is not given\n"
+	   "-W        -- Password to use when binding with -B.  Default is the UID.\n"
+	   "-U        -- Filter to use with binding file.  Ignored if -x is not given.  Default is '(uid=%%s)'.\n"
 	   "\n",
 	   DEFAULT_HOSTNAME, DEFAULT_PORT,
 	   LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE,
@@ -223,6 +227,8 @@ char *searchDatFile = 0;
 char *attrFile = 0;
 char *bindDN = NULL;
 char *bindPW = NULL;
+char *userPW = NULL;
+char *uidFilter = NULL;
 char **attrToReturn = 0;
 char *attrList = 0;
 Operation opType = op_search;
@@ -253,7 +259,7 @@ int main(int argc, char** argv)
     }
 
     while ((ch = getopt(argc, argv, 
-			"B:a:j:i:h:s:f:p:o:t:T:D:w:n:A:S:C:R:bvlyqmMcduNLHx?V"))
+		"U:W:B:a:j:i:h:s:f:p:o:t:T:D:w:n:A:S:C:R:bvlyqmMcduNLHx?V"))
 	   != EOF)
 	switch (ch) {
 	case 'h':
@@ -359,6 +365,12 @@ int main(int argc, char** argv)
 	case 'x':
 	    useBFile = 1;
 	    break;
+	case 'W':
+		userPW = optarg;
+		break;
+	case 'U':
+		uidFilter = optarg;
+		break;
 	case 'a':
 	    if (optarg[0] == '?') {
 		usage_A();
@@ -387,6 +399,11 @@ int main(int argc, char** argv)
     argc -= optind;
     argv += optind;
 
+	if (uidFilter && NULL == strstr(uidFilter, "%s")) {
+		printf("rsearch: invalid UID filter - must contain %%s, eg, (uid=%%s)\n");
+		usage();
+	}
+
     PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 0);
 
     ntable = nt_new(0);
@@ -487,13 +504,20 @@ int main(int argc, char** argv)
 	cumrate += rate;
 	if ((numThreads > 1) || (!verbose)) {
 	    if (!quiet) {
+			char tbuf[18];
+			struct tm* now;
+			time_t lt;
+
+			time(&lt);
+			now = localtime(&lt);
+			strftime(tbuf, sizeof(tbuf), "%Y%m%d %H:%M:%S", now);
 		if (showRunningAvg)
-		    printf("Rate: %7.2f/thr (cumul rate: %7.2f/thr)\n",
-			   rate, cumrate/(double)counter);
+		    printf("%s - Rate: %7.2f/thr (cumul rate: %7.2f/thr)\n",
+			   tbuf, rate, cumrate/(double)counter);
 		else
-		    printf("Rate: %7.2f/thr (%6.2f/sec =%7.4fms/op), "
+		    printf("%s - Rate: %7.2f/thr (%6.2f/sec =%7.4fms/op), "
 			   "total:%6u (%d thr)\n",
-			   rate, val, (double)1000.0/val, total, numThreads);
+			   tbuf, rate, val, (double)1000.0/val, total, numThreads);
 	    }
 	}
 	if (countLimit && (counter >= countLimit)) {

+ 2 - 0
ldap/servers/slapd/tools/rsearch/rsearch.h

@@ -69,6 +69,8 @@ extern char *filter;
 /**/ extern char *nameFile;
 extern char *bindDN;
 extern char *bindPW;
+extern char *userPW;
+extern char *uidFilter;
 extern char **attrToReturn;
 /**/ extern char *attrList;
 extern Operation opType;

+ 22 - 10
ldap/servers/slapd/tools/rsearch/searchthread.c

@@ -90,7 +90,6 @@ SearchThread *st_new(void)
     st->alive = 1;
     st->lock = PR_NewLock();
 	st->retry = 0;
-    srand(time(0));
     return st;
 }
 
@@ -106,6 +105,11 @@ int st_getThread(SearchThread *st, PRThread **tid)
     return st->id;
 }
 
+void st_seed(SearchThread *st) {
+	time_t t = time(0);
+	t -= st->id * 1000;
+	srand((unsigned int)t);
+}
 
 static void st_enableTCPnodelay(SearchThread *st)
 {
@@ -143,12 +147,12 @@ static void st_disconnect(SearchThread *st)
     st->soc = -1;
 }
 
-static int st_bind_core(SearchThread *st, LDAP **ld, char *dn, char *uid)
+static int st_bind_core(SearchThread *st, LDAP **ld, char *dn, char *pw)
 {
 	int ret = 0;
 	int retry = 0;
     while (1) {
-        ret = ldap_simple_bind_s(*ld, dn, uid);
+        ret = ldap_simple_bind_s(*ld, dn, pw);
         if (LDAP_SUCCESS == ret) {
             break;
         } else if (LDAP_CONNECT_ERROR == ret && retry < 10) {
@@ -156,7 +160,7 @@ static int st_bind_core(SearchThread *st, LDAP **ld, char *dn, char *uid)
 		} else {
             fprintf(stderr, "T%d: failed to bind, ldap_simple_bind_s"
                             "(%s, %s) returned 0x%x (errno %d)\n", 
-                            st->id, dn, uid, ret, errno);
+                            st->id, dn, pw, ret, errno);
             *ld = NULL;
             return 0;
         }
@@ -188,30 +192,33 @@ static int st_bind(SearchThread *st)
     if (opType != op_delete && opType != op_modify && opType != op_idxmodify &&
                sdattable && sdt_getlen(sdattable) > 0) {
         int e;
-        char *dn, *uid;
+        char *dn, *uid, *upw;
 
         do {
             e = sdt_getrand(sdattable);
         } while (e < 0);
         dn = sdt_dn_get(sdattable, e);
         uid = sdt_uid_get(sdattable, e);
+		/*  in this test, assuming uid == password unless told otherwise */
+		upw = (userPW) ? userPW : uid;
 
         if (useBFile) {
-            /*  in this test, assuming uid == password */
+
             if (dn) {
-                if (0 == st_bind_core(st, &(st->ld), dn, uid)) {
+                if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                     return 0;
                 }
             } else if (uid) {
                 char filterBuffer[100];
                 char *pFilter;
+				char *filterTemplate = (uidFilter) ? uidFilter : "(uid=%s)";
                 struct timeval timeout;
                 int scope = LDAP_SCOPE_SUBTREE, attrsOnly = 0;
                 LDAPMessage *result;
                 int retry = 0;
     
                 pFilter = filterBuffer;
-                sprintf(filterBuffer, "(uid=%s)", uid);
+				sprintf(filterBuffer, filterTemplate, uid);
                 timeout.tv_sec = 3600;
                 timeout.tv_usec = 0;
                 while (1) {
@@ -230,7 +237,7 @@ static int st_bind(SearchThread *st)
                 }
                 dn = ldap_get_dn(st->ld2, result);
     
-                if (0 == st_bind_core(st, &(st->ld), dn, uid)) {
+                if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                     return 0;
                 }
             } else {
@@ -239,7 +246,7 @@ static int st_bind(SearchThread *st)
                 return 0;
             }
         } else {
-            if (0 == st_bind_core(st, &(st->ld), dn, uid)) {
+            if (0 == st_bind_core(st, &(st->ld), dn, upw)) {
                 return 0;
             }
         }
@@ -504,6 +511,7 @@ void search_start(void *v)
     int notBound = 1, res = LDAP_SUCCESS, searches = 0;
     PRUint32 span;
 
+    st_seed(st);
     st->alive = 1;
     st->ld = 0;
     while (1) {
@@ -544,6 +552,10 @@ void search_start(void *v)
                 return;
             }
         }
+		else {
+			/* Fake status for NOOP */
+			res = LDAP_SUCCESS;
+		}
         if (LDAP_SUCCESS == res) {
             st->retry = 0;
         } else if (LDAP_CONNECT_ERROR == res && st->retry < 10) {