diff mbox

[OpenWrt-Devel,ubus,2/3] ubusd: fallback to linear search on ACLs to fix wildcards

Message ID 9c99aae27d35e65b9c80abd1ed147f5a33bfce6b.1472125392.git.denis.osvald@sartura.hr
State Changes Requested
Delegated to: John Crispin
Headers show

Commit Message

Denis Osvald Aug. 25, 2016, 11:54 a.m. UTC
Change ACL search loop to go from exact match towards beginning.  The
linear search fallback (continue instead of break) is needed because the
ACLs matching one object need not be consecutive in the AVL tree.  For
example, if we have ACLs for "foo.*", "foo.abc" and "foo.xyz", then
object "foo.xyz" is matched by first and third rules which can't be
consecutive in any sorting order.

Also, this makes the ACL searching loops logically same as in rpcd, with
the same quirk that "net*" won't match "net", effectively making '*'
represent _one_ or more characters.

Signed-off-by: Denis Osvald <denis.osvald@sartura.hr>
---
 ubusd_acl.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/ubusd_acl.c b/ubusd_acl.c
index 2700c86..2db515e 100644
--- a/ubusd_acl.c
+++ b/ubusd_acl.c
@@ -104,15 +104,13 @@  ubusd_acl_check(struct ubus_client *cl, const char *obj,
 	if (!cl->uid || !obj)
 		return 0;
 
-	acl = avl_find_ge_element(&ubusd_acls, obj, acl, avl);
+	acl = avl_find_le_element(&ubusd_acls, obj, acl, avl);
 	if (!acl)
 		return -1;
 
-	avl_for_element_to_last(&ubusd_acls, acl, acl, avl) {
-		int diff = ubusd_acl_match_path(obj, acl->avl.key, NULL);
-
-		if (diff)
-			break;
+	avl_for_first_to_element_reverse(&ubusd_acls, acl, acl, avl) {
+		if (ubusd_acl_match_path(obj, acl->avl.key, NULL))
+			continue;
 
 		if (ubusd_acl_match_cred(cl, acl))
 			continue;
@@ -424,11 +422,11 @@  ubusd_reply_add(struct ubus_object *obj)
 	if (!obj->path.key)
 		return;
 
-	acl = avl_find_ge_element(&ubusd_acls, obj->path.key, acl, avl);
+	acl = avl_find_le_element(&ubusd_acls, obj->path.key, acl, avl);
 	if (!acl)
 		return;
 
-	avl_for_element_to_last(&ubusd_acls, acl, acl, avl) {
+	avl_for_first_to_element_reverse(&ubusd_acls, acl, acl, avl) {
 		void *c;
 
 		if (!acl->priv)
@@ -489,7 +487,7 @@  static int ubusd_acl_recv(struct ubus_client *cl, struct ubus_msg_buf *ub, const
 
 void ubusd_acl_init(void)
 {
-	avl_init(&ubusd_acls, ubusd_acl_match_path, true, NULL);
+	avl_init(&ubusd_acls, avl_strcmp, true, NULL);
 	acl_obj = ubusd_create_object_internal(NULL, UBUS_SYSTEM_OBJECT_ACL);
 	acl_obj->recv_msg = ubusd_acl_recv;
 }