libubus: do not register/unregister with uloop during sync requests
[project/ubus.git] / ubusd_acl.c
index e5a7b56..4b72663 100644 (file)
@@ -62,6 +62,7 @@ struct ubusd_acl_file {
        int ok;
 };
 
+const char *ubusd_acl_dir = "/usr/share/acl.d";
 static struct blob_buf bbuf;
 static struct avl_tree ubusd_acls;
 static int ubusd_acl_seq;
@@ -100,20 +101,21 @@ ubusd_acl_check(struct ubus_client *cl, const char *obj,
        struct blob_attr *cur;
        int rem;
 
-       if (!cl->gid && !cl->uid)
+       if (!cl->uid || !obj)
                return 0;
 
        acl = avl_find_ge_element(&ubusd_acls, obj, acl, avl);
-       while (acl) {
+       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;
 
-               if (ubusd_acl_match_cred(cl, acl)) {
-                       acl = avl_next_element(acl, avl);
+               if (ubusd_acl_match_cred(cl, acl))
                        continue;
-               }
 
                switch (type) {
                case UBUS_ACL_PUBLISH:
@@ -134,7 +136,6 @@ ubusd_acl_check(struct ubus_client *cl, const char *obj,
                                                        return 0;
                        break;
                }
-               acl = avl_next_element(acl, avl);
        }
 
        return -1;
@@ -173,6 +174,13 @@ ubusd_acl_init_client(struct ubus_client *cl, int fd)
        return 0;
 }
 
+void
+ubusd_acl_free_client(struct ubus_client *cl)
+{
+       free(cl->group);
+       free(cl->user);
+}
+
 static void
 ubusd_acl_file_free(struct ubusd_acl_file *file)
 {
@@ -379,8 +387,11 @@ ubusd_acl_load(void)
        struct stat st;
        glob_t gl;
        int j;
+       const char *suffix = "/*.json";
+       char *path = alloca(strlen(ubusd_acl_dir) + strlen(suffix) + 1);
 
-       if (glob("/usr/share/acl.d/*.json", GLOB_NOESCAPE | GLOB_MARK, NULL, &gl))
+       sprintf(path, "%s%s", ubusd_acl_dir, suffix);
+       if (glob(path, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl))
                return;
 
        vlist_update(&ubusd_acl_files);
@@ -412,26 +423,31 @@ ubusd_reply_add(struct ubus_object *obj)
 
        if (!obj->path.key)
                return;
+
        acl = avl_find_ge_element(&ubusd_acls, obj->path.key, acl, avl);
-       while (acl && !avl_is_last(&ubusd_acls, &acl->avl) &&
-                     !ubusd_acl_match_path(obj->path.key, acl->avl.key, NULL)) {
+       if (!acl)
+               return;
 
-               if (acl->priv) {
-                       void *c = blobmsg_open_table(&b, NULL);
+       avl_for_element_to_last(&ubusd_acls, acl, acl, avl) {
+               void *c;
 
-                       blobmsg_add_string(&b, "obj", obj->path.key);
-                       if (acl->user)
-                               blobmsg_add_string(&b, "user", acl->user);
-                       if (acl->group)
-                               blobmsg_add_string(&b, "group", acl->group);
+               if (!acl->priv)
+                       continue;
 
-                       if (acl->priv)
-                               blobmsg_add_field(&b, blobmsg_type(acl->priv), "acl",
-                                       blobmsg_data(acl->priv), blobmsg_data_len(acl->priv));
+               if (ubusd_acl_match_path(obj->path.key, acl->avl.key, NULL))
+                       continue;
 
-                       blobmsg_close_table(&b, c);
-               }
-               acl = avl_next_element(acl, avl);
+               c = blobmsg_open_table(&b, NULL);
+               blobmsg_add_string(&b, "obj", obj->path.key);
+               if (acl->user)
+                       blobmsg_add_string(&b, "user", acl->user);
+               if (acl->group)
+                       blobmsg_add_string(&b, "group", acl->group);
+
+               blobmsg_add_field(&b, blobmsg_type(acl->priv), "acl",
+                       blobmsg_data(acl->priv), blobmsg_data_len(acl->priv));
+
+               blobmsg_close_table(&b, c);
        }
 }
 static int ubusd_reply_query(struct ubus_client *cl, struct ubus_msg_buf *ub, struct blob_attr **attr, struct blob_attr *msg)