summaryrefslogtreecommitdiff
path: root/usr.sbin/ldapd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/ldapd')
-rw-r--r--usr.sbin/ldapd/auth.c7
-rw-r--r--usr.sbin/ldapd/btree.c95
-rw-r--r--usr.sbin/ldapd/btree.h5
-rw-r--r--usr.sbin/ldapd/index.c7
-rw-r--r--usr.sbin/ldapd/modify.c108
-rw-r--r--usr.sbin/ldapd/namespace.c46
-rw-r--r--usr.sbin/ldapd/search.c57
7 files changed, 169 insertions, 156 deletions
diff --git a/usr.sbin/ldapd/auth.c b/usr.sbin/ldapd/auth.c
index 4f26aad63e3..ec2c6018ad2 100644
--- a/usr.sbin/ldapd/auth.c
+++ b/usr.sbin/ldapd/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.2 2010/06/15 15:47:56 martinh Exp $ */
+/* $OpenBSD: auth.c,v 1.3 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -287,9 +287,8 @@ ldap_auth_simple(struct request *req, char *binddn, struct ber_element *auth)
LDAP_SCOPE_BASE))
return LDAP_INSUFFICIENT_ACCESS;
- if (ns->data_db == NULL ||
- ((elm = namespace_get(ns, binddn)) == NULL &&
- errno == EAGAIN)) {
+ elm = namespace_get(ns, binddn);
+ if (elm == NULL && errno == ESTALE) {
if (namespace_queue_request(ns, req) != 0)
return LDAP_BUSY;
return -1; /* Database is being reopened. */
diff --git a/usr.sbin/ldapd/btree.c b/usr.sbin/ldapd/btree.c
index 05e208f0772..6aee566b34f 100644
--- a/usr.sbin/ldapd/btree.c
+++ b/usr.sbin/ldapd/btree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btree.c,v 1.12 2010/06/17 18:36:36 martinh Exp $ */
+/* $OpenBSD: btree.c,v 1.13 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -586,7 +586,8 @@ btree_read_page(struct btree *bt, pgno_t pgno, struct page *page)
bt->stat.reads++;
if ((rc = pread(bt->fd, page, PAGESIZE, (off_t)pgno*PAGESIZE)) == 0) {
DPRINTF("page %u doesn't exist", pgno);
- return BT_NOTFOUND;
+ errno = ENOENT;
+ return BT_FAIL;
}
else if (rc != PAGESIZE) {
DPRINTF("read: %s", strerror(errno));
@@ -613,11 +614,11 @@ btree_sync(struct btree *bt)
struct btree_txn *
btree_txn_begin(struct btree *bt, int rdonly)
{
- int rc;
struct btree_txn *txn;
if (!rdonly && bt->txn != NULL) {
DPRINTF("write transaction already begun");
+ errno = EBUSY;
return NULL;
}
@@ -638,6 +639,8 @@ btree_txn_begin(struct btree *bt, int rdonly)
DPRINTF("taking write lock on txn %p", txn);
if (flock(bt->fd, LOCK_EX | LOCK_NB) != 0) {
+ DPRINTF("flock: %s", strerror(errno));
+ errno = EBUSY;
free(txn->dirty_queue);
free(txn);
return NULL;
@@ -648,8 +651,7 @@ btree_txn_begin(struct btree *bt, int rdonly)
txn->bt = bt;
btree_ref(bt);
- if ((rc = btree_read_meta(bt, &txn->next_pgno)) == BT_FAIL ||
- rc == BT_DEAD) {
+ if (btree_read_meta(bt, &txn->next_pgno) != BT_SUCCESS) {
btree_txn_abort(txn);
return NULL;
}
@@ -713,18 +715,21 @@ btree_txn_commit(struct btree_txn *txn)
if (F_ISSET(txn->flags, BT_TXN_RDONLY)) {
DPRINTF("attempt to commit read-only transaction");
btree_txn_abort(txn);
+ errno = EPERM;
return BT_FAIL;
}
if (txn != bt->txn) {
DPRINTF("attempt to commit unknown transaction");
btree_txn_abort(txn);
+ errno = EINVAL;
return BT_FAIL;
}
if (F_ISSET(txn->flags, BT_TXN_ERROR)) {
DPRINTF("error flag is set, can't commit");
btree_txn_abort(txn);
+ errno = EINVAL;
return BT_FAIL;
}
@@ -903,7 +908,7 @@ btree_read_meta(struct btree *bt, pgno_t *p_next)
if (size == 0) {
if (p_next != NULL)
*p_next = 0;
- return BT_NOTFOUND; /* new file */
+ return BT_SUCCESS; /* new file */
}
next_pgno = size / PAGESIZE;
@@ -928,8 +933,8 @@ btree_read_meta(struct btree *bt, pgno_t *p_next)
DPRINTF("size unchanged, keeping current meta page");
if (F_ISSET(bt->meta->flags, BT_TOMBSTONE)) {
DPRINTF("file is dead");
- errno = EAGAIN;
- return BT_DEAD;
+ errno = ESTALE;
+ return BT_FAIL;
} else
return BT_SUCCESS;
}
@@ -937,15 +942,15 @@ btree_read_meta(struct btree *bt, pgno_t *p_next)
while (meta_pgno > 0) {
rc = btree_read_page(bt, meta_pgno, bt->metapage);
- if (rc == BT_NOTFOUND)
+ if (rc == BT_FAIL && errno == ENOENT)
break; /* no meta page found */
if (rc == BT_SUCCESS && btree_is_meta_page(bt->metapage)) {
bt->meta = METADATA(bt->metapage);
DPRINTF("flags = 0x%x", bt->meta->flags);
if (F_ISSET(bt->meta->flags, BT_TOMBSTONE)) {
DPRINTF("file is dead");
- errno = EAGAIN;
- return BT_DEAD;
+ errno = ESTALE;
+ return BT_FAIL;
} else
return BT_SUCCESS;
}
@@ -962,7 +967,7 @@ fail:
struct btree *
btree_open_fd(int fd, unsigned int flags)
{
- int fl, rc;
+ int fl;
struct btree *bt;
fl = fcntl(fd, F_GETFL, 0);
@@ -988,7 +993,7 @@ btree_open_fd(int fd, unsigned int flags)
if ((bt->metapage = calloc(1, PAGESIZE)) == NULL)
goto fail;
- if ((rc = btree_read_meta(bt, NULL)) == BT_FAIL || rc == BT_DEAD)
+ if (btree_read_meta(bt, NULL) != 0)
goto fail;
if (bt->meta == NULL) {
@@ -1346,12 +1351,15 @@ btree_search_page(struct btree *bt, struct btree_txn *txn, struct btval *key,
root = bt->meta->root;
} else if (F_ISSET(txn->flags, BT_TXN_ERROR)) {
DPRINTF("transaction has failed, must abort");
+ errno = EINVAL;
return BT_FAIL;
} else
root = txn->root;
- if (root == P_INVALID) /* Tree is empty. */
- return BT_NOTFOUND;
+ if (root == P_INVALID) { /* Tree is empty. */
+ errno = ENOENT;
+ return BT_FAIL;
+ }
if ((rc = btree_get_mpage(bt, root, &mp)) != BT_SUCCESS)
return rc;
@@ -1409,7 +1417,7 @@ btree_read_data(struct btree *bt, struct mpage *mp, struct node *leaf,
data->mp = NULL;
pgno = *(pgno_t *)NODEDATA(leaf); /* XXX: alignment? */
for (sz = 0; sz < data->size; ) {
- if (btree_read_page(bt, pgno, &p) != 0 ||
+ if (btree_read_page(bt, pgno, &p) != BT_SUCCESS ||
!F_ISSET(p.flags, P_OVERFLOW)) {
DPRINTF("read overflow page failed (%02x)", p.flags);
free(data->data);
@@ -1462,8 +1470,10 @@ btree_txn_get(struct btree *bt, struct btree_txn *txn,
leaf = btree_search_node(bt, mp, key, &exact, NULL);
if (leaf && exact)
rc = btree_read_data(bt, mp, leaf, data);
- else
- rc = BT_NOTFOUND;
+ else {
+ errno = ENOENT;
+ rc = BT_FAIL;
+ }
mpage_prune(bt);
return rc;
@@ -1478,8 +1488,10 @@ btree_sibling(struct cursor *cursor, int move_right)
struct mpage *mp;
top = CURSOR_TOP(cursor);
- if ((parent = SLIST_NEXT(top, entry)) == NULL)
- return BT_NOTFOUND; /* root has no siblings */
+ if ((parent = SLIST_NEXT(top, entry)) == NULL) {
+ errno = ENOENT;
+ return BT_FAIL; /* root has no siblings */
+ }
DPRINTF("parent page is page %u, index %u",
parent->mpage->pgno, parent->ki);
@@ -1549,8 +1561,10 @@ btree_cursor_next(struct cursor *cursor, struct btval *key, struct btval *data)
struct mpage *mp;
struct node *leaf;
- if (cursor->eof)
- return BT_NOTFOUND;
+ if (cursor->eof) {
+ errno = ENOENT;
+ return BT_FAIL;
+ }
assert(cursor->initialized);
@@ -1563,7 +1577,7 @@ btree_cursor_next(struct cursor *cursor, struct btval *key, struct btval *data)
DPRINTF("=====> move to next sibling page");
if (btree_sibling(cursor, 1) != BT_SUCCESS) {
cursor->eof = 1;
- return BT_NOTFOUND;
+ return BT_FAIL;
}
top = CURSOR_TOP(cursor);
mp = top->mpage;
@@ -1608,7 +1622,7 @@ btree_cursor_set(struct cursor *cursor, struct btval *key, struct btval *data)
if (leaf == NULL) {
DPRINTF("===> inexact leaf not found, goto sibling");
if (btree_sibling(cursor, 1) != BT_SUCCESS)
- return BT_NOTFOUND; /* no entries matched */
+ return BT_FAIL; /* no entries matched */
top = CURSOR_TOP(cursor);
top->ki = 0;
mp = top->mpage;
@@ -2462,7 +2476,8 @@ btree_txn_del(struct btree *bt, struct btree_txn *txn,
leaf = btree_search_node(bt, mp, key, &exact, &ki);
if (leaf == NULL || !exact) {
- rc = BT_NOTFOUND;
+ errno = ENOENT;
+ rc = BT_FAIL;
goto done;
}
@@ -2782,7 +2797,8 @@ btree_txn_put(struct btree *bt, struct btree_txn *txn,
if (F_ISSET(flags, BT_NOOVERWRITE)) {
DPRINTF("duplicate key %.*s",
(int)key->size, (char *)key->data);
- rc = BT_EXISTS;
+ errno = EEXIST;
+ rc = BT_FAIL;
goto done;
}
btree_del_node(bt, mp, ki);
@@ -2791,7 +2807,7 @@ btree_txn_put(struct btree *bt, struct btree_txn *txn,
ki = NUMKEYS(mp);
DPRINTF("appending key at index %i", ki);
}
- } else if (rc == BT_NOTFOUND) {
+ } else if (errno == ENOENT) {
/* new file, just write a root leaf page */
DPRINTF("allocating new root leaf page");
if ((mp = btree_new_page(bt, P_LEAF)) == NULL) {
@@ -2891,33 +2907,40 @@ btree_compact_tree(struct btree *bt, pgno_t pgno, int fd)
int
btree_compact(struct btree *bt)
{
- int rc, fd, old_fd;
+ off_t old_size;
char *compact_path = NULL;
struct btree_txn *txn;
+ int fd, old_fd;
pgno_t root, next_pgno;
assert(bt != NULL);
- if (bt->path == NULL)
+ DPRINTF("compacting btree %p with path %s", bt, bt->path);
+
+ if (bt->path == NULL) {
+ errno = EINVAL;
+ return BT_FAIL;
+ }
+
+ if ((txn = btree_txn_begin(bt, 0)) == NULL)
return BT_FAIL;
- if ((rc = btree_read_meta(bt, NULL)) == BT_NOTFOUND)
+ if (txn->next_pgno == 0) {
+ /* File is empty. */
+ btree_txn_abort(txn);
return BT_SUCCESS;
- else if (rc != BT_SUCCESS)
- return rc;
+ }
asprintf(&compact_path, "%s.compact.XXXXXX", bt->path);
fd = mkstemp(compact_path);
if (fd == -1) {
free(compact_path);
+ btree_txn_abort(txn);
return BT_FAIL;
}
old_fd = bt->fd;
- if ((txn = btree_txn_begin(bt, 0)) == NULL)
- goto failed;
-
next_pgno = bt->txn->next_pgno;
bt->txn->next_pgno = 0;
root = btree_compact_tree(bt, bt->meta->root, fd);
@@ -2937,12 +2960,14 @@ btree_compact(struct btree *bt)
/* Write a "tombstone" meta page so other processes can pick up
* the change and re-open the file.
*/
+ old_size = bt->size;
bt->fd = old_fd;
bt->txn->next_pgno = next_pgno;
if (btree_write_meta(bt, P_INVALID, BT_TOMBSTONE) != BT_SUCCESS)
goto failed;
bt->fd = fd;
+ bt->size = old_size;
btree_txn_abort(txn);
free(compact_path);
mpage_flush(bt);
diff --git a/usr.sbin/ldapd/btree.h b/usr.sbin/ldapd/btree.h
index c65f57ab15e..161a8a8ca36 100644
--- a/usr.sbin/ldapd/btree.h
+++ b/usr.sbin/ldapd/btree.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: btree.h,v 1.4 2010/06/13 06:55:33 martinh Exp $ */
+/* $OpenBSD: btree.h,v 1.5 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -51,9 +51,6 @@ enum cursor_op { /* cursor operations */
/* return codes */
#define BT_FAIL -1
#define BT_SUCCESS 0
-#define BT_NOTFOUND 1
-#define BT_EXISTS 2
-#define BT_DEAD 3 /* file has been replaced */
/* btree flags */
#define BT_NOSYNC 0x02 /* don't fsync after commit */
diff --git a/usr.sbin/ldapd/index.c b/usr.sbin/ldapd/index.c
index 13e01dd407e..f490e11ceef 100644
--- a/usr.sbin/ldapd/index.c
+++ b/usr.sbin/ldapd/index.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: index.c,v 1.5 2010/06/23 12:40:19 martinh Exp $ */
+/* $OpenBSD: index.c,v 1.6 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009 Martin Hedenfalk <martin@bzero.se>
@@ -74,6 +74,7 @@
#include <sys/queue.h>
#include <assert.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -188,7 +189,7 @@ unindex_attribute(struct namespace *ns, char *attr, struct btval *dn,
normalize_dn(key.data);
rc = btree_txn_del(NULL, ns->indx_txn, &key, NULL);
free(t);
- if (rc == BT_FAIL)
+ if (rc == BT_FAIL && errno != ENOENT)
return -1;
}
@@ -240,7 +241,7 @@ unindex_rdn(struct namespace *ns, struct btval *dn)
normalize_dn(key.data);
rc = btree_txn_del(NULL, ns->indx_txn, &key, NULL);
free(t);
- if (rc == BT_FAIL)
+ if (rc == BT_FAIL && errno != ENOENT)
return -1;
return 0;
}
diff --git a/usr.sbin/ldapd/modify.c b/usr.sbin/ldapd/modify.c
index 883cd58c39d..b2a25d8ff1a 100644
--- a/usr.sbin/ldapd/modify.c
+++ b/usr.sbin/ldapd/modify.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: modify.c,v 1.2 2010/06/15 15:47:56 martinh Exp $ */
+/* $OpenBSD: modify.c,v 1.3 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -20,6 +20,7 @@
#include <sys/queue.h>
#include <assert.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -29,7 +30,6 @@
int
ldap_delete(struct request *req)
{
- int rc;
char *dn;
struct namespace *ns;
@@ -47,29 +47,25 @@ ldap_delete(struct request *req)
if (!authorized(req->conn, ns, ACI_WRITE, dn, LDAP_SCOPE_BASE))
return ldap_respond(req, LDAP_INSUFFICIENT_ACCESS);
- if ((rc = namespace_begin(ns)) == BT_DEAD) {
- if (namespace_queue_request(ns, req) != 0)
- return ldap_respond(req, LDAP_BUSY);
- return LDAP_BUSY;
- } else if (rc != BT_SUCCESS)
+ if (namespace_begin(ns) != 0) {
+ if (errno == EBUSY) {
+ if (namespace_queue_request(ns, req) != 0)
+ return ldap_respond(req, LDAP_BUSY);
+ return LDAP_BUSY;
+ }
return ldap_respond(req, LDAP_OTHER);
-
- switch (namespace_del(ns, dn)) {
- case BT_NOTFOUND:
- rc = LDAP_NO_SUCH_OBJECT;
- break;
- case BT_SUCCESS:
- rc = LDAP_SUCCESS;
- break;
- default:
- rc = LDAP_OTHER;
- break;
}
- namespace_commit(ns);
- if (rc >= 0)
- ldap_respond(req, rc);
- return rc;
+ if (namespace_del(ns, dn) == 0) {
+ namespace_commit(ns);
+ return ldap_respond(req, LDAP_SUCCESS);
+ } else {
+ namespace_abort(ns);
+ if (errno == ENOENT)
+ return ldap_respond(req, LDAP_NO_SUCH_OBJECT);
+ else
+ return ldap_respond(req, LDAP_OTHER);
+ }
}
int
@@ -99,12 +95,14 @@ ldap_add(struct request *req)
if (!authorized(req->conn, ns, ACI_WRITE, dn, LDAP_SCOPE_BASE) != 0)
return ldap_respond(req, LDAP_INSUFFICIENT_ACCESS);
- if ((rc = namespace_begin(ns)) == BT_DEAD) {
- if (namespace_queue_request(ns, req) != 0)
- return ldap_respond(req, LDAP_BUSY);
- return LDAP_BUSY;
- } else if (rc != BT_SUCCESS)
+ if (namespace_begin(ns) == -1) {
+ if (errno == EBUSY) {
+ if (namespace_queue_request(ns, req) != 0)
+ return ldap_respond(req, LDAP_BUSY);
+ return LDAP_BUSY;
+ }
return ldap_respond(req, LDAP_OTHER);
+ }
/* add operational attributes
*/
@@ -122,26 +120,17 @@ ldap_add(struct request *req)
ber_add_string(set, uuid_str);
ldap_add_attribute(attrs, "entryUUID", set);
- if ((rc = validate_entry(dn, attrs, ns->relax)) != LDAP_SUCCESS)
- goto done;
-
- switch (namespace_add(ns, dn, attrs)) {
- case BT_SUCCESS:
- rc = LDAP_SUCCESS;
- break;
- case BT_EXISTS:
- rc = LDAP_ALREADY_EXISTS;
- break;
- default:
+ if ((rc = validate_entry(dn, attrs, ns->relax)) != LDAP_SUCCESS ||
+ namespace_add(ns, dn, attrs) != 0) {
+ namespace_abort(ns);
+ if (rc == LDAP_SUCCESS && errno == EEXIST)
+ rc = LDAP_ALREADY_EXISTS;
+ else
+ rc = LDAP_OTHER;
+ } else if (namespace_commit(ns) != 0)
rc = LDAP_OTHER;
- break;
- }
-done:
- namespace_commit(ns);
- if (rc >= 0)
- ldap_respond(req, rc);
- return rc;
+ return ldap_respond(req, rc);
}
int
@@ -172,12 +161,14 @@ ldap_modify(struct request *req)
if (!authorized(req->conn, ns, ACI_WRITE, dn, LDAP_SCOPE_BASE) != 0)
return ldap_respond(req, LDAP_INSUFFICIENT_ACCESS);
- if ((rc = namespace_begin(ns)) == BT_DEAD) {
- if (namespace_queue_request(ns, req) != 0)
- return ldap_respond(req, LDAP_BUSY);
- return LDAP_BUSY;
- } else if (rc != BT_SUCCESS)
+ if (namespace_begin(ns) == -1) {
+ if (errno == EBUSY) {
+ if (namespace_queue_request(ns, req) != 0)
+ return ldap_respond(req, LDAP_BUSY);
+ return LDAP_BUSY;
+ }
return ldap_respond(req, LDAP_OTHER);
+ }
if ((entry = namespace_get(ns, dn)) == NULL) {
rc = LDAP_NO_SUCH_OBJECT;
@@ -253,20 +244,17 @@ ldap_modify(struct request *req)
else
ldap_add_attribute(entry, "modifyTimestamp", set);
- switch (namespace_update(ns, dn, entry)) {
- case BT_SUCCESS:
+ if (namespace_update(ns, dn, entry) == 0)
rc = LDAP_SUCCESS;
- break;
- case BT_EXISTS:
- rc = LDAP_ALREADY_EXISTS;
- break;
- default:
+ else
rc = LDAP_OTHER;
- break;
- }
done:
- namespace_commit(ns);
+ if (rc == LDAP_SUCCESS)
+ namespace_commit(ns);
+ else
+ namespace_abort(ns);
+
if (rc >= 0)
ldap_respond(req, rc);
return rc;
diff --git a/usr.sbin/ldapd/namespace.c b/usr.sbin/ldapd/namespace.c
index 4b8c56a61e8..72eb3743bd9 100644
--- a/usr.sbin/ldapd/namespace.c
+++ b/usr.sbin/ldapd/namespace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: namespace.c,v 1.7 2010/06/15 19:30:26 martinh Exp $ */
+/* $OpenBSD: namespace.c,v 1.8 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -42,27 +42,27 @@ int
namespace_begin_txn(struct namespace *ns, struct btree_txn **data_txn,
struct btree_txn **indx_txn, int rdonly)
{
- int rc = BT_FAIL;
-
- if (ns->data_db == NULL || ns->indx_db == NULL)
- return BT_DEAD;
+ if (ns->data_db == NULL || ns->indx_db == NULL) {
+ errno = EBUSY; /* namespace is being reopened */
+ return -1;
+ }
if ((*data_txn = btree_txn_begin(ns->data_db, rdonly)) == NULL ||
(*indx_txn = btree_txn_begin(ns->indx_db, rdonly)) == NULL) {
- if (errno == EAGAIN) {
+ if (errno == ESTALE) {
if (*data_txn == NULL)
namespace_reopen_data(ns);
else
namespace_reopen_indx(ns);
- rc = BT_DEAD;
+ errno = EBUSY;
}
log_warn("failed to open transaction");
btree_txn_abort(*data_txn);
*data_txn = NULL;
- return rc;
+ return -1;
}
- return BT_SUCCESS;
+ return 0;
}
int
@@ -255,22 +255,26 @@ namespace_find(struct namespace *ns, char *dn)
struct btval key;
static struct btval val;
+ if (ns->data_db == NULL) {
+ errno = EBUSY; /* namespace is being reopened */
+ return NULL;
+ }
+
bzero(&key, sizeof(key));
bzero(&val, sizeof(val));
key.data = dn;
key.size = strlen(dn);
- switch (btree_txn_get(ns->data_db, ns->data_txn, &key, &val)) {
- case BT_FAIL:
- log_warn("%s", dn);
- return NULL;
- case BT_DEAD:
- log_warn("%s", dn);
- namespace_reopen_data(ns);
- return NULL;
- case BT_NOTFOUND:
- log_debug("%s: dn not found", dn);
+ if (btree_txn_get(ns->data_db, ns->data_txn, &key, &val) != 0) {
+ if (errno == ENOENT)
+ log_debug("%s: dn not found", dn);
+ else
+ log_warn("%s", dn);
+
+ if (errno == ESTALE)
+ namespace_reopen_data(ns);
+
return NULL;
}
@@ -336,7 +340,7 @@ namespace_put(struct namespace *ns, char *dn, struct ber_element *root,
rc = btree_txn_put(NULL, ns->data_txn, &key, &val,
update ? 0 : BT_NOOVERWRITE);
if (rc != BT_SUCCESS) {
- if (rc == BT_EXISTS)
+ if (errno == EEXIST)
log_debug("%s: already exists", dn);
else
log_warn("%s", dn);
@@ -345,7 +349,7 @@ namespace_put(struct namespace *ns, char *dn, struct ber_element *root,
/* FIXME: if updating, try harder to just update changed indices.
*/
- if (update && unindex_entry(ns, &key, root) != BT_SUCCESS)
+ if (update && (rc = unindex_entry(ns, &key, root)) != BT_SUCCESS)
goto done;
rc = index_entry(ns, &key, root);
diff --git a/usr.sbin/ldapd/search.c b/usr.sbin/ldapd/search.c
index d23cf53ec19..37446d527c1 100644
--- a/usr.sbin/ldapd/search.c
+++ b/usr.sbin/ldapd/search.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: search.c,v 1.5 2010/06/15 15:47:56 martinh Exp $ */
+/* $OpenBSD: search.c,v 1.6 2010/06/23 13:10:14 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -332,11 +332,13 @@ conn_search(struct search *search)
search->cindx->prefix);
btval_reset(&val);
btval_reset(&key);
- rc = BT_NOTFOUND;
+ rc = BT_FAIL;
+ errno = ENOENT;
}
}
- if (rc == BT_NOTFOUND && search->plan->indexed > 1) {
+ if (rc == BT_FAIL && errno == ENOENT &&
+ search->plan->indexed > 1) {
search->cindx = TAILQ_NEXT(search->cindx, next);
if (search->cindx != NULL) {
rc = BT_SUCCESS;
@@ -350,7 +352,7 @@ conn_search(struct search *search)
}
if (rc != BT_SUCCESS) {
- if (rc == BT_FAIL) {
+ if (errno != ENOENT) {
log_warnx("btree failure");
reason = LDAP_OTHER;
}
@@ -389,18 +391,21 @@ conn_search(struct search *search)
btval_reset(&key);
continue;
}
+
rc = btree_txn_get(NULL, search->data_txn, &key, &val);
if (rc == BT_FAIL) {
+ if (errno == ENOENT) {
+ log_warnx("indexed key [%.*s]"
+ " doesn't exist!",
+ (int)key.size, (char *)key.data);
+ btval_reset(&key);
+ rc = BT_SUCCESS;
+ continue;
+ }
log_warnx("btree failure");
- reason = LDAP_OTHER;
btval_reset(&key);
+ reason = LDAP_OTHER;
break;
- } else if (rc == BT_NOTFOUND) {
- log_warnx("indexed key [%.*s] doesn't exist!",
- (int)key.size, (char *)key.data);
- rc = BT_SUCCESS;
- btval_reset(&key);
- continue;
}
}
@@ -432,7 +437,7 @@ conn_search(struct search *search)
search->conn->fd, search->req->msgid,
search->szlim);
reason = LDAP_SIZELIMIT_EXCEEDED;
- rc = BT_NOTFOUND;
+ rc = BT_FAIL;
}
}
@@ -455,8 +460,8 @@ conn_search(struct search *search)
search->nscanned, search->nmatched, search->ndups);
send_ldap_result(conn, search->req->msgid,
LDAP_RES_SEARCH_RESULT, reason);
- if (rc == -1)
- log_debug("search failed");
+ if (errno != ENOENT)
+ log_debug("search failed: %s", strerror(errno));
search_close(search);
}
}
@@ -786,9 +791,9 @@ ldap_search(struct request *req)
goto done;
}
- if ((rc = namespace_begin_txn(search->ns,
- &search->data_txn, &search->indx_txn, 1)) != BT_SUCCESS) {
- if (rc == BT_DEAD) {
+ if ((rc = namespace_begin_txn(search->ns, &search->data_txn,
+ &search->indx_txn, 1)) != BT_SUCCESS) {
+ if (errno == EBUSY) {
if (namespace_queue_request(search->ns, req) != 0) {
reason = LDAP_BUSY;
goto done;
@@ -808,22 +813,16 @@ ldap_search(struct request *req)
bzero(&val, sizeof(val));
key.data = search->basedn;
key.size = strlen(key.data);
- switch (btree_txn_get(NULL, search->data_txn, &key, &val)) {
- case BT_SUCCESS:
+
+ if (btree_txn_get(NULL, search->data_txn, &key, &val) == 0) {
check_search_entry(&key, &val, search);
btval_reset(&val);
- /* FALLTHROUGH */
- case BT_NOTFOUND:
reason = LDAP_SUCCESS;
- goto done;
- case BT_DEAD:
- case BT_FAIL:
- default:
+ } else if (errno == ENOENT)
+ reason = LDAP_SUCCESS;
+ else
reason = LDAP_OTHER;
- goto done;
- }
-
- return 0;
+ goto done;
}
search->plan = search_planner(search->ns, search->filter);