Add buxton_update_client_label api 51/92251/9
authorJiwoong Im <jiwoong.im@samsung.com>
Fri, 14 Oct 2016 06:44:39 +0000 (15:44 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Tue, 1 Nov 2016 06:21:01 +0000 (15:21 +0900)
- Because candidate app has "User" label, buxton2d should update buxton
  client label after candidate app changes smack label.
  To solve this, buxton2 provide api to update app's client label.

Change-Id: I57820f6d83197bc8059dd7b1e5d41007a313045f
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
daemon/daemon.c
lib/buxton2.c
lib/include/buxton2.h

index 09aeb88..c7a212d 100644 (file)
@@ -503,6 +503,35 @@ static void proc_get_priv(struct bxt_client *cli,
        resp->val = val;
 }
 
+static int update_label(struct bxt_client *cli)
+{
+       int fd;
+       int ret;
+       char buf[1024];
+       char path[1024];
+
+       snprintf(path, sizeof(path), "/proc/%d/attr/current", cli->cred.pid);
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return -1;
+
+       ret = read(fd, buf, sizeof(buf) - 1);
+       if (ret <= 0) {
+               close(fd);
+               return -1;
+       } else {
+               buf[ret] = 0;
+       }
+
+       close(fd);
+
+       if (cli->label)
+               free(cli->label);
+       cli->label = strdup(buf);
+
+       return 0;
+}
+
 static void proc_control(struct bxt_client *cli,
                struct request *rqst, struct response *resp)
 {
@@ -510,18 +539,20 @@ static void proc_control(struct bxt_client *cli,
        assert(rqst);
        assert(resp);
 
-       if (cli->cred.uid != 0) {
-               resp->res = EPERM;
-               return;
-       }
-
        if (!strcmp(rqst->key, "set_security_mode")) {
+               if (cli->cred.uid != 0) {
+                       resp->res = EPERM;
+                       return;
+               }
                if (rqst->val->value.b == TRUE)
                        buxton_cynara_enable();
                else
                        buxton_cynara_disable();
                resp->res = 0;
                return;
+       } else if (!strcmp(rqst->key, "update_client_label")) {
+               resp->res = update_label(cli);
+               return;
        }
        resp->res = ENOTSUP;
 }
index 1638018..708052f 100644 (file)
@@ -2180,6 +2180,102 @@ EXPORT int buxton_disable_security_sync(struct buxton_client *client)
        return 0;
 }
 
+static void update_label_sync_cb(int status, const struct buxton_layer *layer,
+               const char *key, const struct buxton_value *val,
+               void *user_data)
+{
+       struct response *resp = user_data;
+
+       assert(resp);
+
+       resp->res = status;
+}
+
+static struct bxt_req *update_client_label(struct buxton_client *client,
+               buxton_response_callback callback,
+               void *user_data)
+{
+       int r;
+       struct bxt_req *req;
+       struct request rqst;
+       struct buxton_layer *layer;
+
+       layer = layer_create("dummy");
+
+       req = create_req(layer, NULL, callback, NULL, user_data);
+
+       if (!req)
+               return NULL;
+       layer_unref(layer);
+
+       memset(&rqst, 0, sizeof(rqst));
+       rqst.type = MSG_CTRL;
+       rqst.msgid = req->msgid;
+       rqst.layer = req->layer;
+       rqst.key = strdup("update_client_label");
+
+       pthread_mutex_lock(&client->lock);
+       g_hash_table_insert(client->req_cbs, GUINT_TO_POINTER(req->msgid), req);
+
+       r = send_req(client, &rqst);
+
+       free(rqst.key);
+       if (r == -1) {
+               g_hash_table_remove(client->req_cbs,
+                               GUINT_TO_POINTER(req->msgid));
+               pthread_mutex_unlock(&client->lock);
+               return NULL;
+       }
+
+       pthread_mutex_unlock(&client->lock);
+       return req;
+}
+
+EXPORT int buxton_update_client_label(struct buxton_client *client,
+               buxton_response_callback callback, void *user_data)
+{
+       struct bxt_req *req;
+
+       pthread_mutex_lock(&clients_lock);
+       req = update_client_label(client, callback, user_data);
+       if (!req) {
+               pthread_mutex_unlock(&clients_lock);
+               return -1;
+       }
+
+       pthread_mutex_unlock(&clients_lock);
+       return 0;
+}
+
+EXPORT int buxton_update_client_label_sync(struct buxton_client *client)
+{
+       int r;
+       struct bxt_req *req;
+       struct response resp;
+
+       pthread_mutex_lock(&clients_lock);
+       req = update_client_label(client, update_label_sync_cb, &resp);
+       if (!req) {
+               pthread_mutex_unlock(&clients_lock);
+               return -1;
+       }
+
+       r = wait_msg(client, req->msgid);
+       if (r == -1) {
+               pthread_mutex_unlock(&clients_lock);
+               return -1;
+       }
+
+       if (resp.res) {
+               errno = resp.res;
+               pthread_mutex_unlock(&clients_lock);
+               return -1;
+       }
+
+       pthread_mutex_unlock(&clients_lock);
+       return 0;
+}
+
 static void free_noti(struct bxt_noti *noti)
 {
        if (!noti)
index 512e9c1..aec394a 100644 (file)
@@ -778,6 +778,25 @@ int buxton_disable_security(struct buxton_client *client,
  */
 int buxton_disable_security_sync(struct buxton_client *client);
 
+/**
+ * Update client's label
+ *
+ * @param[in] client #buxton_client struct
+ * @param[in] callback response callback function
+ * @param[in] user_data User data to be used with callback function
+ * @return 0 on success, -1 on error(when an error occurred, errno is set)
+ */
+int buxton_update_client_label(struct buxton_client *client,
+               buxton_response_callback callback, void *user_data);
+
+/**
+ * Update client's label synchronously
+ *
+ * @param[in] client #buxton_client struct
+ * @return 0 on success, -1 on error(when an error occurred, errno is set)
+ */
+int buxton_update_client_label_sync(struct buxton_client *client);
+
 #ifdef __cplusplus
 }
 #endif