summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Lipinski <konrad.l@samsung.com>2017-01-18 16:44:34 +0100
committerKonrad Lipinski <konrad.l@samsung.com>2017-02-03 13:46:06 +0100
commitfc278ebd7e5db244b659b0eea74b1c856f01f584 (patch)
tree03bd8d0be67f34179fdb2fb5ef50c28e1be687e3
parent5754f7e51f77828789bdf062c800833fd7d5974f (diff)
downloaddbus-sandbox/konradl/tizen.tar.gz
dbus-sandbox/konradl/tizen.tar.bz2
dbus-sandbox/konradl/tizen.zip
org.freedesktop.DBus.UpdateCredentials, dbus_bus_update_credentialssandbox/konradl/tizen
-rw-r--r--bus/driver.c22
-rw-r--r--dbus/dbus-bus.c40
-rw-r--r--dbus/dbus-bus.h3
-rw-r--r--dbus/dbus-connection.c13
-rw-r--r--dbus/dbus-connection.h2
-rw-r--r--dbus/dbus-message.c2
-rwxr-xr-xdbus/dbus-transport-kdbus.c382
-rw-r--r--dbus/kdbus.h3
8 files changed, 310 insertions, 157 deletions
diff --git a/bus/driver.c b/bus/driver.c
index 16454316..720b7e88 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -1388,6 +1388,24 @@ bus_driver_handle_add_match (DBusConnection *connection,
return BUS_RESULT_FALSE;
}
+static BusResult bus_driver_handle_update_credentials(DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+#ifdef DBUS_ENABLE_SMACK
+ if (!dbus_connection_reset_smack_label(connection))
+ {
+ dbus_set_error(error, DBUS_ERROR_FAILED, "Failed to get seclabel");
+ return BUS_RESULT_FALSE;
+ }
+#endif
+
+ return send_ack_reply (connection, transaction, message, error)
+ ? BUS_RESULT_TRUE
+ : BUS_RESULT_FALSE;
+}
+
static BusResult
bus_driver_handle_remove_match (DBusConnection *connection,
BusTransaction *transaction,
@@ -2393,6 +2411,10 @@ static const MessageHandler dbus_message_handlers[] = {
DBUS_TYPE_STRING_AS_STRING,
DBUS_TYPE_STRING_AS_STRING,
bus_smack_handle_get_connection_context },
+ { "UpdateCredentials",
+ "",
+ "",
+ bus_driver_handle_update_credentials },
{ NULL, NULL, NULL, NULL }
};
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index 6c66e1c9..81a47eac 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -1606,4 +1606,44 @@ dbus_bus_remove_match (DBusConnection *connection,
dbus_message_unref (msg);
}
+/**
+ * Updates connection metadata (ex. creds, seclabel) to current values.
+ *
+ * @param connection the connection.
+ * @returns #TRUE iff successful
+ */
+dbus_bool_t
+dbus_bus_update_credentials (DBusConnection *connection, DBusError *error)
+{
+ DBusMessage *msg;
+ DBusMessage *reply;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+ msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ "UpdateCredentials");
+
+ reply = dbus_connection_send_with_reply_and_block (connection, msg,
+ -1, error);
+ dbus_message_unref (msg);
+
+ if (reply == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return FALSE;
+ }
+
+ if (dbus_set_error_from_message (error, reply))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ dbus_message_unref (reply);
+ return FALSE;
+ }
+
+ dbus_message_unref (reply);
+ return TRUE;
+}
+
/** @} */
diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h
index 02a95711..1fcb2c9e 100644
--- a/dbus/dbus-bus.h
+++ b/dbus/dbus-bus.h
@@ -87,6 +87,9 @@ DBUS_EXPORT
void dbus_bus_remove_match (DBusConnection *connection,
const char *rule,
DBusError *error);
+DBUS_EXPORT
+dbus_bool_t dbus_bus_update_credentials (DBusConnection *connection,
+ DBusError *error);
/** @} */
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 9a5be336..dc17a6a6 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -5439,6 +5439,19 @@ dbus_connection_get_smack_label (DBusConnection *connection,
*label = connection->peer_smack_label;
return *label != NULL;
}
+
+dbus_bool_t
+dbus_connection_reset_smack_label (DBusConnection *connection)
+{
+ unsigned long pid;
+ char *label;
+ if (!dbus_connection_get_unix_process_id (connection, &pid)
+ || 0 > smack_new_label_from_process (pid, &label))
+ return FALSE;
+ free(connection->peer_smack_label);
+ connection->peer_smack_label = label;
+ return TRUE;
+}
#endif
/**
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index aac57046..c0da37b4 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -268,6 +268,8 @@ dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection
DBUS_EXPORT
dbus_bool_t dbus_connection_get_smack_label (DBusConnection *connection,
const char **label);
+DBUS_EXPORT
+dbus_bool_t dbus_connection_reset_smack_label (DBusConnection *connection);
#endif
DBUS_EXPORT
dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index 0e3f323b..97707e65 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -4573,7 +4573,7 @@ _dbus_message_loader_queue_messages (DBusMessageLoader *loader)
_dbus_assert (loader->messages != NULL);
_dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
- }
+ }
else
{
_dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c
index 893a3eff..a0647267 100755
--- a/dbus/dbus-transport-kdbus.c
+++ b/dbus/dbus-transport-kdbus.c
@@ -44,12 +44,14 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <fcntl.h>
#ifdef LIBDBUSPOLICY
#include <dbuspolicy/libdbuspolicy1.h>
+#include <sys/smack.h>
#include "dbus-marshal-header.h"
#include "dbus-protocol-gvariant.h"
#endif
@@ -163,12 +165,15 @@ struct DBusTransportKdbus
Matchmaker *matchmaker; /**< for match rules management */
dbus_uint32_t client_serial; /**< serial number for messages synthesized by library*/
#ifdef LIBDBUSPOLICY
- void *policy;
+ uid_t uid;
+ gid_t gid;
+ bool dbuspolicy_bus_type;
+ char *label;
#endif
};
/**
- * Creates unique name string frong unique id.
+ * Creates unique name string from unique id.
*
* @param id unique id
* @returns allocated string with unique name
@@ -651,27 +656,26 @@ static int
can_send (DBusTransportKdbus *transport,
DBusMessage *message)
{
+ int ret = DBUSPOLICY_RESULT_ALLOW;
+ dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message);
- int ret = DBUSPOLICY_RESULT_ALLOW;
- if (NULL != transport->policy)
- {
- dbus_uint32_t reply_serial = dbus_message_get_reply_serial (message);
-
- /* If reply_serial is non-zero, then it is a reply - just send it.
- * Otherwise - check the policy.
- */
- if (0 == reply_serial)
- ret = dbuspolicy1_check_out (transport->policy,
- dbus_message_get_destination (message),
- dbus_message_get_sender (message),
- dbus_message_get_path (message),
- dbus_message_get_interface (message),
- dbus_message_get_member (message),
- dbus_message_get_type (message),
- dbus_message_get_error_name (message),
- reply_serial,
- !dbus_message_get_no_reply (message));
- }
+ /* If reply_serial is non-zero, then it is a reply - just send it.
+ * Otherwise - check the policy.
+ */
+ if (0 == reply_serial)
+ ret = dbuspolicy1_check_out (transport->dbuspolicy_bus_type,
+ transport->uid,
+ transport->gid,
+ transport->label,
+ dbus_message_get_destination (message),
+ dbus_message_get_sender (message),
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message),
+ dbus_message_get_type (message),
+ dbus_message_get_error_name (message),
+ reply_serial,
+ !dbus_message_get_no_reply (message));
return ret;
}
@@ -1222,8 +1226,7 @@ can_own (DBusTransportKdbus *transport,
dbus_bool_t result = TRUE;
#ifdef LIBDBUSPOLICY
- if (NULL != transport->policy)
- result = (dbuspolicy1_can_own (transport->policy, name) == 1);
+ result = (dbuspolicy1_can_own (transport->dbuspolicy_bus_type, transport->uid, transport->gid, transport->label, name) == DBUSPOLICY_RESULT_ALLOW);
#endif
return result;
@@ -1666,6 +1669,12 @@ add_match_kdbus (DBusTransportKdbus *transport,
return TRUE;
}
+static char *getlabel() {
+ char *l;
+ ssize_t r = smack_new_label_from_self(&l);
+ return r<0 ? NULL : l;
+}
+
static DBusMessage *
capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport,
DBusMessage *message,
@@ -1681,6 +1690,13 @@ capture_org_freedesktop_DBus_Hello (DBusTransportKdbus *transport,
if (!bus_register_kdbus (transport, registration_flags, error))
goto out;
+#ifdef LIBDBUSPOLICY
+ transport->uid = getuid();
+ transport->gid = getgid();
+ if (!(transport->label = getlabel()))
+ goto out;
+#endif
+
return reply_1_data (message, DBUS_TYPE_STRING, &transport->my_DBus_unique_name);
out:
@@ -2364,6 +2380,64 @@ struct CaptureHandlers {
CaptureHandler handler;
};
+static dbus_bool_t kdbus_update_credentials(DBusTransport *transport, DBusError *error)
+{
+ DBusTransportKdbus *kdbus_transport = (DBusTransportKdbus*) transport;
+ int fd = _kdbus_get_fd(kdbus_transport->kdbus);
+ int ret;
+ char *label;
+
+ if (!(label = getlabel()))
+ {
+ dbus_set_error(error, DBUS_ERROR_FAILED, "Failed to get seclabel");
+ return FALSE;
+ }
+
+ do
+ ret = ioctl(fd, KDBUS_CMD_UPDATE_METADATA);
+ while (ret<0 && EINTR == (ret = errno));
+ if (ret<0)
+ {
+ dbus_set_error(error, _dbus_error_from_errno(ret), NULL);
+ free(label);
+ return FALSE;
+ }
+
+ free(kdbus_transport->label);
+ kdbus_transport->label = label;
+ kdbus_transport->uid = getuid();
+ kdbus_transport->gid = getgid();
+
+ return TRUE;
+}
+
+static DBusMessage *
+capture_org_freedesktop_DBus_UpdateCredentials (DBusTransportKdbus *transport,
+ DBusMessage *message,
+ DBusError *error)
+{
+ DBusMessage *reply;
+ if (dbus_message_has_signature (message, ""))
+ {
+ dbus_set_error(error, DBUS_ERROR_FAILED, "UpdateCredentials with nonempty signature");
+ return NULL;
+ }
+
+
+ if (!kdbus_update_credentials ((DBusTransport*)transport, error))
+ return NULL;
+
+ if ((reply = dbus_message_new_method_return (message)))
+ if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
+ {
+ dbus_message_unref(reply);
+ reply = NULL;
+ }
+ if (!reply)
+ dbus_set_error(error, _dbus_error_from_errno(ENOMEM), NULL);
+ return reply;
+}
+
#define HANDLER_ELEMENT(x) {#x, capture_org_freedesktop_DBus_##x}
/* This is to cut the code to parts, and keep it organized:
@@ -2391,7 +2465,8 @@ static struct CaptureHandlers capture_handlers[] =
HANDLER_ELEMENT (NameHasOwner),
HANDLER_ELEMENT (ReloadConfig),
HANDLER_ELEMENT (StartServiceByName),
- HANDLER_ELEMENT (UpdateActivationEnvironment)
+ HANDLER_ELEMENT (UpdateActivationEnvironment),
+ HANDLER_ELEMENT (UpdateCredentials)
};
/**
@@ -2804,132 +2879,132 @@ can_receive (DBusTransportKdbus *transport,
dbus_bool_t result = TRUE;
#ifdef LIBDBUSPOLICY
- if (transport->policy)
- {
- DBusHeader header;
- dbus_bool_t got_header = FALSE;
- dbus_bool_t got_creds = FALSE;
- dbus_bool_t got_seclabel = FALSE;
+ DBusHeader header;
+ dbus_bool_t got_header = FALSE;
+ dbus_bool_t got_creds = FALSE;
+ dbus_bool_t got_seclabel = FALSE;
- if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
- {
- const struct kdbus_item *item;
- uid_t sender_euid = -1;
- gid_t sender_egid = -1;
- const char *seclabel = NULL;
- DBusString names;
+ if (KDBUS_PAYLOAD_DBUS == msg->payload_type)
+ {
+ const struct kdbus_item *item;
+ uid_t sender_euid = -1;
+ gid_t sender_egid = -1;
+ const char *seclabel = NULL;
+ DBusString names;
- result = FALSE;
+ result = FALSE;
- _dbus_string_init (&names);
+ _dbus_string_init (&names);
- KDBUS_ITEM_FOREACH(item, msg, items)
- switch (item->type)
- {
- case KDBUS_ITEM_CREDS:
- sender_euid = (uid_t) item->creds.euid;
- sender_egid = (gid_t) item->creds.egid;
- got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
- break;
- case KDBUS_ITEM_SECLABEL:
- seclabel = item->str;
- got_seclabel = (seclabel != NULL);
- break;
- case KDBUS_ITEM_OWNED_NAME:
- {
- DBusString name;
- _dbus_string_init_const (&name, item->name.name);
- if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
- {
- if (_dbus_string_get_length (&names) != 0)
- _dbus_string_append_byte (&names, ' ');
-
- _dbus_string_copy (&name,
- 0,
- &names,
- _dbus_string_get_length (&names));
- }
- }
- break;
- default:
- break; /* ignore all other items */
- }
-
- if (NULL != message_data && message_len > 0)
+ KDBUS_ITEM_FOREACH(item, msg, items)
+ switch (item->type)
{
- if (load_dbus_header (transport, &header, message_data, message_len))
- got_header = TRUE;
+ case KDBUS_ITEM_CREDS:
+ sender_euid = (uid_t) item->creds.euid;
+ sender_egid = (gid_t) item->creds.egid;
+ got_creds = (sender_euid != (uid_t)-1) && (sender_egid != (gid_t)-1);
+ break;
+ case KDBUS_ITEM_SECLABEL:
+ seclabel = item->str;
+ got_seclabel = (seclabel != NULL);
+ break;
+ case KDBUS_ITEM_OWNED_NAME:
+ {
+ DBusString name;
+ _dbus_string_init_const (&name, item->name.name);
+ if (_dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))
+ {
+ if (_dbus_string_get_length (&names) != 0)
+ _dbus_string_append_byte (&names, ' ');
+
+ _dbus_string_copy (&name,
+ 0,
+ &names,
+ _dbus_string_get_length (&names));
+ }
+ }
+ break;
+ default:
+ break; /* ignore all other items */
}
- if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL)
- {
- result = TRUE;
- }
- else if (got_header && got_creds && got_seclabel)
- {
- const char *destination = NULL;
- const char *path = NULL;
- const char *interface = NULL;
- const char *member = NULL;
- const char *error_name = NULL;
- dbus_uint64_t reply_cookie = 0;
- dbus_bool_t requested_reply = FALSE;
- int ret;
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_DESTINATION,
- DBUS_TYPE_STRING,
- &destination);
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_PATH,
- DBUS_TYPE_STRING,
- &path);
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_INTERFACE,
- DBUS_TYPE_STRING,
- &interface);
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_MEMBER,
- DBUS_TYPE_STRING,
- &member);
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_ERROR_NAME,
- DBUS_TYPE_STRING,
- &error_name);
-
- _dbus_header_get_field_basic (&header,
- DBUS_HEADER_FIELD_REPLY_SERIAL,
- DBUS_TYPE_UINT64,
- &reply_cookie);
-
- requested_reply = !(_dbus_header_get_flag (&header,
- DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
-
- ret = dbuspolicy1_check_in (transport->policy,
- destination,
- _dbus_string_get_length (&names) > 0 ?
- _dbus_string_get_const_data (&names) :
- NULL,
- seclabel,
- sender_euid,
- sender_egid,
- path,
- interface,
- member,
- _dbus_header_get_message_type (&header),
- error_name,
- reply_cookie,
- requested_reply);
- result = (1 == ret);
- }
+ if (NULL != message_data && message_len > 0)
+ {
+ if (load_dbus_header (transport, &header, message_data, message_len))
+ got_header = TRUE;
+ }
- _dbus_string_free (&names);
- }
- }
+ if (got_header && _dbus_header_get_message_type (&header) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+ {
+ result = TRUE;
+ }
+ else if (got_header && got_creds && got_seclabel)
+ {
+ const char *destination = NULL;
+ const char *path = NULL;
+ const char *interface = NULL;
+ const char *member = NULL;
+ const char *error_name = NULL;
+ dbus_uint64_t reply_cookie = 0;
+ dbus_bool_t requested_reply = FALSE;
+ int ret;
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_DESTINATION,
+ DBUS_TYPE_STRING,
+ &destination);
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_PATH,
+ DBUS_TYPE_STRING,
+ &path);
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_INTERFACE,
+ DBUS_TYPE_STRING,
+ &interface);
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_MEMBER,
+ DBUS_TYPE_STRING,
+ &member);
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ DBUS_TYPE_STRING,
+ &error_name);
+
+ _dbus_header_get_field_basic (&header,
+ DBUS_HEADER_FIELD_REPLY_SERIAL,
+ DBUS_TYPE_UINT64,
+ &reply_cookie);
+
+ requested_reply = !(_dbus_header_get_flag (&header,
+ DBUS_HEADER_FLAG_NO_REPLY_EXPECTED));
+
+ ret = dbuspolicy1_check_in (transport->dbuspolicy_bus_type,
+ transport->uid,
+ transport->gid,
+ transport->label,
+ destination,
+ _dbus_string_get_length (&names) > 0 ?
+ _dbus_string_get_const_data (&names) :
+ NULL,
+ seclabel,
+ sender_euid,
+ sender_egid,
+ path,
+ interface,
+ member,
+ _dbus_header_get_message_type (&header),
+ error_name,
+ reply_cookie,
+ requested_reply);
+ result = (DBUSPOLICY_RESULT_ALLOW == ret);
+ }
+
+ _dbus_string_free (&names);
+ }
#endif
return result;
@@ -3439,15 +3514,6 @@ free_watches (DBusTransportKdbus *kdbus_transport)
_dbus_verbose ("end\n");
}
-static void
-free_policies (DBusTransportKdbus *transport)
-{
-#ifdef LIBDBUSPOLICY
- if (NULL != transport->policy)
- dbuspolicy1_free (transport->policy);
-#endif
-}
-
/**
* Copy-paste from socket transport. Only done needed renames and removed
* lines related to encoded messages.
@@ -3469,11 +3535,13 @@ transport_finalize (DBusTransport *transport)
dbus_free (kdbus_transport->activator);
- free_policies ( kdbus_transport );
-
_kdbus_free (kdbus_transport->kdbus);
free (kdbus_transport->my_DBus_unique_name);
+#ifdef LIBDBUSPOLICY
+ free (kdbus_transport->label);
+#endif
+
dbus_free (transport);
}
@@ -4247,9 +4315,11 @@ initialize_policies (DBusTransportKdbus *transport, const char *path)
dbus_bool_t result = TRUE;
#ifdef LIBDBUSPOLICY
- transport->policy = dbuspolicy1_init (path);
- if (NULL == transport->policy)
+ int bus_type = dbuspolicy1_init (path);
+ if (0 > bus_type)
result = FALSE;
+ else
+ transport->dbuspolicy_bus_type = bus_type;
#endif
return result;
diff --git a/dbus/kdbus.h b/dbus/kdbus.h
index 4fc44cb1..778bccb2 100644
--- a/dbus/kdbus.h
+++ b/dbus/kdbus.h
@@ -979,6 +979,9 @@ enum kdbus_ioctl_type {
struct kdbus_cmd_match),
KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOCTL_MAGIC, 0xb1,
struct kdbus_cmd_match),
+
+ /* Tizen */
+ KDBUS_CMD_UPDATE_METADATA = _IO(KDBUS_IOCTL_MAGIC, 0xd0),
};
#endif /* _UAPI_KDBUS_H_ */