#include "ubusd.h"
+#ifndef SO_PEERCRED
+struct ucred {
+ int pid;
+ int uid;
+ int gid;
+};
+#endif
+
struct ubusd_acl_obj {
struct avl_node avl;
struct list_head list;
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;
struct blob_attr *cur;
int rem;
- if (!cl->gid && !cl->gid)
+ if (!cl->uid || !obj)
return 0;
acl = avl_find_ge_element(&ubusd_acls, obj, acl, avl);
- while (acl && !avl_is_last(&ubusd_acls, &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;
- 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:
return 0;
break;
}
- acl = avl_next_element(acl, avl);
}
return -1;
int
ubusd_acl_init_client(struct ubus_client *cl, int fd)
{
- unsigned int len = sizeof(struct ucred);
struct ucred cred;
struct passwd *pwd;
struct group *group;
+#ifdef SO_PEERCRED
+ unsigned int len = sizeof(struct ucred);
+
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1)
return -1;
+#else
+ memset(&cred, 0, sizeof(cred));
+#endif
pwd = getpwuid(cred.uid);
if (!pwd)
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)
{
struct ubusd_acl_obj *o;
char *k;
- o = calloc_a(1, sizeof(*o), &k, strlen(obj) + 1);
+ o = calloc_a(sizeof(*o), &k, strlen(obj) + 1);
o->user = file->user;
o->group = file->group;
o->avl.key = k;
else
return;
- if (!tb[ACL_ACCESS] && !tb[ACL_PUBLISH] && !tb[ACL_INHERIT])
- return;
-
if (tb[ACL_ACCESS])
blobmsg_for_each_attr(cur, tb[ACL_ACCESS], rem)
ubusd_acl_add_access(file, cur);
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);
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)