ubus: remove session api from plugin and check access via ubus call to let other...
[project/uhttpd.git] / ubus.c
diff --git a/ubus.c b/ubus.c
index 5230270..d3cb6df 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -1,23 +1,22 @@
 /*
  * uhttpd - Tiny single-threaded httpd
  *
- *   Copyright (C) 2010-2012 Jo-Philipp Wich <xm@subsignal.org>
- *   Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
+ *   Copyright (C) 2010-2013 Jo-Philipp Wich <xm@subsignal.org>
+ *   Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-
 #include <libubox/blobmsg.h>
 #include <libubox/blobmsg_json.h>
 #include <libubox/avl.h>
@@ -27,7 +26,6 @@
 
 #include "uhttpd.h"
 #include "plugin.h"
-#include "ubus-session.h"
 
 static const struct uhttpd_ops *ops;
 static struct config *_conf;
@@ -53,6 +51,15 @@ static const struct blobmsg_policy rpc_policy[__RPC_MAX] = {
        [RPC_ID] = { .name = "id", .type = BLOBMSG_TYPE_UNSPEC },
 };
 
+enum {
+       SES_ACCESS,
+       __SES_MAX,
+};
+
+static const struct blobmsg_policy ses_policy[__SES_MAX] = {
+       [SES_ACCESS] = { .name = "access", .type = BLOBMSG_TYPE_BOOL },
+};
+
 struct rpc_data {
        struct blob_attr *id;
        const char *method;
@@ -303,10 +310,42 @@ static void uh_ubus_complete_batch(struct client *cl)
        ops->request_done(cl);
 }
 
+static void uh_ubus_allowed_cb(struct ubus_request *req, int type, struct blob_attr *msg)
+{
+       struct blob_attr *tb[__SES_MAX];
+       bool *allow = (bool *)req->priv;
+
+       if (!msg)
+               return;
+
+       blobmsg_parse(ses_policy, __SES_MAX, tb, blob_data(msg), blob_len(msg));
+
+       if (tb[SES_ACCESS])
+               *allow = blobmsg_get_bool(tb[SES_ACCESS]);
+}
+
+static bool uh_ubus_allowed(const char *sid, const char *obj, const char *fun)
+{
+       uint32_t id;
+       bool allow = false;
+       static struct blob_buf req;
+
+       if (ubus_lookup_id(ctx, "session", &id))
+               return false;
+
+       blob_buf_init(&req, 0);
+       blobmsg_add_string(&req, "sid", sid);
+       blobmsg_add_string(&req, "object", obj);
+       blobmsg_add_string(&req, "function", fun);
+
+       ubus_invoke(ctx, id, "access", req.head, uh_ubus_allowed_cb, &allow, 250);
+
+       return allow;
+}
+
 static void uh_ubus_handle_request_object(struct client *cl, struct json_object *obj)
 {
        struct dispatch_ubus *du = &cl->dispatch.ubus;
-       struct uh_ubus_session *ses;
        struct rpc_data data = {};
        enum rpc_error err = ERROR_PARSE;
 
@@ -326,23 +365,17 @@ static void uh_ubus_handle_request_object(struct client *cl, struct json_object
                goto error;
        }
 
-       ses = uh_ubus_session_get(du->sid);
-       if (!ses) {
-               err = ERROR_SESSION;
+       du->func = data.function;
+       if (ubus_lookup_id(ctx, data.object, &du->obj)) {
+               err = ERROR_OBJECT;
                goto error;
        }
 
-       if (!uh_ubus_session_acl_allowed(ses, data.object, data.function)) {
+       if (!uh_ubus_allowed(du->sid, data.object, data.function)) {
                err = ERROR_ACCESS;
                goto error;
        }
 
-       du->func = data.function;
-       if (ubus_lookup_id(ctx, data.object, &du->obj)) {
-               err = ERROR_OBJECT;
-               goto error;
-       }
-
        uh_ubus_send_request(cl, obj);
        return;
 
@@ -452,10 +485,6 @@ uh_ubus_init(void)
        }
 
        ops->dispatch_add(&ubus_dispatch);
-       if (ubus_session_api_init(ctx)) {
-               fprintf(stderr, "Unable to initialize ubus session API\n");
-               exit(1);
-       }
 
        uloop_done();
        return 0;