This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Author: Andrew Tridgell
*/
-#include "includes.h"
+#include "ldb.h"
+#include "tools/cmdline.h"
static struct timeval tp1,tp2;
+static struct ldb_cmdline *options;
-static void start_timer(void)
+static void _start_timer(void)
{
gettimeofday(&tp1,NULL);
}
-static double end_timer(void)
+static double _end_timer(void)
{
gettimeofday(&tp2,NULL);
return((tp2.tv_sec - tp1.tv_sec) +
}
static void add_records(struct ldb_context *ldb,
- const char *basedn,
+ struct ldb_dn *basedn,
int count)
{
struct ldb_message msg;
int i;
+#if 0
+ if (ldb_lock(ldb, "transaction") != 0) {
+ printf("transaction lock failed\n");
+ exit(1);
+ }
+#endif
for (i=0;i<count;i++) {
struct ldb_message_element el[6];
struct ldb_val vals[6][1];
char *name;
- int j;
+ TALLOC_CTX *tmp_ctx = talloc_new(ldb);
- asprintf(&name, "Test%d", i);
+ name = talloc_asprintf(tmp_ctx, "Test%d", i);
- asprintf(&msg.dn, "cn=%s,%s", name, basedn);
+ msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+ ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
msg.num_elements = 6;
msg.elements = el;
el[0].flags = 0;
- el[0].name = strdup("cn");
+ el[0].name = talloc_strdup(tmp_ctx, "cn");
el[0].num_values = 1;
el[0].values = vals[0];
- vals[0][0].data = name;
+ vals[0][0].data = (uint8_t *)name;
vals[0][0].length = strlen(name);
el[1].flags = 0;
- el[1].name = strdup("title");
+ el[1].name = "title";
el[1].num_values = 1;
el[1].values = vals[1];
- asprintf((char **)&vals[1][0].data, "The title of %s", name);
- vals[1][0].length = strlen(vals[1][0].data);
+ vals[1][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "The title of %s", name);
+ vals[1][0].length = strlen((char *)vals[1][0].data);
el[2].flags = 0;
- el[2].name = strdup("uid");
+ el[2].name = talloc_strdup(tmp_ctx, "uid");
el[2].num_values = 1;
el[2].values = vals[2];
- vals[2][0].data = ldb_casefold(ldb, name);
- vals[2][0].length = strlen(vals[2][0].data);
+ vals[2][0].data = (uint8_t *)ldb_casefold(ldb, tmp_ctx, name, strlen(name));
+ vals[2][0].length = strlen((char *)vals[2][0].data);
el[3].flags = 0;
- el[3].name = strdup("mail");
+ el[3].name = talloc_strdup(tmp_ctx, "mail");
el[3].num_values = 1;
el[3].values = vals[3];
- asprintf((char **)&vals[3][0].data, "%s@example.com", name);
- vals[3][0].length = strlen(vals[3][0].data);
+ vals[3][0].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@example.com", name);
+ vals[3][0].length = strlen((char *)vals[3][0].data);
el[4].flags = 0;
- el[4].name = strdup("objectClass");
+ el[4].name = talloc_strdup(tmp_ctx, "objectClass");
el[4].num_values = 1;
el[4].values = vals[4];
- vals[4][0].data = strdup("OpenLDAPperson");
- vals[4][0].length = strlen(vals[4][0].data);
+ vals[4][0].data = (uint8_t *)talloc_strdup(tmp_ctx, "OpenLDAPperson");
+ vals[4][0].length = strlen((char *)vals[4][0].data);
el[5].flags = 0;
- el[5].name = strdup("sn");
+ el[5].name = talloc_strdup(tmp_ctx, "sn");
el[5].num_values = 1;
el[5].values = vals[5];
- vals[5][0].data = name;
- vals[5][0].length = strlen(vals[5][0].data);
+ vals[5][0].data = (uint8_t *)name;
+ vals[5][0].length = strlen((char *)vals[5][0].data);
ldb_delete(ldb, msg.dn);
printf("adding uid %s\r", name);
fflush(stdout);
- for (j=0;j<msg.num_elements;j++) {
- free(el[j].name);
- }
- free(name);
- free(msg.dn);
- free(vals[1][0].data);
- ldb_free(ldb, vals[2][0].data);
- free(vals[3][0].data);
- free(vals[4][0].data);
+ talloc_free(tmp_ctx);
}
-
+#if 0
+ if (ldb_unlock(ldb, "transaction") != 0) {
+ printf("transaction unlock failed\n");
+ exit(1);
+ }
+#endif
printf("\n");
}
static void modify_records(struct ldb_context *ldb,
- const char *basedn,
+ struct ldb_dn *basedn,
int count)
{
struct ldb_message msg;
struct ldb_message_element el[3];
struct ldb_val vals[3];
char *name;
- int j;
+ TALLOC_CTX *tmp_ctx = talloc_new(ldb);
- asprintf(&name, "Test%d", i);
- asprintf(&msg.dn, "cn=%s,%s", name, basedn);
+ name = talloc_asprintf(tmp_ctx, "Test%d", i);
+ msg.dn = ldb_dn_copy(tmp_ctx, basedn);
+ ldb_dn_add_child_fmt(msg.dn, "cn=%s", name);
msg.num_elements = 3;
msg.elements = el;
el[0].flags = LDB_FLAG_MOD_DELETE;
- el[0].name = strdup("mail");
+ el[0].name = talloc_strdup(tmp_ctx, "mail");
el[0].num_values = 0;
el[1].flags = LDB_FLAG_MOD_ADD;
- el[1].name = strdup("mail");
+ el[1].name = talloc_strdup(tmp_ctx, "mail");
el[1].num_values = 1;
el[1].values = &vals[1];
- asprintf((char **)&vals[1].data, "%s@other.example.com", name);
- vals[1].length = strlen(vals[1].data);
+ vals[1].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other.example.com", name);
+ vals[1].length = strlen((char *)vals[1].data);
el[2].flags = LDB_FLAG_MOD_REPLACE;
- el[2].name = strdup("mail");
+ el[2].name = talloc_strdup(tmp_ctx, "mail");
el[2].num_values = 1;
el[2].values = &vals[2];
- asprintf((char **)&vals[2].data, "%s@other2.example.com", name);
- vals[2].length = strlen(vals[2].data);
+ vals[2].data = (uint8_t *)talloc_asprintf(tmp_ctx, "%s@other2.example.com", name);
+ vals[2].length = strlen((char *)vals[2].data);
if (ldb_modify(ldb, &msg) != 0) {
printf("Modify of %s failed - %s\n", name, ldb_errstring(ldb));
printf("Modifying uid %s\r", name);
fflush(stdout);
- for (j=0;j<msg.num_elements;j++) {
- free(el[j].name);
- }
- free(name);
- free(msg.dn);
- free(vals[1].data);
- free(vals[2].data);
+ talloc_free(tmp_ctx);
}
printf("\n");
static void delete_records(struct ldb_context *ldb,
- const char *basedn,
+ struct ldb_dn *basedn,
int count)
{
int i;
for (i=0;i<count;i++) {
- char *dn;
- asprintf(&dn, "cn=Test%d,%s", i, basedn);
+ struct ldb_dn *dn;
+ char *name = talloc_asprintf(ldb, "Test%d", i);
+ dn = ldb_dn_copy(name, basedn);
+ ldb_dn_add_child_fmt(dn, "cn=%s", name);
printf("Deleting uid Test%d\r", i);
fflush(stdout);
if (ldb_delete(ldb, dn) != 0) {
- printf("Delete of %s failed - %s\n", dn, ldb_errstring(ldb));
+ printf("Delete of %s failed - %s\n", ldb_dn_get_linearized(dn), ldb_errstring(ldb));
exit(1);
}
- free(dn);
+ talloc_free(name);
}
printf("\n");
}
-static void search_uid(struct ldb_context *ldb, int nrecords, int nsearches)
+static void search_uid(struct ldb_context *ldb, struct ldb_dn *basedn, int nrecords, int nsearches)
{
int i;
for (i=0;i<nsearches;i++) {
int uid = (i * 700 + 17) % (nrecords * 2);
char *expr;
- struct ldb_message **res;
+ struct ldb_result *res = NULL;
int ret;
- asprintf(&expr, "(uid=TEST%d)", uid);
- ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res);
+ expr = talloc_asprintf(ldb, "(uid=TEST%d)", uid);
+ ret = ldb_search(ldb, ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "%s", expr);
- if (uid < nrecords && ret != 1) {
+ if (ret != LDB_SUCCESS || (uid < nrecords && res->count != 1)) {
printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb));
exit(1);
}
- if (uid >= nrecords && ret > 0) {
+ if (uid >= nrecords && res->count > 0) {
printf("Found %s !? - %d\n", expr, ret);
exit(1);
}
- if (ret > 0) {
- ldb_search_free(ldb, res);
- }
-
- printf("testing uid %d/%d - %d \r", i, uid, ret);
+ printf("testing uid %d/%d - %d \r", i, uid, res->count);
fflush(stdout);
- free(expr);
+ talloc_free(res);
+ talloc_free(expr);
}
printf("\n");
static void start_test(struct ldb_context *ldb, int nrecords, int nsearches)
{
- const char *base = "ou=Ldb Test,ou=People,o=University of Michigan,c=US";
+ struct ldb_dn *basedn;
+
+ basedn = ldb_dn_new(ldb, ldb, options->basedn);
+ if ( ! ldb_dn_validate(basedn)) {
+ printf("Invalid base DN\n");
+ exit(1);
+ }
printf("Adding %d records\n", nrecords);
- add_records(ldb, base, nrecords);
+ add_records(ldb, basedn, nrecords);
printf("Starting search on uid\n");
- start_timer();
- search_uid(ldb, nrecords, nsearches);
- printf("uid search took %.2f seconds\n", end_timer());
+ _start_timer();
+ search_uid(ldb, basedn, nrecords, nsearches);
+ printf("uid search took %.2f seconds\n", _end_timer());
printf("Modifying records\n");
- modify_records(ldb, base, nrecords);
+ modify_records(ldb, basedn, nrecords);
printf("Deleting records\n");
- delete_records(ldb, base, nrecords);
+ delete_records(ldb, basedn, nrecords);
+}
+
+
+/*
+ 2) Store an @indexlist record
+
+ 3) Store a record that contains fields that should be index according
+to @index
+
+ 4) disconnection from database
+
+ 5) connect to same database
+
+ 6) search for record added in step 3 using a search key that should
+be indexed
+*/
+static void start_test_index(struct ldb_context **ldb)
+{
+ struct ldb_message *msg;
+ struct ldb_result *res = NULL;
+ struct ldb_dn *indexlist;
+ struct ldb_dn *basedn;
+ int ret;
+ int flags = 0;
+ const char *specials;
+
+ specials = getenv("LDB_SPECIALS");
+ if (specials && atoi(specials) == 0) {
+ printf("LDB_SPECIALS disabled - skipping index test\n");
+ return;
+ }
+
+ if (options->nosync) {
+ flags |= LDB_FLG_NOSYNC;
+ }
+
+ printf("Starting index test\n");
+
+ indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
+
+ ldb_delete(*ldb, indexlist);
+
+ msg = ldb_msg_new(NULL);
+
+ msg->dn = indexlist;
+ ldb_msg_add_string(msg, "@IDXATTR", strdup("uid"));
+
+ if (ldb_add(*ldb, msg) != 0) {
+ printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
+ exit(1);
+ }
+
+ basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
+
+ memset(msg, 0, sizeof(*msg));
+ msg->dn = ldb_dn_copy(msg, basedn);
+ ldb_dn_add_child_fmt(msg->dn, "cn=test");
+ ldb_msg_add_string(msg, "cn", strdup("test"));
+ ldb_msg_add_string(msg, "sn", strdup("test"));
+ ldb_msg_add_string(msg, "uid", strdup("test"));
+ ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson"));
+
+ if (ldb_add(*ldb, msg) != 0) {
+ printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb));
+ exit(1);
+ }
+
+ if (talloc_free(*ldb) != 0) {
+ printf("failed to free/close ldb database");
+ exit(1);
+ }
+
+ (*ldb) = ldb_init(options, NULL);
+
+ ret = ldb_connect(*ldb, options->url, flags, NULL);
+ if (ret != 0) {
+ printf("failed to connect to %s\n", options->url);
+ exit(1);
+ }
+
+ basedn = ldb_dn_new(*ldb, *ldb, options->basedn);
+
+ ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test");
+ if (ret != LDB_SUCCESS) {
+ printf("Search with (uid=test) filter failed!\n");
+ exit(1);
+ }
+ if(res->count != 1) {
+ printf("Should have found 1 record - found %d\n", res->count);
+ exit(1);
+ }
+
+ indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST");
+
+ if (ldb_delete(*ldb, msg->dn) != 0 ||
+ ldb_delete(*ldb, indexlist) != 0) {
+ printf("cleanup failed - %s\n", ldb_errstring(*ldb));
+ exit(1);
+ }
+
+ printf("Finished index test\n");
}
printf("Usage: ldbtest <options>\n");
printf("Options:\n");
printf(" -H ldb_url choose the database (or $LDB_URL)\n");
- printf(" -r nrecords database size to use\n");
- printf(" -s nsearches number of searches to do\n");
+ printf(" --num-records nrecords database size to use\n");
+ printf(" --num-searches nsearches number of searches to do\n");
printf("\n");
printf("tests ldb API\n\n");
exit(1);
}
- int main(int argc, char * const argv[])
+int main(int argc, const char **argv)
{
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
struct ldb_context *ldb;
- const char *ldb_url;
- int opt;
- int nrecords = 5000;
- int nsearches = 2000;
-
- ldb_url = getenv("LDB_URL");
-
- while ((opt = getopt(argc, argv, "hH:r:s:")) != EOF) {
- switch (opt) {
- case 'H':
- ldb_url = optarg;
- break;
-
- case 'r':
- nrecords = atoi(optarg);
- break;
-
- case 's':
- nsearches = atoi(optarg);
- break;
-
- case 'h':
- default:
- usage();
- break;
- }
- }
- if (!ldb_url) {
- fprintf(stderr, "You must specify a ldb URL\n\n");
- usage();
- }
+ ldb = ldb_init(mem_ctx, NULL);
- argc -= optind;
- argv += optind;
+ options = ldb_cmdline_process(ldb, argc, argv, usage);
- ldb = ldb_connect(ldb_url, 0, NULL);
+ talloc_steal(mem_ctx, options);
- if (!ldb) {
- perror("ldb_connect");
- exit(1);
+ if (options->basedn == NULL) {
+ options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST";
}
- ldb_set_debug_stderr(ldb);
-
srandom(1);
- start_test(ldb, nrecords, nsearches);
+ printf("Testing with num-records=%d and num-searches=%d\n",
+ options->num_records, options->num_searches);
+
+ start_test(ldb, options->num_records, options->num_searches);
+
+ start_test_index(&ldb);
- ldb_close(ldb);
+ talloc_free(mem_ctx);
return 0;
}