16 #include <sys/socket.h>
17 #include <sys/types.h>
26 #include <libubox/vlist.h>
27 #include <libubox/blobmsg_json.h>
28 #include <libubox/avl-cmp.h>
29 #include <libubox/ulog.h>
43 struct list_head
list;
60 struct vlist_node
avl;
72 static struct blob_buf
bbuf;
96 if (!cl || !cl->
uid || !obj)
106 const char *key = acl->
avl.key;
111 if (cur_match_len < match_len)
114 match_len = cur_match_len;
120 if (match_len != (
int) strlen(key))
150 struct blob_attr *cur;
154 blobmsg_for_each_attr(cur, acl->
methods, rem)
155 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING) {
156 cur_method = blobmsg_get_string(cur);
158 if (!strcmp(method, cur_method) || !strcmp(
"*", cur_method))
177 unsigned int len =
sizeof(
struct ucred);
179 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) {
180 ULOG_ERR(
"Failed getsockopt(): %m\n");
184 memset(&cred, 0,
sizeof(cred));
187 pwd = getpwuid(cred.
uid);
189 ULOG_ERR(
"Failed getpwuid(): %m\n");
193 group = getgrgid(cred.
gid);
195 ULOG_ERR(
"Failed getgrgid(): %m\n");
202 cl->
group = strdup(group->gr_name);
203 cl->
user = strdup(pwd->pw_name);
220 list_for_each_entry_safe(p, q, &file->
acl,
list) {
246 int len = strlen(obj);
250 if (obj[len - 1] ==
'*') {
255 o = calloc_a(
sizeof(*o), &k, len + 1);
259 o->
avl.key = memcpy(k, obj, len);
261 list_add(&o->
list, &file->
acl);
274 blobmsg_data_len(obj));
332 [
ACL_USER] = { .name =
"user", .type = BLOBMSG_TYPE_STRING },
333 [
ACL_GROUP] = { .name =
"group", .type = BLOBMSG_TYPE_STRING },
334 [
ACL_ACCESS] = { .name =
"access", .type = BLOBMSG_TYPE_TABLE },
335 [
ACL_PUBLISH] = { .name =
"publish", .type = BLOBMSG_TYPE_ARRAY },
336 [
ACL_SUBSCRIBE] = { .name =
"subscribe", .type = BLOBMSG_TYPE_ARRAY },
337 [
ACL_INHERIT] = { .name =
"inherit", .type = BLOBMSG_TYPE_ARRAY },
338 [
ACL_LISTEN] = { .name=
"listen", .type = BLOBMSG_TYPE_ARRAY },
339 [
ACL_SEND] = { .name=
"send", .type = BLOBMSG_TYPE_ARRAY },
349 blob_len(file->
blob));
359 blobmsg_for_each_attr(cur, tb[
ACL_ACCESS], rem)
364 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
369 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
373 blobmsg_for_each_attr(cur, tb[
ACL_LISTEN], rem)
374 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
378 blobmsg_for_each_attr(cur, tb[
ACL_SEND], rem)
379 if (blobmsg_type(cur) == BLOBMSG_TYPE_STRING)
385 struct vlist_node *node_old)
405 blob_buf_init(&
b, 0);
410 blob_nest_end(&
b, s);
423 blob_buf_init(&
bbuf, 0);
424 if (!blobmsg_add_json_from_file(&
bbuf, filename)) {
425 syslog(LOG_ERR,
"failed to parse %s\n", filename);
429 file = calloc_a(
sizeof(*file), &
blob, blob_raw_len(
bbuf.head));
436 INIT_LIST_HEAD(&file->
acl);
438 vlist_add(&ubusd_acl_files, &file->
avl, filename);
439 syslog(LOG_INFO,
"loading %s\n", filename);
450 const char *suffix =
"/*.json";
454 if (glob(
path, GLOB_NOESCAPE | GLOB_MARK, NULL, &gl))
457 vlist_update(&ubusd_acl_files);
458 for (j = 0; j < gl.gl_pathc; j++) {
459 if (stat(gl.gl_pathv[j], &st) || !S_ISREG(st.st_mode))
462 if (st.st_uid || st.st_gid) {
463 syslog(LOG_ERR,
"%s has wrong owner\n", gl.gl_pathv[j]);
466 if (st.st_mode & (S_IWOTH | S_IWGRP | S_IXOTH)) {
467 syslog(LOG_ERR,
"%s has wrong permissions\n", gl.gl_pathv[j]);
474 vlist_flush(&ubusd_acl_files);
495 const char *key = acl->
avl.key;
504 if (cur_match_len < match_len)
507 match_len = cur_match_len;
513 if (match_len != (
int) strlen(key))
517 c = blobmsg_open_table(&
b, NULL);
518 blobmsg_add_string(&
b,
"obj", obj->
path.key);
520 blobmsg_add_string(&
b,
"user", acl->
user);
522 blobmsg_add_string(&
b,
"group", acl->
group);
524 blobmsg_add_field(&
b, blobmsg_type(acl->
priv),
"acl",
525 blobmsg_data(acl->
priv), blobmsg_data_len(acl->
priv));
527 blobmsg_close_table(&
b, c);
543 blob_buf_init(&
b, 0);
548 a = blobmsg_open_array(&
b,
"acl");
551 blobmsg_close_table(&
b, a);
553 blob_nest_end(&
b, d);
562 if (!strcmp(method,
"query"))
struct blob_attr ** ubus_parse_msg(struct blob_attr *msg, size_t len)
int(* recv_msg)(struct ubus_client *client, struct ubus_msg_buf *ub, const char *method, struct blob_attr *msg)
struct blob_attr * methods
static bool ubus_strmatch_len(const char *s1, const char *s2, int *len)
struct ubus_msg_buf * ubus_msg_new(void *data, int len, bool shared)
int ubusd_send_event(struct ubus_client *cl, const char *id, event_fill_cb fill_cb, void *cb_priv)
void ubus_proto_send_msg_from_blob(struct ubus_client *cl, struct ubus_msg_buf *ub, uint8_t type)
static struct blob_buf bbuf
static void ubusd_acl_file_add(struct ubusd_acl_file *file)
static struct avl_tree ubusd_acls
static void ubusd_acl_update_cb(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old)
int ubusd_acl_init_client(struct ubus_client *cl, int fd)
const char * ubusd_acl_dir
static VLIST_TREE(ubusd_acl_files, avl_strcmp, ubusd_acl_update_cb, false, false)
static void ubusd_acl_file_free(struct ubusd_acl_file *file)
int ubusd_acl_check(struct ubus_client *cl, const char *obj, const char *method, enum ubusd_acl_type type)
static struct ubus_object * acl_obj
static int ubusd_acl_load_file(const char *filename)
static int ubusd_reply_query(struct ubus_client *cl, struct ubus_msg_buf *ub, struct blob_attr **attr, struct blob_attr *msg)
void ubusd_acl_free_client(struct ubus_client *cl)
void ubusd_acl_init(void)
static void ubusd_acl_add_subscribe(struct ubusd_acl_file *file, const char *obj)
static void ubusd_acl_add_access(struct ubusd_acl_file *file, struct blob_attr *obj)
static void ubusd_acl_add_listen(struct ubusd_acl_file *file, const char *obj)
static const struct blobmsg_policy acl_policy[__ACL_MAX]
static int ubusd_acl_match_cred(struct ubus_client *cl, struct ubusd_acl_obj *obj)
static struct ubus_msg_buf * ubusd_create_sequence_event_msg(void *priv, const char *id)
static void ubusd_acl_add_send(struct ubusd_acl_file *file, const char *obj)
static void ubusd_acl_add_publish(struct ubusd_acl_file *file, const char *obj)
static int ubusd_acl_recv(struct ubus_client *cl, struct ubus_msg_buf *ub, const char *method, struct blob_attr *msg)
static struct ubusd_acl_obj * ubusd_acl_alloc_obj(struct ubusd_acl_file *file, const char *obj)
static void ubusd_reply_add(struct ubus_object *obj)
void ubusd_acl_load(void)
static const struct blobmsg_policy acl_obj_policy[__ACL_ACCESS_MAX]
void ubus_init_string_tree(struct avl_tree *tree, bool dup)
struct ubus_object * ubusd_create_object_internal(struct ubus_object_type *type, uint32_t id)
static struct ubus_object * ubusd_find_object(uint32_t objid)
@ UBUS_STATUS_INVALID_ARGUMENT
@ UBUS_STATUS_INVALID_COMMAND
#define UBUS_SYSTEM_OBJECT_ACL