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)
{
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;
}
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)
*/
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