summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormartinh <martinh@openbsd.org>2010-07-02 01:44:45 +0000
committermartinh <martinh@openbsd.org>2010-07-02 01:44:45 +0000
commit86f37e34f71e3bf06ae4eebb3a1a38a2904da955 (patch)
tree005e7db5680b14c1be754673b5e3588281458ae1
parentAdd a BT_CURSOR_EXACT operation to btree_cursor_get. It behaves like (diff)
downloadwireguard-openbsd-86f37e34f71e3bf06ae4eebb3a1a38a2904da955.tar.xz
wireguard-openbsd-86f37e34f71e3bf06ae4eebb3a1a38a2904da955.zip
Disallow deleting non-leaf nodes.
-rw-r--r--usr.sbin/ldapd/modify.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/usr.sbin/ldapd/modify.c b/usr.sbin/ldapd/modify.c
index 59b878c554d..05151342843 100644
--- a/usr.sbin/ldapd/modify.c
+++ b/usr.sbin/ldapd/modify.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: modify.c,v 1.7 2010/07/01 00:43:56 martinh Exp $ */
+/* $OpenBSD: modify.c,v 1.8 2010/07/02 01:44:45 martinh Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -30,9 +30,11 @@
int
ldap_delete(struct request *req)
{
+ struct btval key;
char *dn;
struct namespace *ns;
struct referrals *refs;
+ struct cursor *cursor;
++stats.req_mod;
@@ -62,16 +64,36 @@ ldap_delete(struct request *req)
return ldap_respond(req, LDAP_OTHER);
}
+ /* Check that this is a leaf node by getting a cursor to the DN
+ * we're about to delete. If there is a next entry with the DN
+ * as suffix (ie, a child node), the DN can't be deleted.
+ */
+ if ((cursor = btree_txn_cursor_open(NULL, ns->data_txn)) == NULL)
+ goto fail;
+
+ bzero(&key, sizeof(key));
+ key.data = dn;
+ key.size = strlen(dn);
+ if (btree_cursor_get(cursor, &key, NULL, BT_CURSOR_EXACT) != 0)
+ goto fail;
+ if (btree_cursor_get(cursor, &key, NULL, BT_NEXT) != 0) {
+ if (errno != ENOENT)
+ goto fail;
+ } else if (has_suffix(&key, dn)) {
+ namespace_abort(ns);
+ return ldap_respond(req, LDAP_NOT_ALLOWED_ON_NONLEAF);
+ }
+
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);
}
+
+fail:
+ namespace_abort(ns);
+ if (errno == ENOENT)
+ return ldap_respond(req, LDAP_NO_SUCH_OBJECT);
+ return ldap_respond(req, LDAP_OTHER);
}
int