PolicyKit: Branch 'master' - 2 commits

David Zeuthen david at kemper.freedesktop.org
Thu Aug 23 18:13:32 PDT 2007


 polkit/polkit-grant-database.c |  182 ++++++++++++++++++++++++++++++
 polkit/polkit-grant-database.h |   37 ++++++
 polkit/polkit-policy-cache.c   |   58 +++++++--
 polkit/polkit-policy-cache.h   |    2 
 tools/Makefile.am              |    2 
 tools/polkit-grant.c           |  245 ++++++++++++++++++++++++++---------------
 tools/polkit-list-actions.c    |   71 +++++++++--
 7 files changed, 481 insertions(+), 116 deletions(-)

New commits:
diff-tree 2816f794b5d52f496060d1f2d1d76c7bdf69dec0 (from parents)
Merge: a0267b82eff268882a65214304381dbcbddc8978 c27e93f7faf2901cbd0d3cd5b4bd9ce87f8ca7cb
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Aug 23 21:08:01 2007 -0400

    Merge branch 'master' of ssh://david@git.freedesktop.org/git/PolicyKit

diff-tree a0267b82eff268882a65214304381dbcbddc8978 (from 9924987f324953fa9e58b937dfedc1cc06ece0b3)
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Aug 23 21:07:46 2007 -0400

    give a little love to polkit-list-actions(1) and polkit-grant(1)
    
    In addition polkit-grant(1) gained a few new features
    
     --list          : for listing all grants
     --delete <user> : for deleting all grants given to an user

diff --git a/polkit/polkit-grant-database.c b/polkit/polkit-grant-database.c
index 737e7ac..ec8a172 100644
--- a/polkit/polkit-grant-database.c
+++ b/polkit/polkit-grant-database.c
@@ -39,6 +39,7 @@
 #include <glib.h>
 
 #include <polkit/polkit-grant-database.h>
+#include <polkit/polkit-debug.h>
 
 /**
  * SECTION:polkit-grant-database
@@ -312,3 +313,184 @@ _polkit_grantdb_check_can_caller_do_acti
 out:
         return result;
 }
+
+void 
+_polkit_grantdb_foreach (PolKitGrantDbForeachFunc callback, void *user_data)
+{
+        GDir *dir;
+        const char *name;
+        time_t when;
+
+        g_return_if_fail (callback != NULL);
+
+        _pk_debug ("Looking at run");
+        dir = g_dir_open (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit", 0, NULL);
+        if (dir != NULL) {
+                while ((name = g_dir_read_name (dir)) != NULL) {
+                        int uid;
+                        char *endptr;
+                        char *action;
+                        char *path;
+                        struct stat statbuf;
+
+                        path = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/%s", name);
+                        if (stat (path, &statbuf) != 0) {
+                                g_free (path);
+                                continue;
+                        }
+                        when = statbuf.st_mtime;
+                        g_free (path);
+
+                        if (!g_str_has_prefix (name, "uid"))
+                                continue;
+                        if (!g_str_has_suffix (name, ".grant"))
+                                continue;
+
+                        uid = strtol (name + 3 /* uid */, &endptr, 10);
+                        if (endptr == NULL || *endptr != '-')
+                                continue;
+
+                        if (strncmp (endptr + 1, "pid-", 4) == 0) {
+                                int pid;
+                                unsigned long long pid_time;
+
+                                pid = strtol (endptr + 1 + 4 /*pid-*/, &endptr, 10);
+                                if (endptr == NULL || *endptr != '@')
+                                        continue;
+                                pid_time = strtol (endptr + 1, NULL, 10);
+
+                                while (*endptr != '-' && *endptr != '\0')
+                                        endptr++;
+                                if (*endptr == '\0')
+                                        continue;
+                                action = g_strdup (endptr + 1);
+                                if (strlen (action) < 6) /* .grant */
+                                        continue;
+                                action[strlen(action) - 6] = '\0';
+
+                                callback (action, uid, when, POLKIT_GRANTDB_GRANT_TYPE_PROCESS, 
+                                          pid, pid_time, NULL, user_data);
+
+                                g_free (action);
+                        } else if (strncmp (endptr + 1, "session-", 8) == 0) {
+                                int n;
+                                char *session;
+
+                                session = g_strdup (endptr + 1 + 8);
+                                for (n = 0; session[n] != '-' && session[n] != '\0'; n++)
+                                        ;
+                                session[n] = '\0';
+
+                                action = g_strdup (endptr + 1 + 8 + n + 1);
+                                if (strlen (action) < 6) /* .grant */
+                                        continue;
+                                action[strlen(action) - 6] = '\0';
+
+                                callback (action, uid, when, POLKIT_GRANTDB_GRANT_TYPE_SESSION, 
+                                          (pid_t) -1, 0, session, user_data);
+
+                                g_free (action);
+                                g_free (session);
+                        }
+
+
+                }
+                g_dir_close (dir);
+        }
+
+        _pk_debug ("Looking at lib");
+        dir = g_dir_open (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit", 0, NULL);
+        if (dir != NULL) {
+                while ((name = g_dir_read_name (dir)) != NULL) {
+                        int uid;
+                        char *action;
+                        char *endptr;
+                        char *path;
+                        struct stat statbuf;
+
+                        path = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/%s", name);
+                        if (stat (path, &statbuf) != 0) {
+                                g_free (path);
+                                continue;
+                        }
+                        when = statbuf.st_mtime;
+                        g_free (path);
+
+                        if (!g_str_has_prefix (name, "uid"))
+                                continue;
+                        if (!g_str_has_suffix (name, ".grant"))
+                                continue;
+
+                        uid = strtol (name + 3 /* uid */, &endptr, 10);
+                        if (endptr == NULL || *endptr != '-')
+                                continue;
+                        action = g_strdup (endptr + 1);
+                        if (strlen (action) < 6) /* .grant */
+                                continue;
+                        action[strlen(action) - 6] = '\0';
+                        
+                        callback (action, uid, when, POLKIT_GRANTDB_GRANT_TYPE_ALWAYS, 
+                                  (pid_t) -1, 0, NULL, user_data);
+
+                        g_free (action);
+                }
+                g_dir_close (dir);
+        }
+}
+
+polkit_bool_t
+_polkit_grantdb_delete_for_user (uid_t uid)
+{
+        int n;
+        GDir *dir;
+        const char *name;
+        polkit_bool_t ret;
+
+        ret = FALSE;
+
+        _pk_debug ("deleting grants for uid %d", uid);
+
+        for (n = 0; n < 2; n++) {
+                if (n == 0)
+                        dir = g_dir_open (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit", 0, NULL);
+                else
+                        dir = g_dir_open (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit", 0, NULL);
+                if (dir != NULL) {
+                        while ((name = g_dir_read_name (dir)) != NULL) {
+                                uid_t uid_in_grant;
+                                char *endptr;
+                                char *path;
+                                
+                                if (!g_str_has_prefix (name, "uid"))
+                                        continue;
+                                if (!g_str_has_suffix (name, ".grant"))
+                                        continue;
+                                
+                                uid_in_grant = (uid_t) strtol (name + 3 /* uid */, &endptr, 10);
+                                if (endptr == NULL || *endptr != '-')
+                                        continue;
+                                
+                                if (uid_in_grant != uid)
+                                        continue;
+                                
+                                if (n == 0)
+                                        path = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/run/PolicyKit/%s", name);
+                                else
+                                        path = g_strdup_printf (PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit/%s", name);
+                                if (unlink (path) != 0) {
+                                        _pk_debug ("Error deleting grant file '%s': %s", path, strerror (errno));
+                                        goto out;
+                                }
+                                _pk_debug ("Deleting file %s", path);
+                                g_free (path);
+                                
+                        }
+                        g_dir_close (dir);
+                }
+        }
+
+        ret = TRUE;
+
+out:
+        return ret;
+}
diff --git a/polkit/polkit-grant-database.h b/polkit/polkit-grant-database.h
index dd53e8e..f867df7 100644
--- a/polkit/polkit-grant-database.h
+++ b/polkit/polkit-grant-database.h
@@ -38,4 +38,41 @@ polkit_bool_t _polkit_grantdb_write_keep
 
 polkit_bool_t _polkit_grantdb_write_pid (const char *action_id, pid_t pid);
 
+/**
+ * PolKitGrantDbGrantType:
+ * 
+ */
+typedef enum {
+        POLKIT_GRANTDB_GRANT_TYPE_PROCESS,
+        POLKIT_GRANTDB_GRANT_TYPE_SESSION,
+        POLKIT_GRANTDB_GRANT_TYPE_ALWAYS
+} PolKitGrantDbGrantType;
+
+/**
+ * PolKitGrantDbForeachFunc:
+ * @action_id: Identifer for the action granted
+ * @when: when the privilege was granted
+ * @grant_type: the type of grant; one of #PolKitGrantDbGrantType
+ * @pid: the process id, or -1 if the passed grant_type is not POLKIT_GRANTDB_GRANT_TYPE_PROCESS
+ * @pid_time: the start time of the process (only if pid is set)
+ * @session_id: the session id, or NULL if the passed grant_type is not POLKIT_GRANTDB_GRANT_TYPE_SESSION
+ * @uid: the UNIX process id, or -1 if the passed grant_type is not POLKIT_GRANTDB_GRANT_TYPE_ALWAYS
+ * 
+ * @user_data: user data passed to polkit_grantdb_foreach()
+ *
+ * Callback function for polkit_policy_cache_foreach().
+ **/
+typedef void (*PolKitGrantDbForeachFunc) (const char *action_id, 
+                                          uid_t uid,
+                                          time_t when, 
+                                          PolKitGrantDbGrantType grant_type,
+                                          pid_t pid, 
+                                          unsigned long long pid_time,
+                                          const char *session_id,
+                                          void *user_data);
+
+void _polkit_grantdb_foreach (PolKitGrantDbForeachFunc callback, void *user_data);
+
+polkit_bool_t _polkit_grantdb_delete_for_user (uid_t uid);
+
 #endif /* POLKIT_GRANT_DATABASE_H */
diff --git a/polkit/polkit-policy-cache.c b/polkit/polkit-policy-cache.c
index a196bf9..0fb6766 100644
--- a/polkit/polkit-policy-cache.c
+++ b/polkit/polkit-policy-cache.c
@@ -205,13 +205,50 @@ polkit_policy_cache_debug (PolKitPolicyC
 }
 
 /**
+ * polkit_policy_cache_get_entry_by_id:
+ * @policy_cache: the cache
+ * @action: the action identifier
+ * 
+ * Given a action identifier, find the object describing the
+ * definition of the policy; e.g. data stemming from files in
+ * /usr/share/PolicyKit/policy.
+ * 
+ * Returns: A #PolKitPolicyFileEntry entry on sucess; otherwise
+ * #NULL if the action wasn't identified. Caller shall not unref
+ * this object.
+ **/
+PolKitPolicyFileEntry* 
+polkit_policy_cache_get_entry_by_id (PolKitPolicyCache *policy_cache, const char *action_id)
+{
+        GSList *i;
+        PolKitPolicyFileEntry *pfe;
+
+        g_return_val_if_fail (policy_cache != NULL, NULL);
+        g_return_val_if_fail (action_id != NULL, NULL);
+
+        pfe = NULL;
+
+        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
+                pfe = i->data;
+                if (strcmp (polkit_policy_file_entry_get_id (pfe), action_id) == 0) {
+                        goto out;
+                }
+        }
+
+        pfe = NULL;
+
+out:
+        return pfe;        
+}
+
+/**
  * polkit_policy_cache_get_entry:
  * @policy_cache: the cache
  * @action: the action
  * 
  * Given a action, find the object describing the definition of the
  * policy; e.g. data stemming from files in
- * /etc/PolicyKit/policy.
+ * /usr/share/PolicyKit/policy.
  * 
  * Returns: A #PolKitPolicyFileEntry entry on sucess; otherwise
  * #NULL if the action wasn't identified. Caller shall not unref
@@ -221,29 +258,20 @@ PolKitPolicyFileEntry* 
 polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache,
                                   PolKitAction      *action)
 {
-        char *priv_id;
-        GSList *i;
+        char *action_id;
         PolKitPolicyFileEntry *pfe;
 
-        pfe = NULL;
-
         /* I'm sure it would be easy to make this O(1)... */
 
         g_return_val_if_fail (policy_cache != NULL, NULL);
         g_return_val_if_fail (action != NULL, NULL);
 
-        if (!polkit_action_get_action_id (action, &priv_id))
-                goto out;
-
-        for (i = policy_cache->priv_entries; i != NULL; i = g_slist_next (i)) {
-                pfe = i->data;
-                if (strcmp (polkit_policy_file_entry_get_id (pfe), priv_id) == 0) {
-                        goto out;
-                }
-        }
-
         pfe = NULL;
 
+        if (!polkit_action_get_action_id (action, &action_id))
+                goto out;
+
+        pfe = polkit_policy_cache_get_entry_by_id (policy_cache, action_id);
 out:
         return pfe;
 }
diff --git a/polkit/polkit-policy-cache.h b/polkit/polkit-policy-cache.h
index c7d89c5..dd86869 100644
--- a/polkit/polkit-policy-cache.h
+++ b/polkit/polkit-policy-cache.h
@@ -54,6 +54,8 @@ void                   polkit_policy_cac
 void                   polkit_policy_cache_debug     (PolKitPolicyCache *policy_cache);
 PolKitPolicyFileEntry* polkit_policy_cache_get_entry (PolKitPolicyCache *policy_cache, 
                                                       PolKitAction *action);
+PolKitPolicyFileEntry* polkit_policy_cache_get_entry_by_id (PolKitPolicyCache *policy_cache, 
+                                                            const char *action_id);
 void                   polkit_policy_cache_foreach   (PolKitPolicyCache *policy_cache, 
                                                       PolKitPolicyCacheForeachFunc callback,
                                                       void *user_data);
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1c922c2..f15a7f6 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -23,7 +23,7 @@ polkit_policy_file_validate_SOURCES = po
 polkit_policy_file_validate_LDADD = $(top_builddir)/polkit/libpolkit.la
 
 polkit_grant_SOURCES = polkit-grant.c
-polkit_grant_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-grant/libpolkit-grant.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
+polkit_grant_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-grant/libpolkit-grant.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la $(top_builddir)/polkit/libpolkit-grant-private.la
 
 polkit_list_actions_SOURCES = polkit-list-actions.c
 polkit_list_actions_LDADD = $(GLIB) $(top_builddir)/polkit/libpolkit.la
diff --git a/tools/polkit-grant.c b/tools/polkit-grant.c
index 43e7005..85f17aa 100644
--- a/tools/polkit-grant.c
+++ b/tools/polkit-grant.c
@@ -39,6 +39,7 @@
 
 #include <polkit-dbus/polkit-dbus.h>
 #include <polkit-grant/polkit-grant.h>
+#include <polkit/polkit-grant-database.h>
 
 #include <glib.h>
 
@@ -47,16 +48,16 @@ usage (int argc, char *argv[])
 {
 	fprintf (stderr,
                  "\n"
-                 "usage : polkit-grant\n"
-                 "          --action <action>\n"
+                 "usage : polkit-grant [--gain <action>] [--list] [--delete <user>]\n"
                  "          [--version] [--help]\n");
 	fprintf (stderr,
                  "\n"
-                 "        --action         Requested action\n"
-                 "        --version        Show version and exit\n"
-                 "        --help           Show this information and exit\n"
-                 "\n"
-                 "TODO.\n");
+                 "        --gain       Attempt to gain the privilege to do an action\n"
+                 "        --list       List all grants\n"
+                 "        --delete     Delete all grants for a given user\n"
+                 "        --version    Show version and exit\n"
+                 "        --help       Show this information and exit\n"
+                 "\n");
 }
 
 typedef struct {
@@ -299,11 +300,63 @@ remove_watch (PolKitGrant *polkit_auth, 
         g_source_remove (watch_id);
 }
 
+static void
+_print_grants (const char *action_id, 
+               uid_t uid,
+               time_t when, 
+               PolKitGrantDbGrantType grant_type,
+               pid_t pid,
+               unsigned long long pid_time,
+               const char *session_id,
+               void *user_data)
+{
+        char *user;
+        char *when_str;
+        struct passwd *passwd;
+
+        passwd = getpwuid (uid);
+        if (passwd != NULL)
+                user = passwd->pw_name;
+        else
+                user = "NON_EXISTING_USER";
+
+        when_str = ctime (&when);
+
+        switch (grant_type) {
+        case POLKIT_GRANTDB_GRANT_TYPE_PROCESS:
+                printf ("process:\n"
+                        "  user:    %s (uid %d)\n"
+                        "  pid:     %d@%lld\n"
+                        "  action:  %s\n"
+                        "  granted: %s\n", 
+                        user, uid, pid, pid_time, action_id, when_str);
+                break;
+        case POLKIT_GRANTDB_GRANT_TYPE_SESSION:
+                printf ("session:\n"
+                        "  user:    %s (uid %d)\n"
+                        "  session: %s\n"
+                        "  action:  %s\n"
+                        "  granted: %s\n", 
+                        user, uid, session_id, action_id, when_str);
+                break;
+        case POLKIT_GRANTDB_GRANT_TYPE_ALWAYS:
+                printf ("always:\n"
+                        "  user:    %s (uid %d)\n"
+                        "  action:  %s\n"
+                        "  granted: %s\n", 
+                        user, uid, action_id, when_str);
+                break;
+        default:
+                break;
+        }
+}
+
+
 int
 main (int argc, char *argv[])
 {
-        char *action_id = NULL;
-        gboolean is_version = FALSE;
+        char *gain_action_id;
+        gboolean is_version;
         DBusConnection *bus;
 	DBusError error;
         PolKitContext *pol_ctx;
@@ -313,27 +366,34 @@ main (int argc, char *argv[])
         PolKitGrant *polkit_grant;
         int ret;
         UserData ud;
+        polkit_bool_t list_grants;
+        char *delete_for_user;
 
-        ret = 2;
+        ret = 1;
 
 	if (argc <= 1) {
 		usage (argc, argv);
-		return 1;
+                goto out;
 	}
 
+        list_grants = FALSE;
+        delete_for_user = NULL;
+        is_version = FALSE;
+        gain_action_id = NULL;
 	while (1) {
 		int c;
 		int option_index = 0;
 		const char *opt;
 		static struct option long_options[] = {
-			{"action", 1, NULL, 0},
+                        {"list", 0, NULL, 0},
+                        {"delete", 1, NULL, 0},
+			{"gain", 1, NULL, 0},
 			{"version", 0, NULL, 0},
 			{"help", 0, NULL, 0},
 			{NULL, 0, NULL, 0}
 		};
 
-		c = getopt_long (argc, argv, "",
-				 long_options, &option_index);
+		c = getopt_long (argc, argv, "", long_options, &option_index);
 		if (c == -1)
 			break;
 
@@ -346,90 +406,107 @@ main (int argc, char *argv[])
 				return 0;
 			} else if (strcmp (opt, "version") == 0) {
 				is_version = TRUE;
-			} else if (strcmp (opt, "action") == 0) {
-				action_id = strdup (optarg);
+			} else if (strcmp (opt, "gain") == 0) {
+				gain_action_id = strdup (optarg);
+			} else if (strcmp (opt, "list") == 0) {
+                                list_grants = TRUE;
+			} else if (strcmp (opt, "delete") == 0) {
+                                delete_for_user = strdup (optarg);
 			}
 			break;
 
 		default:
 			usage (argc, argv);
-                        goto error;
+                        goto out;
 		}
 	}
 
 	if (is_version) {
 		printf ("polkit-grant " PACKAGE_VERSION "\n");
-		return 0;
-	}
-
-	if (action_id == NULL) {
-		usage (argc, argv);
-                goto error;
-	}
-
-        printf ("Attempting to gain the privilege for %s.\n", action_id);
-
-        ud.loop = g_main_loop_new (NULL, TRUE);
-
-        dbus_error_init (&error);
-        bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
-        if (bus == NULL) {
-		fprintf (stderr, "error: dbus_bus_get(): %s: %s\n", error.name, error.message);
-                goto error;
+                ret = 0;
+                goto out;
 	}
 
-        p_error = NULL;
-        pol_ctx = polkit_context_new ();
-        if (!polkit_context_init (pol_ctx, &p_error)) {
-		fprintf (stderr, "error: polkit_context_init: %s\n", polkit_error_get_error_message (p_error));
-                polkit_error_free (p_error);
-                goto error;
-        }
-
-        action = polkit_action_new ();
-        polkit_action_set_action_id (action, action_id);
-
-        caller = polkit_caller_new_from_dbus_name (bus, dbus_bus_get_unique_name (bus), &error);
-        if (caller == NULL) {
-                if (dbus_error_is_set (&error)) {
-                        fprintf (stderr, "error: polkit_caller_new_from_dbus_name(): %s: %s\n", 
-                                 error.name, error.message);
-                        goto error;
+        if (gain_action_id != NULL) {
+                printf ("Attempting to gain the privilege for %s.\n", gain_action_id);
+                
+                ud.loop = g_main_loop_new (NULL, TRUE);
+                
+                dbus_error_init (&error);
+                bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+                if (bus == NULL) {
+                        fprintf (stderr, "error: dbus_bus_get(): %s: %s\n", error.name, error.message);
+                        goto out;
                 }
+                
+                p_error = NULL;
+                pol_ctx = polkit_context_new ();
+                if (!polkit_context_init (pol_ctx, &p_error)) {
+                        fprintf (stderr, "error: polkit_context_init: %s\n", polkit_error_get_error_message (p_error));
+                        polkit_error_free (p_error);
+                        goto out;
+                }
+                
+                action = polkit_action_new ();
+                polkit_action_set_action_id (action, gain_action_id);
+                
+                caller = polkit_caller_new_from_dbus_name (bus, dbus_bus_get_unique_name (bus), &error);
+                if (caller == NULL) {
+                        if (dbus_error_is_set (&error)) {
+                                fprintf (stderr, "error: polkit_caller_new_from_dbus_name(): %s: %s\n", 
+                                         error.name, error.message);
+                                goto out;
+                        }
+                }
+                
+                polkit_grant = polkit_grant_new ();
+                polkit_grant_set_functions (polkit_grant,
+                                            add_io_watch,
+                                            add_child_watch,
+                                            remove_watch,
+                                            conversation_type,
+                                            conversation_select_admin_user,
+                                            conversation_pam_prompt_echo_off,
+                                            conversation_pam_prompt_echo_on,
+                                            conversation_pam_error_msg,
+                                            conversation_pam_text_info,
+                                            conversation_override_grant_type,
+                                            conversation_done,
+                                            &ud);
+                
+                if (!polkit_grant_initiate_auth (polkit_grant,
+                                                 action,
+                                                 caller)) {
+                        printf ("Failed to initiate privilege grant.\n");
+                        ret = 1;
+                        goto out;
+                }
+                g_main_loop_run (ud.loop);
+                polkit_grant_unref (polkit_grant);
+                
+                if (ud.gained_privilege)
+                        printf ("Successfully gained the privilege for %s.\n", gain_action_id);
+                else
+                        printf ("Failed to gain the privilege for %s.\n", gain_action_id);
+                
+                ret = ud.gained_privilege ? 0 : 1;
+        } else if (list_grants) {
+                _polkit_grantdb_foreach (_print_grants, NULL);
+                ret = 0;
+        } else if (delete_for_user != NULL) {
+                struct passwd *passwd;
+                passwd = getpwnam (delete_for_user);
+                if (passwd == NULL) {
+                        printf ("No such user '%s'.\n", delete_for_user);
+                        goto out;
+                }
+                if (!_polkit_grantdb_delete_for_user (passwd->pw_uid)) {
+                        printf ("Error deleting grants for user '%s'. Got root?\n", delete_for_user);
+                }
+        } else {
+		usage (argc, argv);
         }
 
-        polkit_grant = polkit_grant_new ();
-        polkit_grant_set_functions (polkit_grant,
-                                    add_io_watch,
-                                    add_child_watch,
-                                    remove_watch,
-                                    conversation_type,
-                                    conversation_select_admin_user,
-                                    conversation_pam_prompt_echo_off,
-                                    conversation_pam_prompt_echo_on,
-                                    conversation_pam_error_msg,
-                                    conversation_pam_text_info,
-                                    conversation_override_grant_type,
-                                    conversation_done,
-                                    &ud);
-        
-        if (!polkit_grant_initiate_auth (polkit_grant,
-                                         action,
-                                         caller)) {
-                printf ("Failed to initiate privilege grant.\n");
-                ret = 1;
-                goto error;
-        }
-        g_main_loop_run (ud.loop);
-        polkit_grant_unref (polkit_grant);
-
-        if (ud.gained_privilege)
-                printf ("Successfully gained the privilege for %s.\n", action_id);
-        else
-                printf ("Failed to gain the privilege for %s.\n", action_id);
-
-        ret = ud.gained_privilege ? 0 : 1;
-
-error:
+out:
         return ret;
 }
diff --git a/tools/polkit-list-actions.c b/tools/polkit-list-actions.c
index 9e4479e..5ecca98 100644
--- a/tools/polkit-list-actions.c
+++ b/tools/polkit-list-actions.c
@@ -49,14 +49,22 @@ usage (int argc, char *argv[])
                  "\n"
                  "        --version        Show version and exit\n"
                  "        --help           Show this information and exit\n"
+                 "        --action         Show detailed information about a single action\n"
                  "\n"
                  "List the actions registered with PolicyKit.\n");
 }
 
 static void
-_print_entry (PolKitPolicyCache *policy_cache,
-              PolKitPolicyFileEntry *pfe,
-              void *user_data)
+_print_annotations (PolKitPolicyFileEntry *policy_file_entry,
+                    const char *key,
+                    const char *value,
+                    void *user_data)
+{
+        printf ("annotation:       %s -> %s\n", key, value);
+}
+
+static void
+_print_details_for_entry (PolKitPolicyFileEntry *pfe)
 {
         const char *action_id;
         PolKitPolicyDefault *def;
@@ -68,22 +76,43 @@ _print_entry (PolKitPolicyCache *policy_
         default_inactive = polkit_policy_default_get_allow_inactive (def);
         default_active = polkit_policy_default_get_allow_active (def);
 
-        printf ("Policy\n"
-                "------\n"
-                "action            = %s ('%s')\n"
-                "default_inactive  = %s\n"
-                "default_active    = %s\n"
-                "\n", 
+        printf ("action_id:        %s\n"
+                "description:      %s\n"
+                "message:          %s\n"
+                "default_inactive: %s\n"
+                "default_active:   %s\n",
                 action_id,
                 polkit_policy_file_entry_get_action_description (pfe),
+                polkit_policy_file_entry_get_action_message (pfe),
                 polkit_result_to_string_representation (default_inactive),
                 polkit_result_to_string_representation (default_active));
+
+        polkit_policy_file_entry_annotations_foreach (pfe, _print_annotations, NULL);
+}
+
+static void
+_print_entry (PolKitPolicyCache *policy_cache,
+              PolKitPolicyFileEntry *pfe,
+              void *user_data)
+{
+        const char *action_id;
+
+        action_id = polkit_policy_file_entry_get_id (pfe);
+        printf ("%s\n", action_id);
 }
 
 int
 main (int argc, char *argv[])
 {
         int n;
+        int ret;
+        PolKitContext *ctx;
+        PolKitPolicyCache *cache;
+        PolKitError *error;
+        char *action_id;
+
+        ret = 1;
+        action_id = NULL;
 
         for (n = 1; n < argc; n++) {
                 if (strcmp (argv[n], "--help") == 0) {
@@ -94,21 +123,19 @@ main (int argc, char *argv[])
                         printf ("polkit-list-actions " PACKAGE_VERSION "\n");
                         return 0;
                 }
+                if (strcmp (argv[n], "--action") == 0 && n + 1 < argc) {
+                        action_id = argv[n+1];
+                }
 	}
 
-        int ret;
-        ret = 1;
 
-        PolKitContext *ctx;
-        PolKitPolicyCache *cache;
-        PolKitError *error;
         ctx = polkit_context_new ();
         if (ctx == NULL)
                 goto out;
         error = NULL;
         polkit_context_set_load_descriptions (ctx);
         if (!polkit_context_init (ctx, &error)) {
-                printf ("Init failed: %s\n", polkit_error_get_error_message (error));
+                fprintf (stderr, "Init failed: %s\n", polkit_error_get_error_message (error));
                 polkit_context_unref (ctx);
                 goto out;
         }
@@ -119,9 +146,21 @@ main (int argc, char *argv[])
                 goto out;
         }
 
-        polkit_policy_cache_foreach (cache, _print_entry, NULL);
+        if (action_id != NULL) {
+                PolKitPolicyFileEntry *pfe;
+                pfe = polkit_policy_cache_get_entry_by_id (cache, action_id);
+                if (pfe == NULL) {
+                        fprintf (stderr, "Cannot find policy file entry for action id '%s'\n", action_id);
+                        goto out;
+                }
+                _print_details_for_entry (pfe);
+        } else {
+                polkit_policy_cache_foreach (cache, _print_entry, NULL);
+        }
 
         polkit_context_unref (ctx);
+
+        ret = 0;
 out:
         return ret;
 }


More information about the hal-commit mailing list