1 /* 2 * Copyright (C) 2015 John Cripin <blogic@openwrt.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2.1 6 * as published by the Free Software Foundation 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #include <unistd.h> 15 16 #include <libubox/blob.h> 17 #include <libubox/blobmsg.h> 18 19 #include "libubus.h" 20 #include <libubox/avl-cmp.h> 21 22 static struct ubus_event_handler acl_event; 23 static struct ubus_request acl_req; 24 static struct blob_attr *acl_blob; 25 26 static int acl_cmp(const void *k1, const void *k2, void *ptr) 27 { 28 const struct ubus_acl_key *key1 = k1; 29 const struct ubus_acl_key *key2 = k2; 30 int ret = 0; 31 32 if (key1->user && key2->user) 33 ret = strcmp(key1->user, key2->user); 34 if (ret) 35 return ret; 36 37 if (key1->group && key2->group) 38 ret = strcmp(key1->group, key2->group); 39 if (ret) 40 return ret; 41 42 return strcmp(key1->object, key2->object); 43 } 44 45 AVL_TREE(acl_objects, acl_cmp, true, NULL); 46 47 enum { 48 ACL_OBJ_OBJECT, 49 ACL_OBJ_USER, 50 ACL_OBJ_GROUP, 51 ACL_OBJ_ACL, 52 __ACL_OBJ_MAX 53 }; 54 55 static const struct blobmsg_policy acl_obj_policy[__ACL_OBJ_MAX] = { 56 [ACL_OBJ_OBJECT] = { .name = "obj", .type = BLOBMSG_TYPE_STRING }, 57 [ACL_OBJ_USER] = { .name = "user", .type = BLOBMSG_TYPE_STRING }, 58 [ACL_OBJ_GROUP] = { .name = "group", .type = BLOBMSG_TYPE_STRING }, 59 [ACL_OBJ_ACL] = { .name = "acl", .type = BLOBMSG_TYPE_TABLE }, 60 }; 61 62 static void 63 acl_add(struct blob_attr *obj) 64 { 65 struct blob_attr *tb[__ACL_OBJ_MAX]; 66 struct acl_object *acl; 67 68 blobmsg_parse(acl_obj_policy, __ACL_OBJ_MAX, tb, blobmsg_data(obj), 69 blobmsg_data_len(obj)); 70 71 if (!tb[ACL_OBJ_OBJECT] || !tb[ACL_OBJ_ACL]) 72 return; 73 74 if (!tb[ACL_OBJ_USER] && !tb[ACL_OBJ_GROUP]) 75 return; 76 77 acl = calloc(1, sizeof(*acl)); 78 if (!acl) 79 return; 80 81 acl->avl.key = &acl->key; 82 acl->key.object = blobmsg_get_string(tb[ACL_OBJ_OBJECT]); 83 acl->key.user = blobmsg_get_string(tb[ACL_OBJ_USER]); 84 acl->key.group = blobmsg_get_string(tb[ACL_OBJ_GROUP]); 85 acl->acl = tb[ACL_OBJ_ACL]; 86 avl_insert(&acl_objects, &acl->avl); 87 } 88 89 enum { 90 ACL_POLICY_SEQ, 91 ACL_POLICY_ACL, 92 __ACL_POLICY_MAX 93 }; 94 95 static const struct blobmsg_policy acl_policy[__ACL_POLICY_MAX] = { 96 [ACL_POLICY_SEQ] = { .name = "seq", .type = BLOBMSG_TYPE_INT32 }, 97 [ACL_POLICY_ACL] = { .name = "acl", .type = BLOBMSG_TYPE_ARRAY }, 98 }; 99 100 static void acl_recv_cb(struct ubus_request *req, 101 int type, struct blob_attr *msg) 102 { 103 struct blob_attr *tb[__ACL_POLICY_MAX]; 104 struct blob_attr *cur; 105 size_t rem; 106 107 if (acl_blob) { 108 struct acl_object *p, *q; 109 110 avl_for_each_element_safe(&acl_objects, p, avl, q) { 111 avl_delete(&acl_objects, &p->avl); 112 free(p); 113 } 114 free(acl_blob); 115 } 116 acl_blob = blob_memdup(msg); 117 blobmsg_parse(acl_policy, __ACL_POLICY_MAX, tb, blobmsg_data(msg), 118 blobmsg_data_len(msg)); 119 120 if (!tb[ACL_POLICY_SEQ] && !tb[ACL_POLICY_ACL]) 121 return; 122 123 blobmsg_for_each_attr(cur, tb[ACL_POLICY_ACL], rem) 124 acl_add(cur); 125 } 126 127 static void acl_query(struct ubus_context *ctx) 128 { 129 ubus_invoke_async(ctx, UBUS_SYSTEM_OBJECT_ACL, "query", NULL, &acl_req); 130 acl_req.data_cb = acl_recv_cb; 131 ubus_complete_request_async(ctx, &acl_req); 132 } 133 134 static void acl_subscribe_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, 135 const char *type, struct blob_attr *msg) 136 { 137 if (strcmp(type, "ubus.acl.sequence")) 138 return; 139 acl_query(ctx); 140 } 141 142 int ubus_register_acl(struct ubus_context *ctx) 143 { 144 int ret; 145 146 acl_event.cb = acl_subscribe_cb; 147 148 ret = ubus_register_event_handler(ctx, &acl_event, "ubus.acl.sequence"); 149 if (!ret) 150 acl_query(ctx); 151 152 return ret; 153 } 154
This page was automatically generated by LXR 0.3.1. • OpenWrt