*/
#include "kdbus.h"
#include "kdbus-common.h"
+#include "dbus-transport-kdbus.h"
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <dbus/dbus-internals.h>
#include <dbus/dbus-shared.h>
-static struct kdbus_policy *make_policy_name(const char *name)
+static struct kdbus_item *make_policy_name(const char *name)
{
- struct kdbus_policy *p;
- __u64 size;
-
- size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
- p = malloc(size);
- if (!p)
- return NULL;
- memset(p, 0, size);
- p->size = size;
- p->type = KDBUS_POLICY_NAME;
- strcpy(p->name, name);
-
- return p;
+ struct kdbus_item *p;
+ __u64 size;
+
+ size = offsetof(struct kdbus_item, policy.name) + strlen(name) + 1;
+ p = malloc(size);
+ if (!p)
+ return NULL;
+ memset(p, 0, size);
+ p->size = size;
+ p->type = KDBUS_ITEM_POLICY_NAME;
+ memcpy(p->policy.name, name, strlen(name) + 1);
+
+ return p;
}
-static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
+static struct kdbus_item *make_policy_access(__u64 type, __u64 bits, __u64 id)
{
- struct kdbus_policy *p;
- __u64 size = sizeof(*p);
+ struct kdbus_item *p;
+ __u64 size = sizeof(*p);
- p = malloc(size);
- if (!p)
- return NULL;
+ p = malloc(size);
+ if (!p)
+ return NULL;
- memset(p, 0, size);
- p->size = size;
- p->type = KDBUS_POLICY_ACCESS;
- p->access.type = type;
- p->access.bits = bits;
- p->access.id = id;
+ memset(p, 0, size);
+ p->size = size;
+ p->type = KDBUS_ITEM_POLICY_ACCESS;
+ p->policy.access.type = type;
+ p->policy.access.bits = bits;
+ p->policy.access.id = id;
- return p;
+ return p;
}
-static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
+static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_item *policy, __u64 max_size)
{
- struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
+ struct kdbus_item *dst = (struct kdbus_item *) ((char *) cmd_policy + cmd_policy->size);
- if (cmd_policy->size + policy->size > max_size)
- return;
+ if (cmd_policy->size + policy->size > max_size)
+ return;
- memcpy(dst, policy, policy->size);
- cmd_policy->size += KDBUS_ALIGN8(policy->size);
- free(policy);
+ memcpy(dst, policy, policy->size);
+ cmd_policy->size += KDBUS_ALIGN8(policy->size);
+ free(policy);
}
/**
* Name of the policy equals name on the bus.
*
* @param name name of the policy = name of the connection
- * @param connection the connection
- * @param error place to store errors
+ * @param transport - transport
+ * @param owner_uid - uid or euid of the process being owner of the name
*
* @returns #TRUE on success
*/
-dbus_bool_t register_kdbus_policy(const char* name, int fd)
+dbus_bool_t register_kdbus_policy(const char* name, DBusTransport *transport, unsigned long int owner_uid)
{
- struct kdbus_cmd_policy *cmd_policy;
- struct kdbus_policy *policy;
- int size = 0xffff;
+ struct kdbus_cmd_policy *cmd_policy;
+ struct kdbus_item *policy;
+ int size = 0xffff;
+ int fd;
- cmd_policy = alloca(size);
- memset(cmd_policy, 0, size);
+ if(!_dbus_transport_get_socket_fd (transport, &fd))
+ return FALSE;
- policy = (struct kdbus_policy *) cmd_policy->policies;
- cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
+ cmd_policy = alloca(size);
+ memset(cmd_policy, 0, size);
- policy = make_policy_name(name);
- append_policy(cmd_policy, policy, size);
+ policy = (struct kdbus_item *) cmd_policy->policies;
+ cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
- policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
- append_policy(cmd_policy, policy, size);
+ policy = make_policy_name(name);
+ append_policy(cmd_policy, policy, size);
- policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
- append_policy(cmd_policy, policy, size);
+ policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, owner_uid);
+ append_policy(cmd_policy, policy, size);
- policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
- append_policy(cmd_policy, policy, size);
+ policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
+ append_policy(cmd_policy, policy, size);
- if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
- {
- _dbus_verbose ("Error setting policy: %m, %d\n", errno);
- return FALSE;
- }
+ policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
+ append_policy(cmd_policy, policy, size);
- _dbus_verbose("Policy %s set correctly\n", name);
- return TRUE;
-}
+ if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
+ {
+ _dbus_verbose ("Error setting policy: %m, %d\n", errno);
+ return FALSE;
+ }
-dbus_bool_t list_kdbus_names(int fd, char ***listp, int *array_len)
-{
- struct kdbus_cmd_names* pCmd;
- __u64 cmd_size;
- dbus_bool_t ret_val = FALSE;
- char** list;
- int list_len = 0;
- int i = 0;
- int j;
-
- cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
- pCmd = malloc(cmd_size);
- if(pCmd == NULL)
- goto out;
- pCmd->size = cmd_size;
-
-again:
- cmd_size = 0;
- if(ioctl(fd, KDBUS_CMD_NAME_LIST, pCmd))
- {
- if(errno == EINTR)
- goto again;
- if(errno == ENOBUFS) //buffer to small to put all names into it
- cmd_size = pCmd->size; //here kernel tells how much memory it needs
- else
- {
- _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
- goto out;
- }
- }
- if(cmd_size) //kernel needs more memory
- {
- pCmd = realloc(pCmd, cmd_size); //prepare memory
- if(pCmd == NULL)
- return FALSE;
- goto again; //and try again
- }
- else
- {
- struct kdbus_cmd_name* pCmd_name;
-
- for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
- list_len++;
-
- list = malloc(sizeof(char*) * (list_len + 1));
- if(list == NULL)
- goto out;
-
- for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
- {
- list[i] = strdup(pCmd_name->name);
- if(list[i] == NULL)
- {
- for(j=0; j<i; j++)
- free(list[j]);
- free(list);
- goto out;
- }
- _dbus_verbose ("Name %d: %s\n", i, list[i]);
- ++i;
- }
- list[i] = NULL;
- }
-
- *array_len = list_len;
- *listp = list;
- ret_val = TRUE;
-
-out:
- if(pCmd)
- free(pCmd);
- return ret_val;
+ _dbus_verbose("Policy %s set correctly\n", name);
+ return TRUE;
}
/**
- * kdbus version of dbus_bus_request_name.
*
- * Asks the bus to assign the given name to this connection.
+ * Asks the bus to assign the given name to the connection.
*
* Use same flags as original dbus version with one exception below.
* Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
* never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
* is returned by kdbus.
*
- * @param connection the connection
+ * @param fd - file descriptor of the connection
* @param name the name to request
* @param flags flags
- * @param error location to store the error
- * @returns a result code, -1 if error is set
+ * @param id unique id of the connection for which the name is being registered
+ * @returns a DBus result code on success, -errno on error
*/
int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id)
{
- struct kdbus_cmd_name *cmd_name;
-
- __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
- __u64 flags_kdbus = 0;
-
- cmd_name = alloca(size);
-
-// memset(cmd_name, 0, size);
- strcpy(cmd_name->name, name);
- cmd_name->size = size;
-
- if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
- flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
- if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
- flags_kdbus |= KDBUS_NAME_QUEUE;
- if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
- flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
- if(flags & KDBUS_NAME_STARTER)
- flags_kdbus |= KDBUS_NAME_STARTER;
-
- cmd_name->flags = flags_kdbus;
- cmd_name->id = id;
-// cmd_name->conn_flags = 0;
-
- _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags);
-
- if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
- {
- _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
- if(errno == EEXIST)
- return DBUS_REQUEST_NAME_REPLY_EXISTS;
- return -errno;
- }
-
- _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags);
-
- if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
- return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
- else
- return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
- /*todo now 1 code is never returned - DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
- * because kdbus never returns it now
- */
+ struct kdbus_cmd_name *cmd_name;
+
+ __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
+ __u64 flags_kdbus = 0;
+
+ cmd_name = alloca(size);
+
+ strcpy(cmd_name->name, name);
+ cmd_name->size = size;
+
+ if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
+ flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
+ if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
+ flags_kdbus |= KDBUS_NAME_QUEUE;
+ if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
+ flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
+ if(flags & KDBUS_NAME_STARTER_NAME)
+ flags_kdbus |= KDBUS_NAME_STARTER_NAME;
+
+ cmd_name->flags = flags_kdbus;
+ cmd_name->id = id;
+
+ _dbus_verbose("Request name - flags sent: 0x%llx !!!!!!!!!\n", cmd_name->flags);
+
+ if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
+ {
+ _dbus_verbose ("error acquiring name '%s': %m, %d\n", name, errno);
+ if(errno == EEXIST)
+ return DBUS_REQUEST_NAME_REPLY_EXISTS;
+ if(errno == EALREADY)
+ return DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
+ return -errno;
+ }
+
+ _dbus_verbose("Request name - received flag: 0x%llx !!!!!!!!!\n", cmd_name->flags);
+
+ if(cmd_name->flags & KDBUS_NAME_IN_QUEUE)
+ return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
+ else
+ return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
}
+/**
+ *
+ * Releases well-known name - the connections resign from the name
+ * which can be then assigned to another connection or the connection
+ * is being removed from the queue for that name
+ *
+ * @param fd - file descriptor of the connection
+ * @param name the name to request
+ * @param id unique id of the connection for which the name is being released
+ * @returns a DBus result code on success, -errno on error
+ */
int release_kdbus_name(int fd, const char *name, __u64 id)
{
- struct kdbus_cmd_name *cmd_name;
+ struct kdbus_cmd_name *cmd_name;
- __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
+ __u64 size = sizeof(*cmd_name) + strlen(name) + 1;
- cmd_name = alloca(size);
- cmd_name->id = id;
- strcpy(cmd_name->name, name);
- cmd_name->size = size;
+ cmd_name = alloca(size);
+ cmd_name->id = id;
+ strcpy(cmd_name->name, name);
+ cmd_name->size = size;
- if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
- {
- if(errno == ESRCH)
- return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
- else if (errno == EPERM)
- return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
- _dbus_verbose ("error releasing name '%s' for id:%llu. Error: %m, %d\n", name, (unsigned long long)id, errno);
- return -errno;
- }
+ if (ioctl(fd, KDBUS_CMD_NAME_RELEASE, cmd_name))
+ {
+ if(errno == ESRCH)
+ return DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
+ else if (errno == EPERM)
+ return DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
+ _dbus_verbose ("error releasing name '%s' for id:%llu. Error: %m, %d\n", name, (unsigned long long)id, errno);
+ return -errno;
+ }
- _dbus_verbose("Name '%s' released\n", name);
+ _dbus_verbose("Name '%s' released\n", name);
- return DBUS_RELEASE_NAME_REPLY_RELEASED;
+ return DBUS_RELEASE_NAME_REPLY_RELEASED;
}