summaryrefslogtreecommitdiff
path: root/dbus
diff options
context:
space:
mode:
authorSangyoon Jang <s89.jang@samsung.com>2014-01-13 18:44:57 +0900
committerLubomir Rintel <lkundrak@v3.sk>2015-02-11 11:55:33 +0100
commitc420f3bd597fef2fd1a08f0c2831bf523b2f9f56 (patch)
treeaebefe0b82b02c05921f0930be4f3e8e394675c6 /dbus
parent1d75b3ecaaf286a43c6afd0d5460840a2c0254cd (diff)
[lib-fix] moved dbus_connection_get_unix_user from daemon to library
This function must be declared at library code even if enable_kdbus_transport is set (same as dbus_connection_get_unix_process_id)
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-connection.c51
-rw-r--r--dbus/kdbus-common.c153
-rw-r--r--dbus/kdbus-common.h14
3 files changed, 196 insertions, 22 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index cc27c371..25556d6b 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -47,6 +47,7 @@
#include "dbus-marshal-basic.h"
#ifdef ENABLE_KDBUS_TRANSPORT
#include "dbus-transport-kdbus.h"
+#include "kdbus-common.h"
#include <stdlib.h>
#endif
@@ -5281,15 +5282,9 @@ dbus_connection_get_socket(DBusConnection *connection,
* @param uid return location for the user ID
* @returns #TRUE if uid is filled in with a valid user ID
*/
-#ifdef ENABLE_KDBUS_TRANSPORT
-dbus_bool_t
-dbus_connection_get_unix_user_dbus (DBusConnection *connection,
- unsigned long *uid)
-#else
dbus_bool_t
dbus_connection_get_unix_user (DBusConnection *connection,
unsigned long *uid)
-#endif
{
dbus_bool_t result;
@@ -5298,16 +5293,26 @@ dbus_connection_get_unix_user (DBusConnection *connection,
CONNECTION_LOCK (connection);
- if (!_dbus_transport_try_to_authenticate (connection->transport))
- result = FALSE;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if (_dbus_connection_get_address (connection) != NULL)
+ {
+ if (!strncmp (_dbus_connection_get_address (connection), "kdbus:", strlen("kdbus:")))
+ result = kdbus_connection_get_unix_user (connection, dbus_bus_get_unique_name (connection), uid, NULL);
+ }
else
- result = _dbus_transport_get_unix_user (connection->transport,
- uid);
+#endif
+ {
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
+ result = FALSE;
+ else
+ result = _dbus_transport_get_unix_user (connection->transport,
+ uid);
+ }
#ifdef DBUS_WIN
_dbus_assert (!result);
#endif
-
+
CONNECTION_UNLOCK (connection);
return result;
@@ -5323,15 +5328,9 @@ dbus_connection_get_unix_user (DBusConnection *connection,
* @param pid return location for the process ID
* @returns #TRUE if uid is filled in with a valid process ID
*/
-#ifdef ENABLE_KDBUS_TRANSPORT
-dbus_bool_t
-dbus_connection_get_unix_process_id_dbus (DBusConnection *connection,
- unsigned long *pid)
-#else
dbus_bool_t
dbus_connection_get_unix_process_id (DBusConnection *connection,
unsigned long *pid)
-#endif
{
dbus_bool_t result;
@@ -5340,11 +5339,21 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
CONNECTION_LOCK (connection);
- if (!_dbus_transport_try_to_authenticate (connection->transport))
- result = FALSE;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if (_dbus_connection_get_address (connection) != NULL)
+ {
+ if (!strncmp (_dbus_connection_get_address (connection), "kdbus:", strlen("kdbus:")))
+ result = kdbus_connection_get_unix_process_id (connection, dbus_bus_get_unique_name (connection), pid, NULL);
+ }
else
- result = _dbus_transport_get_unix_process_id (connection->transport,
- pid);
+#endif
+ {
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
+ result = FALSE;
+ else
+ result = _dbus_transport_get_unix_process_id (connection->transport,
+ pid);
+ }
CONNECTION_UNLOCK (connection);
diff --git a/dbus/kdbus-common.c b/dbus/kdbus-common.c
index e0e63052..837ed917 100644
--- a/dbus/kdbus-common.c
+++ b/dbus/kdbus-common.c
@@ -231,3 +231,156 @@ int release_kdbus_name(int fd, const char *name, __u64 id)
return DBUS_RELEASE_NAME_REPLY_RELEASED;
}
+
+/**
+ * Performs kdbus query of id of the given name
+ *
+ * @param name name to query for
+ * @param transport transport
+ * @param pInfo nameInfo structure address to store info about the name
+ * @return 0 on success, -errno if failed
+ */
+int kdbus_NameQuery(const char* name, DBusTransport* transport, struct nameInfo* pInfo)
+{
+ struct kdbus_cmd_conn_info *cmd;
+ int ret;
+ int fd;
+ uint64_t size;
+ __u64 id = 0;
+
+ memset(pInfo, 0, sizeof(struct nameInfo));
+
+ if(!_dbus_transport_get_socket_fd(transport, &fd))
+ return -EPERM;
+
+ size = sizeof(struct kdbus_cmd_conn_info);
+ if((name[0] == ':') && (name[1] == '1') && (name[2] == '.')) /* if name starts with ":1." it is a unique name and should be send as number */
+ id = strtoull(&name[3], NULL, 10);
+ if(id == 0)
+ size += strlen(name) + 1;
+
+ cmd = alloca(size);
+ if (!cmd)
+ {
+ _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
+ return -errno;
+ }
+
+ memset(cmd, 0, sizeof(struct kdbus_cmd_conn_info));
+ cmd->size = size;
+ cmd->id = id;
+ if(id == 0)
+ memcpy(cmd->name, name, strlen(name) + 1);
+
+ again:
+ ret = ioctl(fd, KDBUS_CMD_CONN_INFO, cmd);
+ if (ret < 0)
+ {
+ if(errno == EINTR)
+ goto again;
+ pInfo->uniqueId = 0;
+ return -errno;
+ }
+ else
+ {
+ struct kdbus_conn_info *info;
+ struct kdbus_item *item;
+
+ info = (struct kdbus_conn_info *)((char*)dbus_transport_get_pool_pointer(transport) + cmd->offset);
+ pInfo->uniqueId = info->id;
+
+ item = info->items;
+ while((uint8_t *)(item) < (uint8_t *)(info) + info->size)
+ {
+ if(item->type == KDBUS_ITEM_CREDS)
+ {
+ pInfo->userId = item->creds.uid;
+ pInfo->processId = item->creds.pid;
+ }
+
+ if(item->type == KDBUS_ITEM_SECLABEL)
+ {
+ pInfo->sec_label_len = item->size - KDBUS_ITEM_HEADER_SIZE - 1;
+ if(pInfo->sec_label_len != 0)
+ {
+ pInfo->sec_label = malloc(pInfo->sec_label_len);
+ if(pInfo->sec_label == NULL)
+ ret = -1;
+ else
+ memcpy(pInfo->sec_label, item->data, pInfo->sec_label_len);
+ }
+ }
+
+ item = KDBUS_PART_NEXT(item);
+ }
+
+ again2:
+ if (ioctl(fd, KDBUS_CMD_FREE, &cmd->offset) < 0)
+ {
+ if(errno == EINTR)
+ goto again2;
+ _dbus_verbose("kdbus error freeing pool: %d (%m)\n", errno);
+ return -errno;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Asks kdbus for uid of the owner of the name given in the message
+ */
+dbus_bool_t kdbus_connection_get_unix_user(DBusConnection* connection, const char* name, unsigned long* uid, DBusError* error)
+{
+ struct nameInfo info;
+ int inter_ret;
+ dbus_bool_t ret = FALSE;
+
+ inter_ret = kdbus_NameQuery(name, dbus_connection_get_transport(connection), &info);
+ if(inter_ret == 0) //name found
+ {
+ _dbus_verbose("User id:%llu\n", (unsigned long long) info.userId);
+ *uid = info.userId;
+ return TRUE;
+ }
+ else if((inter_ret == -ENOENT) || (inter_ret == -ENXIO)) //name has no owner
+ {
+ _dbus_verbose ("Name %s has no owner.\n", name);
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get UID of name '%s': no such name", name);
+ }
+
+ else
+ {
+ _dbus_verbose("kdbus error determining UID: err %d (%m)\n", errno);
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Could not determine UID for '%s'", name);
+ }
+
+ return ret;
+}
+
+/*
+ * Asks kdbus for pid of the owner of the name given in the message
+ */
+dbus_bool_t kdbus_connection_get_unix_process_id(DBusConnection* connection, const char* name, unsigned long* pid, DBusError* error)
+{
+ struct nameInfo info;
+ int inter_ret;
+ dbus_bool_t ret = FALSE;
+
+ inter_ret = kdbus_NameQuery(name, dbus_connection_get_transport(connection), &info);
+ if(inter_ret == 0) //name found
+ {
+ _dbus_verbose("Process id:%llu\n", (unsigned long long) info.processId);
+ *pid = info.processId;
+ return TRUE;
+ }
+ else if((inter_ret == -ENOENT) || (inter_ret == -ENXIO)) //name has no owner
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Could not get PID of name '%s': no such name", name);
+ else
+ {
+ _dbus_verbose("kdbus error determining PID: err %d (%m)\n", errno);
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Could not determine PID for '%s'", name);
+ }
+
+ return ret;
+}
diff --git a/dbus/kdbus-common.h b/dbus/kdbus-common.h
index 14b62af5..4b84a316 100644
--- a/dbus/kdbus-common.h
+++ b/dbus/kdbus-common.h
@@ -41,7 +41,19 @@
//todo restore if DBus policy will be applied in kdbus somehow
//#define POLICY_TO_KDBUS
-dbus_bool_t register_kdbus_policy(const char* name, DBusTransport *transport, unsigned long int uid);
+struct nameInfo
+{
+ __u64 uniqueId;
+ __u64 userId;
+ __u64 processId;
+ __u32 sec_label_len;
+ char *sec_label;
+};
+int kdbus_NameQuery(const char *name, DBusTransport *transport, struct nameInfo *pInfo);
+dbus_bool_t kdbus_connection_get_unix_user(DBusConnection *connection, const char *name, unsigned long *uid, DBusError *error);
+dbus_bool_t kdbus_connection_get_unix_process_id(DBusConnection *connection, const char *name, unsigned long *uid, DBusError *error);
+
+dbus_bool_t register_kdbus_policy(const char *name, DBusTransport *transport, unsigned long int uid);
int request_kdbus_name(int fd, const char *name, const __u64 flags, __u64 id);
int release_kdbus_name(int fd, const char *name, __u64 id);