From 86e1dec506cb5425f3df5947f3e72461a82d3ffc Mon Sep 17 00:00:00 2001 From: Krzysztof Konopko Date: Sun, 17 Mar 2013 23:13:37 +0000 Subject: [PATCH] Required plumbing for reading process credentials from procfs --- bus/bus.c | 5 +++-- bus/bus.h | 3 ++- bus/connection.c | 23 +++++++++++++++++++---- bus/policy.c | 6 ++++-- bus/policy.h | 3 ++- dbus/dbus-auth.c | 3 ++- dbus/dbus-connection.c | 27 +++++++++++++++++++++++++++ dbus/dbus-connection.h | 3 +++ dbus/dbus-sysdeps-unix.c | 19 +++++++++++++++++++ dbus/dbus-sysdeps-util-unix.c | 9 +++++++++ dbus/dbus-sysdeps-util-win.c | 8 +++++++- dbus/dbus-sysdeps-win.c | 7 +++++++ dbus/dbus-sysdeps.h | 5 +++++ 13 files changed, 109 insertions(+), 12 deletions(-) diff --git a/bus/bus.c b/bus/bus.c index e80e708..b1bf893 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -1177,10 +1177,11 @@ bus_context_get_loop (BusContext *context) dbus_bool_t bus_context_allow_unix_user (BusContext *context, - unsigned long uid) + unsigned long uid, + unsigned long pid) { return bus_policy_allow_unix_user (context->policy, - uid); + uid, pid); } /* For now this is never actually called because the default diff --git a/bus/bus.h b/bus/bus.h index 3597884..ba23c0e 100644 --- a/bus/bus.h +++ b/bus/bus.h @@ -96,7 +96,8 @@ BusActivation* bus_context_get_activation (BusContext BusMatchmaker* bus_context_get_matchmaker (BusContext *context); DBusLoop* bus_context_get_loop (BusContext *context); dbus_bool_t bus_context_allow_unix_user (BusContext *context, - unsigned long uid); + unsigned long uid, + unsigned long pid); dbus_bool_t bus_context_allow_windows_user (BusContext *context, const char *windows_sid); BusPolicy* bus_context_get_policy (BusContext *context); diff --git a/bus/connection.c b/bus/connection.c index d69758c..869da8f 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -374,12 +374,19 @@ allow_unix_user_function (DBusConnection *connection, void *data) { BusConnectionData *d; - + unsigned long pid; + d = BUS_CONNECTION_DATA (connection); _dbus_assert (d != NULL); - - return bus_context_allow_unix_user (d->connections->context, uid); + + /* In theory PID might be unset here but it's optional anyway + * and it should fall back to the lookup based on UID. + */ + (void)dbus_connection_get_unix_process_id_unauth (connection, &pid); + return bus_context_allow_unix_user (d->connections->context, + uid, + pid); } static void @@ -840,11 +847,19 @@ bus_connection_get_unix_groups (DBusConnection *connection, DBusError *error) { unsigned long uid; + unsigned long pid; *groups = NULL; *n_groups = 0; - if (dbus_connection_get_unix_user (connection, &uid)) + if (dbus_connection_get_unix_process_id (connection, &pid) && + _dbus_unix_groups_from_pid (pid, groups, n_groups)) + { + _dbus_verbose ("Got %d groups for PID %lu\n", + *n_groups, pid); + return TRUE; + } + else if (dbus_connection_get_unix_user (connection, &uid)) { if (!_dbus_unix_groups_from_uid (uid, groups, n_groups)) { diff --git a/bus/policy.c b/bus/policy.c index 379cea9..d1b39be 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -435,14 +435,16 @@ list_allows_user (dbus_bool_t def, dbus_bool_t bus_policy_allow_unix_user (BusPolicy *policy, - unsigned long uid) + unsigned long uid, + unsigned long pid) { dbus_bool_t allowed; unsigned long *group_ids; int n_group_ids; /* On OOM or error we always reject the user */ - if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids)) + if (!_dbus_unix_groups_from_pid (pid, &group_ids, &n_group_ids) && + !_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids)) { _dbus_verbose ("Did not get any groups for UID %lu\n", uid); diff --git a/bus/policy.h b/bus/policy.h index 3ff6f48..c7b78d3 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -117,7 +117,8 @@ BusClientPolicy* bus_policy_create_client_policy (BusPolicy *policy, DBusConnection *connection, DBusError *error); dbus_bool_t bus_policy_allow_unix_user (BusPolicy *policy, - unsigned long uid); + unsigned long uid, + unsigned long pid); dbus_bool_t bus_policy_allow_windows_user (BusPolicy *policy, const char *windows_sid); dbus_bool_t bus_policy_append_default_rule (BusPolicy *policy, diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c index d2c37a7..f3782ab 100644 --- a/dbus/dbus-auth.c +++ b/dbus/dbus-auth.c @@ -1075,7 +1075,8 @@ handle_server_data_external_mech (DBusAuth *auth, return FALSE; /* OOM */ } } - else + else if (!_dbus_credentials_add_from_uid (auth->desired_identity, + &auth->identity)) { if (!_dbus_credentials_add_from_user (auth->desired_identity, &auth->identity)) diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index ee33b6c..bd662aa 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -5199,6 +5199,33 @@ dbus_connection_get_unix_process_id (DBusConnection *connection, } /** + * Gets the process ID of the connection if any. + * Returns #TRUE if the pid is filled in. + * + * @param connection the connection + * @param pid return location for the process ID + * @returns #TRUE if uid is filled in with a valid process ID + */ +dbus_bool_t +dbus_connection_get_unix_process_id_unauth (DBusConnection *connection, + unsigned long *pid) +{ + dbus_bool_t result; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (pid != NULL, FALSE); + + CONNECTION_LOCK (connection); + + result = _dbus_transport_get_unix_process_id (connection->transport, + pid); + + CONNECTION_UNLOCK (connection); + + return result; +} + +/** * Gets the ADT audit data of the connection if any. * Returns #TRUE if the structure pointer is returned. * Always returns #FALSE prior to authenticating the diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index fe4d04e..127bc0c 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -265,6 +265,9 @@ DBUS_EXPORT dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection, unsigned long *pid); DBUS_EXPORT +dbus_bool_t dbus_connection_get_unix_process_id_unauth (DBusConnection *connection, + unsigned long *pid); +DBUS_EXPORT dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection, void **data, dbus_int32_t *data_size); diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 30606ff..1fae085 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2300,6 +2300,25 @@ _dbus_user_info_fill_uid (DBusUserInfo *info, NULL, error); } +dbus_bool_t +_dbus_credentials_add_from_uid (DBusCredentials *credentials, + const DBusString *uid) +{ + unsigned long n; + + if (!_dbus_is_a_number (uid, &n)) + { + return FALSE; + } + + if (!_dbus_credentials_add_unix_uid (credentials, n)) + { + return FALSE; + } + + return TRUE; +} + /** * Adds the credentials of the current process to the * passed-in credentials object. diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 81098ca..8f50596 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -981,6 +981,15 @@ _dbus_unix_groups_from_uid (dbus_uid_t uid, return _dbus_groups_from_uid (uid, group_ids, n_group_ids); } +dbus_bool_t +_dbus_unix_groups_from_pid (dbus_pid_t pid, + dbus_gid_t **group_ids, + int *n_group_ids) +{ + /* TODO: Implement this function */ + return FALSE; +} + /** * Checks to see if the UNIX user ID is at the console. * Should always fail on Windows (set the error to diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index 111db9e..471c001 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -846,7 +846,13 @@ _dbus_unix_groups_from_uid (dbus_uid_t uid, return FALSE; } - +dbus_bool_t +_dbus_unix_groups_from_pid (dbus_pid_t pid, + dbus_gid_t **group_ids, + int *n_group_ids) +{ + return FALSE; +} /** @} */ /* DBusString stuff */ diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index ce60d29..275fe1b 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -1777,6 +1777,13 @@ _dbus_credentials_add_from_user (DBusCredentials *credentials, _dbus_string_get_const_data(username)); } +dbus_bool_t +_dbus_credentials_add_from_uid (DBusCredentials *credentials, + const DBusString *uid) +{ + return FALSE; +} + /** * Adds the credentials of the current process to the * passed-in credentials object. diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index f4b0ac9..285ec47 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -192,6 +192,8 @@ dbus_bool_t _dbus_send_credentials_socket (int server_fd, dbus_bool_t _dbus_credentials_add_from_user (DBusCredentials *credentials, const DBusString *username); +dbus_bool_t _dbus_credentials_add_from_uid (DBusCredentials *credentials, + const DBusString *uid); dbus_bool_t _dbus_credentials_add_from_current_process (DBusCredentials *credentials); dbus_bool_t _dbus_append_user_from_current_process (DBusString *str); @@ -202,6 +204,9 @@ dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname, dbus_bool_t _dbus_unix_groups_from_uid (dbus_uid_t uid, dbus_gid_t **group_ids, int *n_group_ids); +dbus_bool_t _dbus_unix_groups_from_pid (dbus_pid_t pid, + dbus_gid_t **group_ids, + int *n_group_ids); dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid, DBusError *error); dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid); -- 1.8.1.4