diff options
author | David Zeuthen <david@fubar.dk> | 2006-06-05 23:39:00 +0000 |
---|---|---|
committer | David Zeuthen <david@fubar.dk> | 2006-06-05 23:39:00 +0000 |
commit | 1c3d5691ad444ae2849d079e3745d6b476614623 (patch) | |
tree | 0692c2f1eb10b1ea952449d09782cccb826588a6 /polkitd | |
parent | 12d20fc8a71b59584f5636ac4dc85c36e45c0157 (diff) | |
download | polkit-1c3d5691ad444ae2849d079e3745d6b476614623.tar.gz |
Lots of changes! Almost ready for 0.2 release.
Diffstat (limited to 'polkitd')
-rwxr-xr-x | polkitd/PolicyKit.in | 10 | ||||
-rw-r--r-- | polkitd/main.c | 102 | ||||
-rw-r--r-- | polkitd/policy.c | 480 | ||||
-rw-r--r-- | polkitd/policy.h | 97 | ||||
-rw-r--r-- | polkitd/polkit-manager.c | 375 | ||||
-rw-r--r-- | polkitd/polkit-manager.h | 11 | ||||
-rw-r--r-- | polkitd/polkit-session.c | 61 | ||||
-rw-r--r-- | polkitd/polkit-session.h | 7 |
8 files changed, 994 insertions, 149 deletions
diff --git a/polkitd/PolicyKit.in b/polkitd/PolicyKit.in index 104386b..023fd7f 100755 --- a/polkitd/PolicyKit.in +++ b/polkitd/PolicyKit.in @@ -23,6 +23,13 @@ servicename=PolicyKit RETVAL=0 +cleanup_state_dir() +{ + # Clean out all files in + rm -f @LOCALSTATEDIR@/run/polkit-console/* + mkdir -p @LOCALSTATEDIR@/run/polkit-console +} + start() { echo -n $"Starting PolicyKit daemon: " daemon --check $servicename $processname @@ -46,6 +53,7 @@ stop() { # See how we were called. case "$1" in start) + cleanup_state_dir start ;; stop) @@ -57,13 +65,11 @@ case "$1" in ;; restart) stop - sleep 3 start ;; condrestart) if [ -f @LOCALSTATEDIR@/lock/subsys/$servicename ]; then stop - sleep 3 start fi ;; diff --git a/polkitd/main.c b/polkitd/main.c index f996540..8286670 100644 --- a/polkitd/main.c +++ b/polkitd/main.c @@ -33,6 +33,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <signal.h> #include <dbus/dbus-glib.h> @@ -69,18 +70,61 @@ delete_pid (void) unlink (POLKITD_PID_FILE); } +static int sigusr1_unix_signal_pipe_fds[2]; +static GIOChannel *sigusr1_iochn = NULL; +static PolicyKitManager *manager = NULL; + +static void +handle_sigusr1 (int value) +{ + ssize_t written; + static char marker[1] = {'S'}; + + written = write (sigusr1_unix_signal_pipe_fds[1], marker, 1); +} + +static gboolean +sigusr1_iochn_data (GIOChannel *source, + GIOCondition condition, + gpointer user_data) +{ + GError *err = NULL; + gchar data[1]; + gsize bytes_read; + + /* Empty the pipe */ + if (G_IO_STATUS_NORMAL != + g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) { + g_warning ("Error emptying sigusr1 pipe: %s", err->message); + g_error_free (err); + goto out; + } + + g_debug ("Caught SIGUSR1"); + if (manager != NULL) { + polkit_manager_update_desktop_console_privileges (manager); + } + +out: + return TRUE; +} + + int main (int argc, char *argv[]) { DBusGConnection *bus; DBusGProxy *bus_proxy; GError *error = NULL; - PolicyKitManager *manager; GMainLoop *mainloop; guint request_name_result; int ret; gboolean no_daemon = FALSE; gboolean is_verbose = FALSE; + int pf; + ssize_t written; + char pid[9]; + guint sigusr1_iochn_listener_source_id; static const struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"no-daemon", no_argument, NULL, 'n'}, @@ -131,10 +175,6 @@ main (int argc, char *argv[]) if (!no_daemon) { int child_pid; int dev_null_fd; - int pf; - ssize_t written; - char pid[9]; - if (chdir ("/") < 0) { g_warning ("Could not chdir to /: %s", strerror (errno)); @@ -170,21 +210,21 @@ main (int argc, char *argv[]) /* create session */ setsid (); - - /* remove old pid file */ - unlink (POLKITD_PID_FILE); - - /* make a new pid file */ - if ((pf = open (POLKITD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) { - snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ()); - written = write (pf, pid, strlen(pid)); - close (pf); - g_atexit (delete_pid); - } } else { g_debug (("not becoming a daemon")); } + /* remove old pid file */ + unlink (POLKITD_PID_FILE); + + /* make a new pid file */ + if ((pf = open (POLKITD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) { + snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ()); + written = write (pf, pid, strlen(pid)); + close (pf); + g_atexit (delete_pid); + } + g_type_init (); dbus_g_object_type_install_info (POLKIT_TYPE_MANAGER, &dbus_glib_polkit_manager_object_info); @@ -194,6 +234,30 @@ main (int argc, char *argv[]) mainloop = g_main_loop_new (NULL, FALSE); + /* Listen for SIGUSR1 - UNIX signal handlers are evil though, + * so set up a pipe to transmit the signal. + */ + + /* create pipe */ + if (pipe (sigusr1_unix_signal_pipe_fds) != 0) { + g_warning ("Could not setup pipe, errno=%d", errno); + goto out; + } + + /* setup glib handler - 0 is for reading, 1 is for writing */ + sigusr1_iochn = g_io_channel_unix_new (sigusr1_unix_signal_pipe_fds[0]); + if (sigusr1_iochn == NULL) { + g_warning ("Could not create GIOChannel"); + goto out; + } + + /* get callback when there is data to read */ + sigusr1_iochn_listener_source_id = g_io_add_watch ( + sigusr1_iochn, G_IO_IN, sigusr1_iochn_data, NULL); + + /* setup UNIX signal handler for SIGUSR1 */ + signal (SIGUSR1, handle_sigusr1); + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (bus == NULL) { g_warning ("Couldn't connect to system bus: %s", error->message); @@ -222,9 +286,15 @@ main (int argc, char *argv[]) manager = polkit_manager_new (bus, bus_proxy); + if (manager == NULL) { + g_warning ("Could not construct manager object; bailing out"); + goto out; + } g_debug ("service running"); + polkit_manager_update_desktop_console_privileges (manager); + g_main_loop_run (mainloop); ret = 0; diff --git a/polkitd/policy.c b/polkitd/policy.c index 95032ec..32c8f78 100644 --- a/polkitd/policy.c +++ b/polkitd/policy.c @@ -171,7 +171,7 @@ txt_backend_read_policy (const char *policy, goto out; } - value = g_key_file_get_string (keyfile, "Policy", key, &error); + value = g_key_file_get_string (keyfile, "Privilege", key, &error); if (value == NULL) { g_warning ("Cannot get key '%s' in group 'Policy' in file '%s': %s", key, path, error->message); g_error_free (error); @@ -295,6 +295,115 @@ out: return rc; } + +static PolicyResult +txt_backend_read_list (const char *policy, + const char *key, + GList **result) +{ + int i; + GKeyFile *keyfile; + GError *error; + PolicyResult rc; + char *path; + char *value = NULL; + char **tokens = NULL; + GList *res; + char *token; + + error = NULL; + rc = POLICY_RESULT_ERROR; + res = NULL; + *result = NULL; + + keyfile = g_key_file_new (); + path = g_strdup_printf ("%s/%s.privilege", policy_directory, policy); + /*g_message ("Loading %s", path);*/ + if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &error)) { + g_warning ("Couldn't open key-file '%s': %s", path, error->message); + g_error_free (error); + rc = POLICY_RESULT_NO_SUCH_POLICY; + goto out; + } + + value = g_key_file_get_string (keyfile, "Privilege", key, &error); + if (value == NULL) { + g_warning ("Cannot get key '%s' in group 'Policy' in file '%s': %s", key, path, error->message); + g_error_free (error); + rc = POLICY_RESULT_ERROR; + goto out; + } + + /*g_message ("value = '%s'", value);*/ + tokens = g_strsplit (value, " ", 0); + for (i = 0; tokens[i] != NULL; i++) { + token = tokens[i]; + /*g_message (" token = '%s'", token);*/ + + res = g_list_append (res, g_strdup (token)); + } + + *result = res; + rc = POLICY_RESULT_OK; + +out: + g_strfreev (tokens); + g_free (value); + + g_key_file_free (keyfile); + g_free (path); + + return rc; +} + +static PolicyResult +txt_backend_read_word (const char *policy, + const char *key, + char **result) +{ + GKeyFile *keyfile; + GError *error; + PolicyResult rc; + char *path; + char *value = NULL; + + error = NULL; + rc = POLICY_RESULT_ERROR; + *result = NULL; + + keyfile = g_key_file_new (); + path = g_strdup_printf ("%s/%s.privilege", policy_directory, policy); + /*g_message ("Loading %s", path);*/ + if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &error)) { + g_warning ("Couldn't open key-file '%s': %s", path, error->message); + g_error_free (error); + rc = POLICY_RESULT_NO_SUCH_POLICY; + goto out; + } + + value = g_key_file_get_string (keyfile, "Privilege", key, &error); + if (value == NULL) { + g_warning ("Cannot get key '%s' in group 'Policy' in file '%s': %s", key, path, error->message); + g_error_free (error); + rc = POLICY_RESULT_ERROR; + goto out; + } + + /*g_message ("value = '%s'", value);*/ + + *result = g_strdup (value); + + rc = POLICY_RESULT_OK; + +out: + g_free (value); + + g_key_file_free (keyfile); + g_free (path); + + return rc; +} + static PolicyResult policy_get_whitelist (const char *policy, GList **result) @@ -309,6 +418,20 @@ policy_get_blacklist (const char *policy, return txt_backend_read_policy (policy, "Deny", result); } +static PolicyResult +policy_get_sufficient_privileges (const char *policy, + GList **result) +{ + return txt_backend_read_list (policy, "SufficientPrivileges", result); +} + +static PolicyResult +policy_get_required_privileges (const char *policy, + GList **result) +{ + return txt_backend_read_list (policy, "RequiredPrivileges", result); +} + /** Return all elements in the white-list for a policy * * @param result On success set to a list of dynamically allocated strings. @@ -352,6 +475,177 @@ error: return POLICY_RESULT_ERROR; } +PolicyResult +policy_get_auth_details_for_policy (uid_t uid, + const char *policy, + const char *resource, + gboolean *out_auth_can_obtain, + gboolean *out_auth_can_obtain_is_temporary, + gboolean *out_auth_can_grant, + gboolean *out_auth_obtain_requires_root, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege) +{ + PolicyResult res; + GList *required_privs; + GList *l; + char *can_obtain_word; + char *can_grant_word; + char *obtain_requires_root_word; + + required_privs = NULL; + can_obtain_word = NULL; + can_grant_word = NULL; + + *out_auth_can_obtain = FALSE; + *out_auth_can_obtain_is_temporary = FALSE; + *out_auth_can_grant = FALSE; + *out_auth_obtain_requires_root = TRUE; + + res = POLICY_RESULT_ERROR; + + res = txt_backend_read_word (policy, "CanObtain", &can_obtain_word); + if (res != POLICY_RESULT_OK) + goto out; + + res = txt_backend_read_word (policy, "CanGrant", &can_grant_word); + if (res != POLICY_RESULT_OK) + goto out; + + res = txt_backend_read_word (policy, "ObtainRequireRoot", &obtain_requires_root_word); + if (res != POLICY_RESULT_OK) + goto out; + + if (strcmp (can_obtain_word, "True") == 0) { + *out_auth_can_obtain = TRUE; + *out_auth_can_obtain_is_temporary = FALSE; + } else if (strcmp (can_obtain_word, "False") == 0) { + *out_auth_can_obtain = FALSE; + *out_auth_can_obtain_is_temporary = FALSE; + } else if (strcmp (can_obtain_word, "Temporary") == 0) { + *out_auth_can_obtain = TRUE; + *out_auth_can_obtain_is_temporary = TRUE; + } else { + g_critical ("CanObtain has bogus value '%s' in privilege '%s'", + can_obtain_word, policy); + goto out; + } + + if (strcmp (can_grant_word, "True") == 0) { + *out_auth_can_grant = TRUE; + } else if (strcmp (can_grant_word, "False") == 0) { + *out_auth_can_grant = FALSE; + } else { + g_critical ("CanGrant has bogus value '%s' in privilege '%s'", + can_grant_word, policy); + goto out; + } + + if (strcmp (obtain_requires_root_word, "True") == 0) { + *out_auth_obtain_requires_root = TRUE; + } else if (strcmp (obtain_requires_root_word, "False") == 0) { + *out_auth_obtain_requires_root = FALSE; + } else { + g_critical ("ObtainRequireRoot has bogus value '%s' in privilege '%s'", + obtain_requires_root_word, policy); + goto out; + } + + /* no need to check RequiredPrivileges if said privilege says we can't obtain it */ + if ((*out_auth_can_obtain) == FALSE) + goto determined; + + /* if privilege already requires super user, no need to check RequiredPrivileges */ + if ((*out_auth_obtain_requires_root) == TRUE) + goto determined; + + /* So now the user can obtain the privilege and doesn't + * require root. However, per the spec, if he is lacking any + * of the privileges listed and one or more of these have + * + * - has ObtainRequiresRoot set to TRUE; or + * + * - has CanObtain set to FALSE + * + * then effectively ObtainsRequireRoot becomes TRUE. + */ + + res = policy_get_required_privileges (policy, &required_privs); + if (res != POLICY_RESULT_OK) + goto out; + + g_message (" * obtain_requires_root = %d", *out_auth_obtain_requires_root); + + for (l = required_privs; l != NULL; l = g_list_next (l)) { + gboolean has_required_privilege = FALSE; + gboolean has_required_privilege_is_temp = FALSE; + char *has_required_privilege_is_restricted = NULL; + const char *required_privilege = (const char *) l->data; + PolicyResult res2; + + g_message (" checking for required privilege '%s'", required_privilege); + + has_required_privilege = FALSE; + res2 = policy_is_uid_allowed_for_policy (uid, + required_privilege, + NULL, + &has_required_privilege, + &has_required_privilege_is_temp, + &has_required_privilege_is_restricted, + have_temp_privilege_userdata, + have_temp_privilege); + if (res2 != POLICY_RESULT_OK) + goto out; + + g_message (" has_required_privilege = %d", has_required_privilege); + + if (!has_required_privilege || + (has_required_privilege && has_required_privilege_is_restricted != NULL)) { + + g_free (can_obtain_word); + g_free (can_grant_word); + can_obtain_word = NULL; + can_grant_word = NULL; + + res = txt_backend_read_word (required_privilege, "CanObtain", + &can_obtain_word); + if (res != POLICY_RESULT_OK) + goto out; + + res = txt_backend_read_word (required_privilege, "ObtainRequireRoot", + &obtain_requires_root_word); + if (res != POLICY_RESULT_OK) + goto out; + + if (strcmp (can_obtain_word, "False") == 0) { + *out_auth_obtain_requires_root = TRUE; + goto determined; + } + + if (strcmp (obtain_requires_root_word, "True") == 0) { + *out_auth_obtain_requires_root = TRUE; + goto determined; + } + } + } + +determined: + g_message (" ** obtain_requires_root = %d", *out_auth_obtain_requires_root); + res = POLICY_RESULT_OK; + +out: + if (required_privs != NULL) { + g_list_foreach (required_privs, (GFunc) g_free, NULL); + g_list_free (required_privs); + } + + g_free (can_obtain_word); + g_free (can_grant_word); + + return res; +} + + static void afp_process_elem(PolicyElement *elem, gboolean *flag, uid_t uid, guint num_gids, gid_t *gid_list) @@ -467,25 +761,143 @@ out: return res; } -PolicyResult -policy_is_uid_gid_allowed_for_policy (uid_t uid, - guint num_gids, - gid_t *gid_list, - const char *policy, - const char *resource, - gboolean *result) +static PolicyResult +_policy_is_uid_gid_allowed_for_policy (uid_t uid, + guint num_gids, + gid_t *gid_list, + const char *policy, + const char *resource, + gboolean *out_is_privileged, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege, + int recursion_counter) { gboolean is_in_whitelist; gboolean is_in_blacklist; GList *l; GList *whitelist; GList *blacklist; + GList *sufficient_privs; + GList *required_privs; PolicyResult res; + PolicyResult res2; whitelist = NULL; blacklist = NULL; + sufficient_privs = NULL; + required_privs = NULL; res = POLICY_RESULT_ERROR; + *out_is_privileged = FALSE; + *out_is_temporary = FALSE; + *out_is_privileged_but_restricted = NULL; + + if (recursion_counter > 8) { + g_critical ("Maximal (8) recursion depth detected checking privilege '%s'", policy); + goto out; + } + + res = policy_get_sufficient_privileges (policy, &sufficient_privs); + if (res != POLICY_RESULT_OK) + goto out; + + /* first check SufficientPrivileges.. if we have one of those, then return TRUE */ + for (l = sufficient_privs; l != NULL; l = g_list_next (l)) { + gboolean has_sufficient_privilege = FALSE; + gboolean has_sufficient_privilege_is_temp = FALSE; + char *has_sufficient_privilege_is_restricted = NULL; + const char *sufficient_privilege = (const char *) l->data; + + g_message (" checking for sufficient privilege '%s'", sufficient_privilege); + + has_sufficient_privilege = FALSE; + res2 = _policy_is_uid_gid_allowed_for_policy (uid, num_gids, gid_list, + sufficient_privilege, NULL, + &has_sufficient_privilege, + &has_sufficient_privilege_is_temp, + &has_sufficient_privilege_is_restricted, + have_temp_privilege_userdata, + have_temp_privilege, recursion_counter + 1); + if (res2 != POLICY_RESULT_OK) + goto out; + + if (has_sufficient_privilege && has_sufficient_privilege_is_restricted == NULL) { + g_message ("Returned TRUE because we have the sufficient privilege '%s' for privilege '%s'", + sufficient_privilege, policy); + res = POLICY_RESULT_OK; + *out_is_privileged = TRUE; + *out_is_temporary = has_sufficient_privilege_is_temp; + *out_is_privileged_but_restricted = NULL; + goto out; + } + } + + /* then check temporary privileges as it's OK to have a + * privilege temporarily without having the all the + * RequiredPrivileges. + */ + + if ((*out_is_privileged == FALSE) && have_temp_privilege != NULL) { + gboolean ignore_resource; + + if (recursion_counter == 0) + ignore_resource = FALSE; + else + ignore_resource = TRUE; + + /* TODO: ask for restriction */ + if (have_temp_privilege (uid, policy, resource, ignore_resource, have_temp_privilege_userdata)) { + + res = POLICY_RESULT_OK; + *out_is_privileged = TRUE; + *out_is_temporary = TRUE; + *out_is_privileged_but_restricted = NULL; + goto out; + } + } + + + /* now check RequiredPrivileges.. if we have don't have all of those, then return FALSE */ + + res = policy_get_required_privileges (policy, &required_privs); + if (res != POLICY_RESULT_OK) + goto out; + + for (l = required_privs; l != NULL; l = g_list_next (l)) { + gboolean has_required_privilege = FALSE; + gboolean has_required_privilege_is_temp = FALSE; + char *has_required_privilege_is_restricted = NULL; + const char *required_privilege = (const char *) l->data; + + g_message (" checking for required privilege '%s'", required_privilege); + + has_required_privilege = FALSE; + res2 = _policy_is_uid_gid_allowed_for_policy (uid, num_gids, gid_list, + required_privilege, NULL, + &has_required_privilege, + &has_required_privilege_is_temp, + &has_required_privilege_is_restricted, + have_temp_privilege_userdata, + have_temp_privilege, recursion_counter + 1); + if (res2 != POLICY_RESULT_OK) + goto out; + + if (!has_required_privilege || + (has_required_privilege && has_required_privilege_is_restricted != NULL)) { + g_message ("Returned FALSE because we don't have the required privilege '%s' for privilege '%s'", + required_privilege, policy); + res = POLICY_RESULT_OK; + *out_is_privileged = FALSE; + *out_is_temporary = TRUE; + *out_is_privileged_but_restricted = NULL; + goto out; + } + } + + /* Check against whitelist and blacklist */ + res = policy_get_whitelist (policy, &whitelist); if (res != POLICY_RESULT_OK) goto out; @@ -517,11 +929,21 @@ policy_is_uid_gid_allowed_for_policy (uid_t uid, } } - *result = is_in_whitelist && (!is_in_blacklist); + *out_is_privileged = is_in_whitelist && (!is_in_blacklist); + *out_is_temporary = FALSE; + *out_is_privileged_but_restricted = NULL; res = POLICY_RESULT_OK; out: + if (required_privs != NULL) { + g_list_foreach (required_privs, (GFunc) g_free, NULL); + g_list_free (required_privs); + } + if (sufficient_privs != NULL) { + g_list_foreach (sufficient_privs, (GFunc) g_free, NULL); + g_list_free (sufficient_privs); + } if (whitelist != NULL) policy_element_free_list (whitelist); if (blacklist != NULL) @@ -530,6 +952,28 @@ out: return res; } + +PolicyResult +policy_is_uid_gid_allowed_for_policy (uid_t uid, + guint num_gids, + gid_t *gid_list, + const char *policy, + const char *resource, + gboolean *out_is_privileged, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege) +{ + return _policy_is_uid_gid_allowed_for_policy (uid, num_gids, gid_list, policy, + resource, + out_is_privileged, + out_is_temporary, + out_is_privileged_but_restricted, + have_temp_privilege_userdata, + have_temp_privilege, 0); +} + char * policy_util_uid_to_name (uid_t uid, gid_t *default_gid) @@ -686,10 +1130,14 @@ out: } PolicyResult -policy_is_uid_allowed_for_policy (uid_t uid, - const char *policy, - const char *resource, - gboolean *result) +policy_is_uid_allowed_for_policy (uid_t uid, + const char *policy, + const char *resource, + gboolean *out_is_privileged, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege) { int num_groups = 0; gid_t *groups = NULL; @@ -715,7 +1163,11 @@ policy_is_uid_allowed_for_policy (uid_t uid, groups, policy, resource, - result); + out_is_privileged, + out_is_temporary, + out_is_privileged_but_restricted, + have_temp_privilege_userdata, + have_temp_privilege); out: g_free (username); diff --git a/polkitd/policy.h b/polkitd/policy.h index 11865ea..94a2fd3 100644 --- a/polkitd/policy.h +++ b/polkitd/policy.h @@ -35,41 +35,68 @@ typedef enum { POLICY_RESULT_NO_SUCH_POLICY } PolicyResult; -PolicyResult policy_get_policies (GList **result); - -PolicyResult policy_is_uid_allowed_for_policy (uid_t uid, - const char *policy, - const char *resource, - gboolean *result); - -PolicyResult policy_get_allowed_resources_for_policy_for_uid (uid_t uid, - const char *policy, - GList **result); - -PolicyResult policy_get_allowed_resources_for_policy_for_uid_gid (uid_t uid, - guint num_gids, - gid_t *gid_list, - const char *policy, - GList **result); - -PolicyResult policy_is_uid_gid_allowed_for_policy (uid_t uid, - guint num_gids, - gid_t *gid_list, - const char *policy, - const char *resource, - gboolean *result); - -char *policy_util_uid_to_name (uid_t uid, - gid_t *default_gid); - -char *policy_util_gid_to_name (gid_t gid); - -uid_t policy_util_name_to_uid (const char *username, - gid_t *default_gid); - -gid_t policy_util_name_to_gid (const char *groupname); - -void policy_util_set_policy_directory (const char *directory); +typedef gboolean (*HaveTempPrivCB) (uid_t user, + const char *privilege, + const char *resource, + gboolean ignore_resource, + gpointer userdata); + + +PolicyResult policy_get_policies (GList **result); + +PolicyResult policy_is_uid_allowed_for_policy (uid_t uid, + const char *policy, + const char *resource, + gboolean *out_is_privileged, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege); + + +PolicyResult policy_get_auth_details_for_policy (uid_t uid, + const char *policy, + const char *resource, + gboolean *out_auth_can_obtain, + gboolean *out_auth_can_obtain_is_temporary, + gboolean *out_auth_can_grant, + gboolean *out_auth_obtain_requires_root, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege); + + +PolicyResult policy_get_allowed_resources_for_policy_for_uid (uid_t uid, + const char *policy, + GList **result); + +PolicyResult policy_get_allowed_resources_for_policy_for_uid_gid (uid_t uid, + guint num_gids, + gid_t *gid_list, + const char *policy, + GList **result); + +PolicyResult policy_is_uid_gid_allowed_for_policy (uid_t uid, + guint num_gids, + gid_t *gid_list, + const char *policy, + const char *resource, + gboolean *out_is_privileged, + gboolean *out_is_temporary, + char **out_is_privileged_but_restricted, + gpointer have_temp_privilege_userdata, + HaveTempPrivCB have_temp_privilege); + +char *policy_util_uid_to_name (uid_t uid, + gid_t *default_gid); + +char *policy_util_gid_to_name (gid_t gid); + +uid_t policy_util_name_to_uid (const char *username, + gid_t *default_gid); + +gid_t policy_util_name_to_gid (const char *groupname); + +void policy_util_set_policy_directory (const char *directory); #endif /* POLICY_H */ diff --git a/polkitd/polkit-manager.c b/polkitd/polkit-manager.c index 52c59d9..947d333 100644 --- a/polkitd/polkit-manager.c +++ b/polkitd/polkit-manager.c @@ -38,7 +38,7 @@ typedef struct uid_t user; char *privilege; char *resource; - pid_t pid_restriction; + char *system_bus_unique_name; /* whether the tmp priv is restricted to e.g. :1.43 */ } TemporaryPrivilege; struct PolicyKitManagerPrivate @@ -58,6 +58,26 @@ G_DEFINE_TYPE(PolicyKitManager, polkit_manager, G_TYPE_OBJECT) static GObjectClass *parent_class = NULL; + +static void +_granting_temp_priv (PolicyKitManager *manager, + TemporaryPrivilege *p) +{ + g_debug ("Granting temporary privilege '%s' to uid %d on resource '%s'", + p->privilege, p->user, p->resource != NULL ? p->resource : "(none)"); + /* TODO: send out D-BUS signal */ +} + +static void +_revoking_temp_priv (PolicyKitManager *manager, + TemporaryPrivilege *p) +{ + g_debug ("Revoking temporary privilege '%s' to uid %d on resource '%s'", + p->privilege, p->user, p->resource != NULL ? p->resource : "(none)"); + /* TODO: send out D-BUS signal */ +} + + typedef struct { uid_t uid; pid_t pid; @@ -130,6 +150,7 @@ polkit_manager_error_get_type (void) ENUM_ENTRY (POLKIT_MANAGER_ERROR_NO_SUCH_USER, "NoSuchUser"), ENUM_ENTRY (POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE, "NoSuchPrivilege"), ENUM_ENTRY (POLKIT_MANAGER_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + ENUM_ENTRY (POLKIT_MANAGER_ERROR_CANNOT_OBTAIN_PRIVILEGE, "CannotObtainPrivilege"), ENUM_ENTRY (POLKIT_MANAGER_ERROR_ERROR, "Error"), { 0, 0, 0 } }; @@ -157,6 +178,8 @@ bus_name_owner_changed (DBusGProxy *bus_proxy, if (strlen (new_service_name) == 0) { CallerInfo *caller_info; PolicyKitSession *session; + GList *i; + TemporaryPrivilege *p; /* evict CallerInfo from cache */ caller_info = (CallerInfo *) g_hash_table_lookup (manager->priv->connection_name_to_caller_info, @@ -177,6 +200,29 @@ bus_name_owner_changed (DBusGProxy *bus_proxy, g_hash_table_remove (manager->priv->connection_name_to_session_object, old_service_name); } + + /* revoke any temporary privileges that is restricted to this name */ + for (i = manager->priv->temporary_privileges; i != NULL; ) { + p = (TemporaryPrivilege *) i->data; + + i = g_list_next (i); + + if (p->system_bus_unique_name != NULL && + strcmp (p->system_bus_unique_name, old_service_name) == 0) { + + /* da, revoke this privilege */ + _revoking_temp_priv (manager, p); + + g_free (p->privilege); + g_free (p->resource); + g_free (p->system_bus_unique_name); + g_free (p); + + manager->priv->temporary_privileges = g_list_remove ( + manager->priv->temporary_privileges, p); + } + } + } /*g_message ("NameOwnerChanged: service_name='%s', old_service_name='%s' new_service_name='%s'", @@ -269,6 +315,7 @@ polkit_manager_get_caller_info (PolicyKitManager *manager, gboolean res; CallerInfo *caller_info; GError *error = NULL; + GArray *calling_selinux_context; res = FALSE; @@ -307,6 +354,22 @@ polkit_manager_get_caller_info (PolicyKitManager *manager, goto out; } + if (!dbus_g_proxy_call (manager->priv->bus_proxy, "GetConnectionSELinuxSecurityContext", &error, + G_TYPE_STRING, sender, + G_TYPE_INVALID, + dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), &calling_selinux_context, + G_TYPE_INVALID)) { + g_warning ("GetConnectionSELinuxSecurityContext() failed: %s", error->message); + g_error_free (error); + goto out; + } + + char *selinux_context_string; + g_array_append_val (calling_selinux_context, "\0"); + selinux_context_string = (char *) g_array_free (calling_selinux_context, FALSE); + g_message ("selinux context = '%s' for sender '%s'", selinux_context_string, sender); + g_free (selinux_context_string); + caller_info = g_new0 (CallerInfo, 1); caller_info->uid = *calling_uid; caller_info->pid = *calling_pid; @@ -324,6 +387,68 @@ out: return res; } + +typedef struct +{ + PolicyKitManager *manager; + char *system_bus_unique_name; + char *privileged_but_restricted_to; + gboolean is_temporary; +} TempPrivCheckUserData; + +static gboolean +_check_for_temp_privilege (uid_t user, + const char *privilege, + const char *resource, + gboolean ignore_resource, + gpointer userdata) +{ + GList *i; + TempPrivCheckUserData *tpcud = (TempPrivCheckUserData *) userdata; + gboolean is_privileged; + + is_privileged = FALSE; + + g_message ("in _check_for_temp_privilege for user=%d priv=%s resource=%s sbun=%s", + user, privilege, resource, tpcud->system_bus_unique_name); + + for (i = tpcud->manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) { + TemporaryPrivilege *p; + gboolean res_match; + + p = (TemporaryPrivilege *) i->data; + + if (ignore_resource) { + res_match = TRUE; + } else { + if (resource == NULL || strlen (resource) == 0) + res_match = (p->resource == NULL); + else + res_match = (safe_strcmp (p->resource, resource) == 0); + } + + if ((strcmp (p->privilege, privilege) == 0) && + res_match && + (p->user == user)) { + + if (p->system_bus_unique_name == NULL) { + is_privileged = TRUE; + tpcud->is_temporary = TRUE; + break; + } else if (strcmp (p->system_bus_unique_name, tpcud->system_bus_unique_name) == 0) { + is_privileged = TRUE; + tpcud->is_temporary = TRUE; + break; + } else { + tpcud->privileged_but_restricted_to = p->system_bus_unique_name; + } + + } + } + + return is_privileged; +} + gboolean polkit_manager_initiate_temporary_privilege_grant (PolicyKitManager *manager, char *user, @@ -365,14 +490,45 @@ polkit_manager_initiate_temporary_privilege_grant (PolicyKitManager *manag return FALSE; } + + gboolean auth_can_obtain; + gboolean auth_can_obtain_is_temporary; + gboolean auth_can_grant; + gboolean auth_obtain_requires_root; + PolicyResult res; + TempPrivCheckUserData tpcud; + + tpcud.manager = manager; + tpcud.system_bus_unique_name = NULL; + tpcud.privileged_but_restricted_to = ""; + tpcud.is_temporary = FALSE; + + res = policy_get_auth_details_for_policy (uid, + privilege, + resource, + &auth_can_obtain, + &auth_can_obtain_is_temporary, + &auth_can_grant, + &auth_obtain_requires_root, + &tpcud, + _check_for_temp_privilege); + + if (!auth_can_obtain) { + dbus_g_method_return_error (context, + g_error_new (POLKIT_MANAGER_ERROR, + POLKIT_MANAGER_ERROR_ERROR, + "The privilege %s cannot be obtained.", privilege)); + return FALSE; + } + session = polkit_session_new (manager->priv->connection, manager, calling_uid, - calling_pid, sender, uid, privilege, - strlen (resource) > 0 ? resource : NULL); + strlen (resource) > 0 ? resource : NULL, + auth_obtain_requires_root); g_object_weak_ref (G_OBJECT (session), session_finalized, @@ -391,7 +547,7 @@ polkit_manager_initiate_temporary_privilege_grant (PolicyKitManager *manag gboolean polkit_manager_is_user_privileged (PolicyKitManager *manager, - int pid, + char *system_bus_unique_name, char *user, char *privilege, char *resource, @@ -403,7 +559,8 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager, PolicyResult res; gboolean is_privileged; gboolean is_temporary; - + char *is_privileged_but_restricted_to = NULL; + TempPrivCheckUserData tpcud; if (!polkit_manager_get_caller_info (manager, dbus_g_method_get_sender (context), @@ -438,10 +595,18 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager, return FALSE; } + tpcud.manager = manager; + tpcud.system_bus_unique_name = system_bus_unique_name; + tpcud.privileged_but_restricted_to = ""; + tpcud.is_temporary = FALSE; res = policy_is_uid_allowed_for_policy (uid, privilege, strlen (resource) > 0 ? resource : NULL, - &is_privileged); + &is_privileged, + &is_temporary, + &is_privileged_but_restricted_to, + &tpcud, + _check_for_temp_privilege); switch (res) { case POLICY_RESULT_OK: break; @@ -463,35 +628,16 @@ polkit_manager_is_user_privileged (PolicyKitManager *manager, return FALSE; } - is_temporary = FALSE; - - /* check temporary lists */ - if (!is_privileged) { - GList *i; - TemporaryPrivilege *p; - - for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) { - p = (TemporaryPrivilege *) i->data; - gboolean res_match; - if (strlen (resource) == 0) - res_match = (p->resource == NULL); - else - res_match = (safe_strcmp (p->resource, resource) == 0); - - if ((strcmp (p->privilege, privilege) == 0) && - res_match && - (p->user == uid) && - ((p->pid_restriction == -1) || (p->pid_restriction == pid))) { - - is_privileged = TRUE; - is_temporary = TRUE; - break; - } - } + /* if we ended up being privileged, then don't fill in the _but_restricted_to */ + if (is_privileged) { + g_free (is_privileged_but_restricted_to); + is_privileged_but_restricted_to = g_strdup (""); } - dbus_g_method_return (context, is_privileged, is_temporary); + dbus_g_method_return (context, is_privileged, is_temporary, is_privileged_but_restricted_to); + + g_free (is_privileged_but_restricted_to); return TRUE; } @@ -508,10 +654,12 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag int n; GList *i; GList *resources; + GList *restrictions; uid_t uid; PolicyResult res; TemporaryPrivilege *p; char **resource_list; + char **restriction_list; int num_non_temporary; if (!polkit_manager_get_caller_info (manager, @@ -572,15 +720,19 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag num_non_temporary = g_list_length (resources); + restrictions = NULL; + /* check temporary list */ for (i = manager->priv->temporary_privileges; i != NULL; i = g_list_next (i)) { p = (TemporaryPrivilege *) i->data; if ((strcmp (p->privilege, privilege) == 0) && (p->resource != NULL) && - (p->user == uid) && - (p->pid_restriction == -1)) { + (p->user == uid)) { + resources = g_list_append (resources, g_strdup (p->resource)); + restrictions = g_list_append (restrictions, p->system_bus_unique_name != NULL ? + p->system_bus_unique_name : ""); } } @@ -595,7 +747,18 @@ polkit_manager_get_allowed_resources_for_privilege (PolicyKitManager *manag g_list_foreach (resources, (GFunc) g_free, NULL); g_list_free (resources); - dbus_g_method_return (context, resource_list, num_non_temporary); + restriction_list = g_new0 (char *, g_list_length (resources) + 1); + for (n = 0; n < num_non_temporary; n++) { + restriction_list[n] = ""; + } + for (i = restrictions; i != NULL; i = g_list_next (i)) { + char *restriction = (char *) i->data; + restriction_list[n] = g_strdup (restriction); + n++; + } + restriction_list[n] = NULL; + + dbus_g_method_return (context, resource_list, restriction_list, num_non_temporary); return TRUE; } @@ -713,7 +876,8 @@ polkit_manager_revoke_temporary_privilege (PolicyKitManager *manager, uid, privilege, resource, - -1)) { + NULL, + TRUE)) { dbus_g_method_return_error (context, g_error_new (POLKIT_MANAGER_ERROR, POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE, @@ -730,13 +894,12 @@ polkit_manager_revoke_temporary_privilege (PolicyKitManager *manager, /* local methods */ - gboolean polkit_manager_add_temporary_privilege (PolicyKitManager *manager, uid_t user, const char *privilege, const char *resource, - pid_t pid_restriction) + const char *system_bus_unique_name) { GList *i; TemporaryPrivilege *p; @@ -747,7 +910,7 @@ polkit_manager_add_temporary_privilege (PolicyKitManager *manager, if ((strcmp (p->privilege, privilege) == 0) && ((resource != NULL) && (safe_strcmp (p->resource, resource)) == 0) && (p->user == user) && - (p->pid_restriction == pid_restriction)) + (p->system_bus_unique_name == system_bus_unique_name)) return FALSE; } @@ -755,8 +918,9 @@ polkit_manager_add_temporary_privilege (PolicyKitManager *manager, p->user = user; p->privilege = g_strdup (privilege); p->resource = g_strdup (resource); - p->pid_restriction = pid_restriction; + p->system_bus_unique_name = g_strdup (system_bus_unique_name); + _granting_temp_priv (manager, p); manager->priv->temporary_privileges = g_list_append (manager->priv->temporary_privileges, p); return TRUE; @@ -767,7 +931,8 @@ polkit_manager_remove_temporary_privilege (PolicyKitManager *manager, uid_t user, const char *privilege, const char *resource, - pid_t pid_restriction) + const char *system_bus_unique_name, + gboolean remove_even_if_system_bus_unique_name_does_not_match) { GList *i; TemporaryPrivilege *p; @@ -776,13 +941,25 @@ polkit_manager_remove_temporary_privilege (PolicyKitManager *manager, p = (TemporaryPrivilege *) i->data; if ((strcmp (p->privilege, privilege) == 0) && + ((resource == NULL) ? (p->resource == NULL) : ((p->resource != NULL) ? (strcmp (p->resource, resource) == 0) : FALSE)) && + (p->user == user) && - (p->pid_restriction == pid_restriction)) { + + (remove_even_if_system_bus_unique_name_does_not_match || + ((system_bus_unique_name == NULL) ? (p->system_bus_unique_name == NULL) + : ((p->system_bus_unique_name != NULL) ? + (strcmp (p->system_bus_unique_name, system_bus_unique_name) == 0) : + FALSE))) + ) { + + _revoking_temp_priv (manager, p); g_free (p->privilege); g_free (p->resource); + g_free (p->system_bus_unique_name); + g_free (p); manager->priv->temporary_privileges = g_list_remove ( manager->priv->temporary_privileges, p); @@ -793,3 +970,117 @@ polkit_manager_remove_temporary_privilege (PolicyKitManager *manager, return FALSE; } + +void +polkit_manager_update_desktop_console_privileges (PolicyKitManager *manager) +{ + GDir *dir; + GError *err = NULL; + const char *f; + GSList *list; + GSList *j; + GList *i; + TemporaryPrivilege *p; + + g_debug ("Entering polkit_manager_update_desktop_console_privileges"); + + /* Build a list of what /var/run/polkit-console contains; + * e.g. {":0", "davidz", ":1", "bateman", ..} + * + * This is essentially a list of pairs <consoleId, userId> + * denoting what users are logged in at the consoles attached + * to the system. + */ + list = NULL; + if ((dir = g_dir_open (PACKAGE_LOCALSTATEDIR "/run/polkit-console", 0, &err)) == NULL) { + g_warning ("Unable to open " PACKAGE_LOCALSTATEDIR "/run/polkit-console : %s", err->message); + g_error_free (err); + goto out; + } + while ((f = g_dir_read_name (dir)) != NULL) { + char **tokens; + + tokens = g_strsplit (f, "_", 2); + if (tokens != NULL && g_strv_length (tokens) == 2) { + char *console; + char *user; + + console = g_strdup_printf ("console://%s", tokens[0]); + user = g_strdup (tokens[1]); + list = g_slist_append (list, console); + list = g_slist_append (list, user); + } + g_strfreev (tokens); + } + g_dir_close (dir); + + /* now revoke the temporary desktop-console privilege for + * users no longer at the console; go through all tempoary + * desktop-console privileges and check that each one is still + * in the list above... + */ + for (i = manager->priv->temporary_privileges; i != NULL; ) { + p = (TemporaryPrivilege *) i->data; + gboolean found; + + i = g_list_next (i); + + found = FALSE; + + if ((strcmp (p->privilege, "desktop-console") == 0) && p->resource != NULL) { + + for (j = list; j != NULL; j = g_slist_next (j)) { + char *console; + char *user; + uid_t uid; + + console = (char *) j->data; + j = g_slist_next (j); + user = (char *) j->data; + uid = policy_util_name_to_uid (user, NULL); + if (uid != (uid_t) -1 && strcmp (p->resource, console) == 0 && + p->user == uid && + p->system_bus_unique_name == NULL) { + found = TRUE; + break; + } + } + } + + if (!found) { + /* revoke this privilege */ + _revoking_temp_priv (manager, p); + + g_free (p->privilege); + g_free (p->resource); + g_free (p->system_bus_unique_name); + g_free (p); + + manager->priv->temporary_privileges = g_list_remove ( + manager->priv->temporary_privileges, p); + } + } + + /* finally grant temporary desktop-console privilege for users + * now at the console + */ + for (j = list; j != NULL; j = g_slist_next (j)) { + char *console; + char *user; + uid_t uid; + + console = (char *) j->data; + j = g_slist_next (j); + user = (char *) j->data; + uid = policy_util_name_to_uid (user, NULL); + if (uid != (uid_t) -1) { + polkit_manager_add_temporary_privilege (manager, uid, "desktop-console", console, NULL); + } + } + + g_slist_foreach (list, (GFunc) g_free, NULL); + g_slist_free (list); + +out: + ; +} diff --git a/polkitd/polkit-manager.h b/polkitd/polkit-manager.h index f59e2dd..9d7b802 100644 --- a/polkitd/polkit-manager.h +++ b/polkitd/polkit-manager.h @@ -40,6 +40,7 @@ typedef enum POLKIT_MANAGER_ERROR_NO_SUCH_PRIVILEGE = 1, POLKIT_MANAGER_ERROR_NOT_PRIVILEGED = 2, POLKIT_MANAGER_ERROR_ERROR = 3, + POLKIT_MANAGER_ERROR_CANNOT_OBTAIN_PRIVILEGE = 4, POLKIT_MANAGER_NUM_ERRORS } PolkitManagerError; @@ -90,7 +91,7 @@ gboolean polkit_manager_revoke_temporary_privilege (PolicyKitM DBusGMethodInvocation *context); gboolean polkit_manager_is_user_privileged (PolicyKitManager *manager, - int pid, + char *system_bus_unique_name, char *user, char *privilege, char *resource, @@ -116,12 +117,16 @@ gboolean polkit_manager_add_temporary_privilege (PolicyKitM uid_t user, const char *privilege, const char *resource, - pid_t pid_restriction); + const char *system_bus_unique_name); gboolean polkit_manager_remove_temporary_privilege (PolicyKitManager *manager, uid_t user, const char *privilege, const char *resource, - pid_t pid_restriction); + const char *system_bus_unique_name, + gboolean remove_even_if_system_bus_unique_name_does_not_match); + +void polkit_manager_update_desktop_console_privileges (PolicyKitManager *manager); + #endif /* _POLKIT_MANAGER_H */ diff --git a/polkitd/polkit-session.c b/polkitd/polkit-session.c index 458e854..cbc2fb5 100644 --- a/polkitd/polkit-session.c +++ b/polkitd/polkit-session.c @@ -36,6 +36,7 @@ #include <dbus/dbus-glib-lowlevel.h> #include <security/pam_appl.h> +#include "policy.h" #include "polkit-session.h" enum @@ -58,13 +59,12 @@ struct PolicyKitSessionPrivate char *auth_with_pam_service; uid_t calling_uid; - pid_t calling_pid; char *calling_dbus_name; uid_t grant_to_uid; char *grant_privilege; char *grant_resource; - pid_t grant_pid_restriction; + char *grant_system_bus_name_unique_name_restriction; gboolean have_granted_temp_privileges; @@ -879,10 +879,9 @@ polkit_session_provide_answers (PolicyKitSession *session, gboolean polkit_session_close (PolicyKitSession *session, - gboolean do_not_revoke_privilege, DBusGMethodInvocation *context) { - /*g_debug ("in %s", __FUNCTION__);*/ + g_debug ("In polkit_session_close for session %d", session->priv->session_number); if (!polkit_session_check_caller (session, context)) return FALSE; @@ -891,21 +890,6 @@ polkit_session_close (PolicyKitSession *session, if (session->priv->child_pid != 0) kill (session->priv->child_pid, SIGTERM); - if (!do_not_revoke_privilege && session->priv->have_granted_temp_privileges) { - - if (!polkit_manager_remove_temporary_privilege (session->priv->manager, - session->priv->grant_to_uid, - session->priv->grant_privilege, - session->priv->grant_resource, - session->priv->grant_pid_restriction)) { - g_warning ("Could not remove tmp priv '%s' to uid %d for resource '%s' on pid %d", - session->priv->grant_privilege, - session->priv->grant_to_uid, - session->priv->grant_resource, - session->priv->grant_pid_restriction); - } - } - g_object_unref (session); dbus_g_method_return (context); @@ -914,7 +898,7 @@ polkit_session_close (PolicyKitSession *session, gboolean polkit_session_grant_privilege_temporarily (PolicyKitSession *session, - gboolean restrict_to_callers_pid, + gboolean restrict_to_callers_system_bus_unique_name, DBusGMethodInvocation *context) { if (!polkit_session_check_caller (session, context)) @@ -936,17 +920,18 @@ polkit_session_grant_privilege_temporarily (PolicyKitSession *session, return FALSE; } - session->priv->grant_pid_restriction = restrict_to_callers_pid ? session->priv->calling_pid : (pid_t) -1; + session->priv->grant_system_bus_name_unique_name_restriction = restrict_to_callers_system_bus_unique_name ? + g_strdup (session->priv->calling_dbus_name) : NULL; if (!polkit_manager_add_temporary_privilege (session->priv->manager, session->priv->grant_to_uid, session->priv->grant_privilege, session->priv->grant_resource, - session->priv->grant_pid_restriction)) { - g_warning ("Could not add tmp priv '%s' to uid %d for resource '%s' on pid %d", + session->priv->grant_system_bus_name_unique_name_restriction)) { + g_warning ("Could not add tmp priv '%s' to uid %d for resource '%s' on connection '%s'", session->priv->grant_privilege, session->priv->grant_to_uid, session->priv->grant_resource, - session->priv->grant_pid_restriction); + session->priv->grant_system_bus_name_unique_name_restriction); } session->priv->have_granted_temp_privileges = TRUE; @@ -959,11 +944,11 @@ PolicyKitSession * polkit_session_new (DBusGConnection *connection, PolicyKitManager *manager, uid_t calling_uid, - pid_t calling_pid, const char *calling_dbus_name, uid_t uid, const char *privilege, - const char *resource) + const char *resource, + gboolean auth_as_root) { char *objpath; PolicyKitSession *session; @@ -978,17 +963,21 @@ polkit_session_new (DBusGConnection *connection, g_free (objpath); session->priv->calling_uid = calling_uid; - session->priv->calling_pid = calling_pid; session->priv->calling_dbus_name = g_strdup (calling_dbus_name); session->priv->grant_to_uid = uid; session->priv->grant_privilege = g_strdup (privilege); session->priv->grant_resource = g_strdup (resource); - /* TODO: look up auth_as_user, auth_with_pam_service from privilege configuration files */ - session->priv->auth_as_user = g_strdup ("root"); + /* TODO: look up auth_as_user from privilege configuration files */ + if (auth_as_root) + session->priv->auth_as_user = g_strdup ("root"); + else + session->priv->auth_as_user = policy_util_uid_to_name (uid, NULL); session->priv->auth_with_pam_service = g_strdup ("policy-kit"); + g_debug ("In polkit_session_new ; established session %d", session->priv->session_number); + return session; } @@ -996,23 +985,29 @@ polkit_session_new (DBusGConnection *connection, void polkit_session_initiator_disconnected (PolicyKitSession *session) { - /*g_debug ("initiator disconnected");*/ + g_debug ("Initiator for session %d disconnected", session->priv->session_number); /* if we have a child... kill it */ if (session->priv->child_pid != 0) kill (session->priv->child_pid, SIGTERM); if (session->priv->have_granted_temp_privileges) { + g_debug (" Revoking temporary privilege %s on %s for uid %d on connection %s", + session->priv->grant_privilege, + session->priv->grant_resource, + session->priv->grant_to_uid, + session->priv->grant_system_bus_name_unique_name_restriction); if (!polkit_manager_remove_temporary_privilege (session->priv->manager, session->priv->grant_to_uid, session->priv->grant_privilege, session->priv->grant_resource, - session->priv->grant_pid_restriction)) { - g_warning ("Could not remove tmp priv '%s' to uid %d for resource '%s' on pid %d", + session->priv->grant_system_bus_name_unique_name_restriction, + FALSE)) { + g_warning ("Could not remove tmp priv '%s' to uid %d for resource '%s' on connection '%s'", session->priv->grant_privilege, session->priv->grant_to_uid, session->priv->grant_resource, - session->priv->grant_pid_restriction); + session->priv->grant_system_bus_name_unique_name_restriction); } } } diff --git a/polkitd/polkit-session.h b/polkitd/polkit-session.h index c02bd22..19fac2f 100644 --- a/polkitd/polkit-session.h +++ b/polkitd/polkit-session.h @@ -80,11 +80,11 @@ struct PolicyKitSessionClass PolicyKitSession *polkit_session_new (DBusGConnection *connection, PolicyKitManager *manager, uid_t calling_uid, - pid_t calling_pid, const char *calling_dbus_name, uid_t uid, const char *privilege, - const char *resource); + const char *resource, + gboolean auth_as_root); /* remote methods */ @@ -102,7 +102,6 @@ gboolean polkit_session_provide_answers (PolicyKitSession DBusGMethodInvocation *context); gboolean polkit_session_close (PolicyKitSession *session, - gboolean do_not_revoke_privilege, DBusGMethodInvocation *context); gboolean polkit_session_get_auth_details (PolicyKitSession *session, @@ -112,7 +111,7 @@ gboolean polkit_session_get_auth_denied_reason (PolicyKitSession DBusGMethodInvocation *context); gboolean polkit_session_grant_privilege_temporarily (PolicyKitSession *session, - gboolean restrict_to_callers_pid, + gboolean restrict_to_callers_system_bus_unique_name, DBusGMethodInvocation *context); /* local methods */ |