PolicyKit: Branch 'master' - 2 commits

David Zeuthen david at kemper.freedesktop.org
Fri Apr 6 18:01:46 PDT 2007


 doc/man/polkit-privilege-file-validate.1.in |    9 -
 libpolkit/libpolkit-context.c               |  135 +++++++++++++++++++++++-----
 libpolkit/libpolkit-context.h               |   98 ++++++++++++++++++--
 libpolkit/libpolkit-privilege-cache.c       |    3 
 tools/polkit-check-caller.c                 |    8 -
 tools/polkit-check-session.c                |    8 -
 tools/polkit-privilege-file-validate.c      |  105 ++++++---------------
 7 files changed, 252 insertions(+), 114 deletions(-)

New commits:
diff-tree 6d42a04772497cb9ce37a33f46903fcaa60e574f (from 01b261ee507efe9b96ff8736127525b8abd39ecf)
Author: David Zeuthen <davidz at redhat.com>
Date:   Fri Apr 6 21:01:35 2007 -0400

    refine file monitoring interface and implement policy reload

diff --git a/libpolkit/libpolkit-context.c b/libpolkit/libpolkit-context.c
index b1cf968..79aa588 100644
--- a/libpolkit/libpolkit-context.c
+++ b/libpolkit/libpolkit-context.c
@@ -56,49 +56,98 @@
 struct PolKitContext
 {
         int refcount;
+
         PolKitContextConfigChangedCB config_changed_cb;
         gpointer config_changed_user_data;
 
+        PolKitContextFileMonitorAddWatch      file_monitor_add_watch_func;
+        PolKitContextFileMonitorRemoveWatch   file_monitor_remove_watch_func;
+
+        char *priv_dir;
+
         PolKitPrivilegeCache *priv_cache;
 };
 
 /**
  * libpolkit_context_new:
- * @error: return location for error
  * 
- * Create a new context; loads PolicyKit files from
- * /etc/PolicyKit/privileges unless the environment variable
- * $POLKIT_PRIVILEGE_DIR points to a location.
- *
- * If the environment $POLKIT_DEBUG is set, libpolkit will spew lots
- * of debug.
+ * Create a new context
  * 
- * Returns: #NULL if @error was set, otherwise the #PolKitPrivilegeCache object
+ * Returns: the #PolKitPrivilegeCache object
  **/
 PolKitContext *
-libpolkit_context_new (GError **error)
+libpolkit_context_new (void)
 {
-        const char *dirname;
         PolKitContext *pk_context;
         pk_context = g_new0 (PolKitContext, 1);
         pk_context->refcount = 1;
+        return pk_context;
+}
+
+static void
+_privilege_dir_events (PolKitContext                 *pk_context,
+                       PolKitContextFileMonitorEvent  event_mask,
+                       const char                    *path,
+                       gpointer                       user_data)
+{
+        /* mark cache of privilege files as stale.. (will be populated on-demand, see _get_cache()) */
+        if (pk_context->priv_cache != NULL) {
+                _pk_debug ("Something happened in %s - invalidating cache", pk_context->priv_dir);
+                libpolkit_privilege_cache_unref (pk_context->priv_cache);
+                pk_context->priv_cache = NULL;
+        }
+
+        /* signal that our configuration (may have) changed */
+        if (pk_context->config_changed_cb) {
+                pk_context->config_changed_cb (pk_context, pk_context->config_changed_user_data);
+        }
+}
+
+/**
+ * libpolkit_context_init:
+ * @pk_context: the context object
+ * @error: return location for error
+ * 
+ * Initializes a new context; loads PolicyKit files from
+ * /etc/PolicyKit/privileges unless the environment variable
+ * $POLKIT_PRIVILEGE_DIR points to a location.
+ *
+ * Returns: #FALSE if @error was set, otherwise #TRUE
+ **/
+gboolean
+libpolkit_context_init (PolKitContext *pk_context, GError **error)
+{
+        gboolean ret;
+        const char *dirname;
+
+        ret = FALSE;
 
         dirname = getenv ("POLKIT_PRIVILEGE_DIR");
         if (dirname != NULL) {
-                _pk_debug ("Using directory %s", dirname);
+                pk_context->priv_dir = g_strdup (dirname);
         } else {
-                dirname = PACKAGE_SYSCONF_DIR "/PolicyKit/privileges";
+                pk_context->priv_dir = g_strdup (PACKAGE_SYSCONF_DIR "/PolicyKit/privileges");
         }
+        _pk_debug ("Using privilege files from directory %s", pk_context->priv_dir);
 
-        pk_context->priv_cache = libpolkit_privilege_cache_new (dirname, error);
-        if (pk_context->priv_cache == NULL)
-                goto error;
-        libpolkit_privilege_cache_debug (pk_context->priv_cache);
+        /* don't populate the cache until it's needed.. */
 
-        return pk_context;
-error:
-        libpolkit_context_unref (pk_context);
-        return NULL;
+        if (pk_context->file_monitor_add_watch_func == NULL) {
+                _pk_debug ("No file monitor; cannot monitor '%s' for .priv file changes", dirname);
+        } else {
+                pk_context->file_monitor_add_watch_func (pk_context, 
+                                                         dirname,
+                                                         POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE|
+                                                         POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE|
+                                                         POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE,
+                                                         _privilege_dir_events,
+                                                         NULL);
+        }
+
+        /* right now we can't fail - but in the future modules we load may */
+
+        ret = TRUE;
+        return ret;
 }
 
 /**
@@ -144,7 +193,15 @@ libpolkit_context_unref (PolKitContext *
  * Register the callback function for when configuration changes.
  * Mechanisms should use this callback to e.g. reconfigure all
  * permissions / acl's they have set in response to policy decisions
- * made from information provided by PolicyKit.
+ * made from information provided by PolicyKit. 
+ *
+ * Note that this function may be called many times within a short
+ * interval due to how file monitoring works if e.g. the user is
+ * editing a configuration file (editors typically create back-up
+ * files). Mechanisms should use a "cool-off" timer (of, say, one
+ * second) to avoid doing many expensive operations (such as
+ * reconfiguring all ACL's for all devices) within a very short
+ * timeframe.
  **/
 void
 libpolkit_context_set_config_changed (PolKitContext                *pk_context, 
@@ -157,6 +214,25 @@ libpolkit_context_set_config_changed (Po
 }
 
 /**
+ * libpolkit_context_set_file_monitor:
+ * @pk_context: the context object
+ * @add_watch_func: the function that the PolicyKit library can invoke to start watching a file
+ * @remove_watch_func: the function that the PolicyKit library can invoke to stop watching a file
+ * 
+ * Register a functions that PolicyKit can use for watching files.
+ **/
+void
+libpolkit_context_set_file_monitor (PolKitContext                        *pk_context, 
+                                    PolKitContextFileMonitorAddWatch      add_watch_func,
+                                    PolKitContextFileMonitorRemoveWatch   remove_watch_func)
+{
+        g_return_if_fail (pk_context != NULL);
+        pk_context->file_monitor_add_watch_func = add_watch_func;
+        pk_context->file_monitor_remove_watch_func = remove_watch_func;
+}
+
+
+/**
  * libpolkit_context_get_privilege_cache:
  * @pk_context: the context
  * 
@@ -168,5 +244,22 @@ PolKitPrivilegeCache *
 libpolkit_context_get_privilege_cache (PolKitContext *pk_context)
 {
         g_return_val_if_fail (pk_context != NULL, NULL);
+
+        if (pk_context->priv_cache == NULL) {
+                GError *error;
+
+                _pk_debug ("Populating cache from directory %s", pk_context->priv_dir);
+
+                error = NULL;
+                pk_context->priv_cache = libpolkit_privilege_cache_new (pk_context->priv_dir, &error);
+                if (pk_context->priv_cache == NULL) {
+                        g_warning ("Error loading privilege files from %s: %s", 
+                                   pk_context->priv_dir, error->message);
+                        g_error_free (error);
+                } else {
+                        libpolkit_privilege_cache_debug (pk_context->priv_cache);
+                }
+        }
+
         return pk_context->priv_cache;
 }
diff --git a/libpolkit/libpolkit-context.h b/libpolkit/libpolkit-context.h
index bf34c40..33705ff 100644
--- a/libpolkit/libpolkit-context.h
+++ b/libpolkit/libpolkit-context.h
@@ -41,17 +41,101 @@ typedef struct PolKitContext PolKitConte
  * @pk_context: PolicyKit context
  * @user_data: user data
  *
- * See libpolkit_context_set_config_changed() for details.
+ * The type of the callback function for when configuration changes.
+ * Mechanisms should use this callback to e.g. reconfigure all
+ * permissions / acl's they have set in response to policy decisions
+ * made from information provided by PolicyKit.
+ *
+ * Note that this function may be called many times within a short
+ * interval due to how file monitoring works if e.g. the user is
+ * editing a configuration file (editors typically create back-up
+ * files). Mechanisms should use a "cool-off" timer (of, say, one
+ * second) to avoid doing many expensive operations (such as
+ * reconfiguring all ACL's for all devices) within a very short
+ * timeframe.
  */
 typedef void (*PolKitContextConfigChangedCB) (PolKitContext  *pk_context,
                                               gpointer        user_data);
 
-PolKitContext *libpolkit_context_new                (GError                      **error);
-PolKitContext *libpolkit_context_ref                (PolKitContext                *pk_context);
-void           libpolkit_context_set_config_changed (PolKitContext                *pk_context, 
-                                                     PolKitContextConfigChangedCB  cb, 
-                                                     gpointer                      user_data);
-void           libpolkit_context_unref              (PolKitContext                *pk_context);
+/**
+ * PolKitContextFileMonitorEvent:
+ * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_NONE: TODO
+ * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_ACCESS: watch when a file is accessed
+ * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE: watch when a file is created
+ * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE: watch when a file is deleted
+ * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE: watch when a file changes
+ *
+ * File monitoring events.
+ **/
+typedef enum
+{
+        POLKIT_CONTEXT_FILE_MONITOR_EVENT_NONE    = 1 << 0,
+        POLKIT_CONTEXT_FILE_MONITOR_EVENT_ACCESS  = 1 << 1,
+        POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE  = 1 << 2,
+        POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE  = 1 << 3,
+        POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE  = 1 << 4,
+} PolKitContextFileMonitorEvent;
+
+/**
+ * PolKitContextFileMonitorNotifyFunc:
+ * @pk_context: PolicyKit context
+ * @event_mask: event that happened
+ * @path: the path to the monitored file
+ * @user_data: the user data supplied to the function of type #PolKitContextFileMonitorAddWatch
+ *
+ * Callback when an event happens on a file that is monitored.
+ **/
+typedef void (*PolKitContextFileMonitorNotifyFunc) (PolKitContext                 *pk_context,
+                                                    PolKitContextFileMonitorEvent  event_mask,
+                                                    const char                    *path,
+                                                    gpointer                       user_data);
+
+/**
+ * PolKitContextFileMonitorAddWatch:
+ * @pk_context: PolicyKit context
+ * @path: path to file/directory to monitor for events
+ * @event_mask: events to look for
+ * @notify_cb: function to call on events
+ * @user_data: user data
+ *
+ * The type of a function that PolicyKit can use to watch file
+ * events. This function must call the supplied @notify_cb function
+ * (and pass @path and @user_data) on events
+ *
+ * Returns: A handle for the watch. If zero it means the file cannot
+ * be watched. Caller can remove the watch using the supplied function
+ * of type #PolKitContextFileMonitorRemoveWatch and the handle.
+ */
+typedef guint (*PolKitContextFileMonitorAddWatch) (PolKitContext                     *pk_context,
+                                                   const char                        *path,
+                                                   PolKitContextFileMonitorEvent      event_mask,
+                                                   PolKitContextFileMonitorNotifyFunc notify_cb,
+                                                   gpointer                           user_data);
+
+/**
+ * PolKitContextFileMonitorRemoveWatch:
+ * @pk_context: PolicyKit context
+ * @watch_id: the watch id
+ *
+ * The type of a function that PolicyKit can use to stop monitoring
+ * file events. Pass the handle obtained from the supplied function of
+ * type #PolKitContextFileMonitorAddWatch.
+ */
+typedef void (*PolKitContextFileMonitorRemoveWatch) (PolKitContext                     *pk_context,
+                                                     guint                              watch_id);
+
+
+PolKitContext *libpolkit_context_new                (void);
+gboolean       libpolkit_context_init               (PolKitContext                       *pk_context, 
+                                                     GError                             **error);
+PolKitContext *libpolkit_context_ref                (PolKitContext                        *pk_context);
+void           libpolkit_context_unref              (PolKitContext                        *pk_context);
+void           libpolkit_context_set_config_changed (PolKitContext                        *pk_context, 
+                                                     PolKitContextConfigChangedCB          cb, 
+                                                     gpointer                              user_data);
+void           libpolkit_context_set_file_monitor   (PolKitContext                        *pk_context, 
+                                                     PolKitContextFileMonitorAddWatch      add_watch_func,
+                                                     PolKitContextFileMonitorRemoveWatch   remove_watch_func);
 
 PolKitPrivilegeCache *libpolkit_context_get_privilege_cache (PolKitContext *pk_context);
 
diff --git a/libpolkit/libpolkit-privilege-cache.c b/libpolkit/libpolkit-privilege-cache.c
index 517de24..e9aeffa 100644
--- a/libpolkit/libpolkit-privilege-cache.c
+++ b/libpolkit/libpolkit-privilege-cache.c
@@ -111,6 +111,9 @@ libpolkit_privilege_cache_new (const cha
                 if (!g_str_has_suffix (file, ".priv"))
                         continue;
 
+                if (g_str_has_suffix (file, "."))
+                        continue;
+
                 path = g_strdup_printf ("%s/%s", dirname, file);
 
                 _pk_debug ("Loading %s", path);
diff-tree 01b261ee507efe9b96ff8736127525b8abd39ecf (from 936ca49edb4ea8efa15d336797a3d66269c9e1f4)
Author: David Zeuthen <davidz at redhat.com>
Date:   Fri Apr 6 21:01:14 2007 -0400

    make polkit-privilege-file-validate accept multiple files

diff --git a/doc/man/polkit-privilege-file-validate.1.in b/doc/man/polkit-privilege-file-validate.1.in
index 9c7ecc3..035f881 100644
--- a/doc/man/polkit-privilege-file-validate.1.in
+++ b/doc/man/polkit-privilege-file-validate.1.in
@@ -8,7 +8,7 @@ polkit-privilege-file-validate \- check 
 .SH SYNOPSIS
 .PP
 .B polkit-privilege-file-validate
-[options]
+<privilege-files>
 
 .SH DESCRIPTION
 
@@ -23,9 +23,6 @@ depending on the distribution.
 .SH OPTIONS
 The following options are supported:
 .TP
-.I "--file"
-File to validate.
-.TP
 .I "--help"
 Print out usage.
 .TP
@@ -34,8 +31,8 @@ Print the version.
 
 .SH RETURN VALUE
 .PP
-If the file validates, this program exits with exit code 0. Otherwise
-the program exits with a non-zero exit code.
+If the given files are all valid, this program exits with exit code
+0. Otherwise the program exits with a non-zero exit code.
 
 .SH BUGS
 .PP
diff --git a/tools/polkit-check-caller.c b/tools/polkit-check-caller.c
index e9e7715..d1f53aa 100644
--- a/tools/polkit-check-caller.c
+++ b/tools/polkit-check-caller.c
@@ -130,7 +130,7 @@ main (int argc, char *argv[])
 	}
 
 	if (is_version) {
-		printf ("pk-can-caller-access-resource " PACKAGE_VERSION "\n");
+		printf ("polkit-check-caller " PACKAGE_VERSION "\n");
 		return 0;
 	}
 
@@ -147,9 +147,9 @@ main (int argc, char *argv[])
 	}
 
         g_error = NULL;
-        pol_ctx = libpolkit_context_new (&g_error);
-        if (pol_ctx == NULL) {
-		fprintf (stderr, "error: libpolkit_context_new: %s\n", g_error->message);
+        pol_ctx = libpolkit_context_new ();
+        if (!libpolkit_context_init (pol_ctx, &g_error)) {
+		fprintf (stderr, "error: libpolkit_context_init: %s\n", g_error->message);
                 g_error_free (g_error);
                 return 1;
         }
diff --git a/tools/polkit-check-session.c b/tools/polkit-check-session.c
index 8ee2932..d6ee164 100644
--- a/tools/polkit-check-session.c
+++ b/tools/polkit-check-session.c
@@ -133,7 +133,7 @@ main (int argc, char *argv[])
 	}
 
 	if (is_version) {
-		printf ("pk-can-caller-access-resource " PACKAGE_VERSION "\n");
+		printf ("polkit-check-session " PACKAGE_VERSION "\n");
 		return 0;
 	}
 
@@ -150,9 +150,9 @@ main (int argc, char *argv[])
 	}
 
         g_error = NULL;
-        pol_ctx = libpolkit_context_new (&g_error);
-        if (pol_ctx == NULL) {
-		fprintf (stderr, "error: libpolkit_context_new: %s\n", g_error->message);
+        pol_ctx = libpolkit_context_new ();
+        if (!libpolkit_context_init (pol_ctx, &g_error)) {
+		fprintf (stderr, "error: libpolkit_context_init: %s\n", g_error->message);
                 g_error_free (g_error);
                 return 1;
         }
diff --git a/tools/polkit-privilege-file-validate.c b/tools/polkit-privilege-file-validate.c
index f4ea857..cf3b1f5 100644
--- a/tools/polkit-privilege-file-validate.c
+++ b/tools/polkit-privilege-file-validate.c
@@ -42,96 +42,57 @@ usage (int argc, char *argv[])
 {
 	fprintf (stderr,
                  "\n"
-                 "usage : polkit-privilege-file-validate --file <privilege-file>\n"
+                 "usage : polkit-privilege-file-validate <privilege-files>\n"
                  "        [--version] [--help]\n");
 	fprintf (stderr,
                  "\n"
-                 "        --file           File to validate\n"
                  "        --version        Show version and exit\n"
                  "        --help           Show this information and exit\n"
                  "\n"
-                 "Validates a PolicyKit privilege file. Returns 0 if it validates. If\n"
-                 "not, the program exits with a non-zero exit code.\n");
+                 "Validates one or more PolicyKit privilege file. Returns 0 if it validates.\n"
+                 "If not, the program exits with a non-zero exit code.\n");
 }
 
-int
-main (int argc, char *argv[])
+static gboolean
+validate_file (const char *file)
 {
-        char *file = NULL;
-        gboolean is_version = FALSE;
-        gboolean validated;
         PolKitPrivilegeFile *priv_file;
         GError *error = NULL;
 
-        validated = FALSE;
-
-	if (argc <= 1) {
-		usage (argc, argv);
-                goto out;
-	}
-
-	while (1) {
-		int c;
-		int option_index = 0;
-		const char *opt;
-		static struct option long_options[] = {
-			{"file", 1, NULL, 0},
-			{"version", 0, NULL, 0},
-			{"help", 0, NULL, 0},
-			{NULL, 0, NULL, 0}
-		};
-
-		c = getopt_long (argc, argv, "",
-				 long_options, &option_index);
-		if (c == -1)
-			break;
-
-		switch (c) {
-		case 0:
-			opt = long_options[option_index].name;
-
-			if (strcmp (opt, "help") == 0) {
-				usage (argc, argv);
-				return 0;
-			} else if (strcmp (opt, "version") == 0) {
-				is_version = TRUE;
-			} else if (strcmp (opt, "file") == 0) {
-                                file = g_strdup (optarg);
-			}
-			break;
-
-		default:
-			usage (argc, argv);
-                        goto out;
-		}
-	}
-
-	if (is_version) {
-		printf ("pk-privilege-file-validate " PACKAGE_VERSION "\n");
-                return 0;
-	}
-
-	if (file == NULL) {
-		usage (argc, argv);
-                goto out;
-	}
-
         priv_file = libpolkit_privilege_file_new (file, &error);
         if (priv_file == NULL) {
                 printf ("%s did not validate: %s\n", file, error->message);
                 g_error_free (error);
-                goto out;
+                return FALSE;
         }
-
-        validated = TRUE;
         libpolkit_privilege_file_unref (priv_file);
+        return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+        int n;
 
-out:
-        if (file != NULL)
-                g_free (file);
-
-        if (validated)
-                return 0;
-        else
+	if (argc <= 1) {
+		usage (argc, argv);
                 return 1;
+	}
+
+        for (n = 1; n < argc; n++) {
+                if (strcmp (argv[n], "--help") == 0) {
+                        usage (argc, argv);
+                        return 0;
+                }
+                if (strcmp (argv[n], "--version") == 0) {
+                        printf ("polkit-privilege-file-validate " PACKAGE_VERSION "\n");
+                        return 0;
+                }
+
+                if (!validate_file (argv[n])) {
+                        return 1;
+                }
+	}
+
+        return 0;
 }


More information about the hal-commit mailing list