summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Hedenfal <martinh@cvs.openbsd.org>2010-06-11 12:02:04 +0000
committerMartin Hedenfal <martinh@cvs.openbsd.org>2010-06-11 12:02:04 +0000
commitbd69be7a587df5862cb59d681c1e6f082868569d (patch)
tree53b0a7f1e1d4e802a9f8fdac25eb59a32f53abf1
parent6f6839d748c5ede3f8fb892788751875f4a5cdb4 (diff)
Wrap searches in a read-only transaction so it is guaranteed to see a
consistent snapshot of the database. Also fixes a couple of format string errors for long long ints.
-rw-r--r--usr.sbin/ldapd/ldapd.h4
-rw-r--r--usr.sbin/ldapd/search.c35
2 files changed, 28 insertions, 11 deletions
diff --git a/usr.sbin/ldapd/ldapd.h b/usr.sbin/ldapd/ldapd.h
index d6e573abbf5..9aebad24db6 100644
--- a/usr.sbin/ldapd/ldapd.h
+++ b/usr.sbin/ldapd/ldapd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.h,v 1.2 2010/06/03 17:29:54 martinh Exp $ */
+/* $OpenBSD: ldapd.h,v 1.3 2010/06/11 12:02:03 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -162,6 +162,8 @@ struct search {
struct conn *conn;
struct request *req;
struct namespace *ns;
+ struct btree_txn *data_txn;
+ struct btree_txn *indx_txn;
struct cursor *cursor;
unsigned int nscanned, nmatched, ndups;
time_t started_at;
diff --git a/usr.sbin/ldapd/search.c b/usr.sbin/ldapd/search.c
index 6d134811f89..4b2882a2701 100644
--- a/usr.sbin/ldapd/search.c
+++ b/usr.sbin/ldapd/search.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: search.c,v 1.3 2010/06/03 17:32:25 martinh Exp $ */
+/* $OpenBSD: search.c,v 1.4 2010/06/11 12:02:03 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -166,8 +166,10 @@ search_close(struct search *search)
}
btree_cursor_close(search->cursor);
+ btree_txn_abort(search->data_txn);
+ btree_txn_abort(search->indx_txn);
- log_debug("finished search on msgid %d", search->req->msgid);
+ log_debug("finished search on msgid %lld", search->req->msgid);
TAILQ_REMOVE(&search->conn->searches, search, next);
request_free(search->req);
filter_free(search->plan);
@@ -276,7 +278,7 @@ conn_search(struct search *search)
unsigned int op = BT_NEXT;
time_t now;
struct conn *conn;
- struct btree *db;
+ struct btree_txn *txn;
struct btval key, ikey, val;
conn = search->conn;
@@ -285,12 +287,13 @@ conn_search(struct search *search)
bzero(&val, sizeof(val));
if (search->plan->indexed)
- db = search->ns->indx_db;
+ txn = search->indx_txn;
else
- db = search->ns->data_db;
+ txn = search->data_txn;
if (!search->init) {
- if ((search->cursor = btree_cursor_open(db)) == NULL) {
+ search->cursor = btree_txn_cursor_open(NULL, txn);
+ if (search->cursor == NULL) {
log_warn("btree_cursor_open");
search_close(search);
return;
@@ -383,7 +386,7 @@ conn_search(struct search *search)
btval_reset(&key);
continue;
}
- rc = btree_get(search->ns->data_db, &key, &val);
+ rc = btree_txn_get(NULL, search->data_txn, &key, &val);
if (rc == BT_FAIL) {
log_warnx("btree failure");
reason = LDAP_OTHER;
@@ -422,7 +425,7 @@ conn_search(struct search *search)
/* Check if we have passed the size limit. */
if (rc == BT_SUCCESS && search->szlim > 0 &&
search->nmatched >= search->szlim) {
- log_debug("search %i/%i has reached size limit (%u)",
+ log_debug("search %d/%lld has reached size limit (%u)",
search->conn->fd, search->req->msgid,
search->szlim);
reason = LDAP_SIZELIMIT_EXCEEDED;
@@ -434,7 +437,7 @@ conn_search(struct search *search)
now = time(0);
if (rc == 0 && search->tmlim > 0 &&
search->started_at + search->tmlim <= now) {
- log_debug("search %i/%i has reached time limit (%u)",
+ log_debug("search %d/%lld has reached time limit (%u)",
search->conn->fd, search->req->msgid,
search->tmlim);
reason = LDAP_TIMELIMIT_EXCEEDED;
@@ -779,6 +782,16 @@ ldap_search(struct request *req)
goto done;
}
+ search->data_txn = btree_txn_begin(search->ns->data_db, 1);
+ if (search->data_txn != NULL)
+ search->indx_txn = btree_txn_begin(search->ns->indx_db, 1);
+ if (search->indx_txn == NULL) {
+ btree_txn_abort(search->data_txn);
+ search->data_txn = NULL;
+ reason = LDAP_OPERATIONS_ERROR;
+ goto done;
+ }
+
if (search->scope == LDAP_SCOPE_BASE) {
struct btval key, val;
@@ -786,7 +799,7 @@ ldap_search(struct request *req)
bzero(&val, sizeof(val));
key.data = search->basedn;
key.size = strlen(key.data);
- switch (btree_get(search->ns->data_db, &key, &val)) {
+ switch (btree_txn_get(NULL, search->data_txn, &key, &val)) {
case BT_SUCCESS:
check_search_entry(&key, &val, search);
btval_reset(&val);
@@ -794,7 +807,9 @@ ldap_search(struct request *req)
case BT_NOTFOUND:
reason = LDAP_SUCCESS;
goto done;
+ case BT_DEAD:
case BT_FAIL:
+ default:
reason = LDAP_OTHER;
goto done;
}