PolicyKit: Branch 'master' - 2 commits

David Zeuthen david at kemper.freedesktop.org
Wed Apr 4 13:26:35 PDT 2007


 doc/api/libpolkit/libpolkit-docs.xml   |    2 
 libpolkit/Makefile.am                  |   24 ++-
 libpolkit/libpolkit-error.c            |   61 +++++++++
 libpolkit/libpolkit-error.h            |   53 ++++++++
 libpolkit/libpolkit-privilege-file.c   |  211 +++++++++++++++++++++++++++++++++
 libpolkit/libpolkit-privilege-file.h   |   43 ++++++
 libpolkit/libpolkit-result.c           |  118 ++++++++++++++++++
 libpolkit/libpolkit-result.h           |   72 +++++++++++
 libpolkit/libpolkit.c                  |   37 +++--
 libpolkit/libpolkit.h                  |   13 --
 tools/Makefile.am                      |    6 
 tools/polkit-privilege-file-validate.c |  137 +++++++++++++++++++++
 12 files changed, 746 insertions(+), 31 deletions(-)

New commits:
diff-tree 6451bbb85b2d8636f6e3197e8f62484ce1cfd8e4 (from 4de5d6c6d44b8cbe46530648e53d006b24b8942d)
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Apr 4 16:26:20 2007 -0400

    introduce a PolKitResult enumeration and make privilege files use that

diff --git a/doc/api/libpolkit/libpolkit-docs.xml b/doc/api/libpolkit/libpolkit-docs.xml
index d8f2c63..cf1c896 100644
--- a/doc/api/libpolkit/libpolkit-docs.xml
+++ b/doc/api/libpolkit/libpolkit-docs.xml
@@ -65,6 +65,8 @@
       </para>
     </partintro>
     <xi:include href="xml/libpolkit.xml"/>
+    <xi:include href="xml/libpolkit-error.xml"/>
+    <xi:include href="xml/libpolkit-result.xml"/>
     <xi:include href="xml/libpolkit-context.xml"/>
     <xi:include href="xml/libpolkit-privilege.xml"/>
     <xi:include href="xml/libpolkit-resource.xml"/>
diff --git a/libpolkit/Makefile.am b/libpolkit/Makefile.am
index 37c979a..b65a9fd 100644
--- a/libpolkit/Makefile.am
+++ b/libpolkit/Makefile.am
@@ -17,6 +17,8 @@ libpolkitincludedir=$(includedir)/Policy
 
 libpolkitinclude_HEADERS =              		\
 	libpolkit.h					\
+	libpolkit-error.h				\
+	libpolkit-result.h				\
 	libpolkit-context.h				\
 	libpolkit-privilege.h				\
 	libpolkit-resource.h				\
@@ -27,6 +29,8 @@ libpolkitinclude_HEADERS =              
 
 libpolkit_la_SOURCES =                  	              		\
 	libpolkit.h			libpolkit.c			\
+	libpolkit-error.h		libpolkit-error.c		\
+	libpolkit-result.h		libpolkit-result.c		\
 	libpolkit-context.h		libpolkit-context.c		\
 	libpolkit-privilege.h		libpolkit-privilege.c		\
 	libpolkit-resource.h		libpolkit-resource.c		\
diff --git a/libpolkit/libpolkit-error.c b/libpolkit/libpolkit-error.c
new file mode 100644
index 0000000..7e6ed8d
--- /dev/null
+++ b/libpolkit/libpolkit-error.c
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-error.c : GError error codes from PolicyKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ **************************************************************************/
+
+/**
+ * SECTION:libpolkit-error
+ * @short_description: Error codes from PolicyKit.
+ *
+ * Error codes from PolicyKit.
+ **/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include "libpolkit-error.h"
+
+
+/**
+ * libpolkit_error_quark:
+ * 
+ * Returns error domain for PolicyKit library.
+ * 
+ * Returns: The error domain
+ **/
+GQuark
+libpolkit_error_quark (void)
+{
+        return g_quark_from_static_string ("libpolkit-error-quark");
+}
diff --git a/libpolkit/libpolkit-error.h b/libpolkit/libpolkit-error.h
new file mode 100644
index 0000000..53d5be9
--- /dev/null
+++ b/libpolkit/libpolkit-error.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-error.h : GError error codes from PolicyKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_ERROR_H
+#define LIBPOLKIT_ERROR_H
+
+#include <glib.h>
+
+/**
+ * PolKitError:
+ * @POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE: There was an error parsing the given privilege file
+ *
+ * Error codes returned by PolicyKit
+ */
+typedef enum
+{      
+        POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE
+} PolKitError;
+
+/**
+ * POLKIT_ERROR:
+ *
+ * Error domain for PolicyKit library. Errors in this domain will be
+ * from the #PolKitError enumeration. See GError for details.
+ **/
+#define POLKIT_ERROR libpolkit_error_quark()
+
+GQuark libpolkit_error_quark (void);
+
+
+#endif /* LIBPOLKIT_RESULT_H */
diff --git a/libpolkit/libpolkit-privilege-file.c b/libpolkit/libpolkit-privilege-file.c
index eadbe1a..f414c48 100644
--- a/libpolkit/libpolkit-privilege-file.c
+++ b/libpolkit/libpolkit-privilege-file.c
@@ -37,7 +37,8 @@
 #include <errno.h>
 
 #include <glib.h>
-#include "libpolkit.h"
+#include "libpolkit-error.h"
+#include "libpolkit-result.h"
 #include "libpolkit-privilege-file.h"
 
 /**
@@ -47,16 +48,6 @@
  * This class is used to represent a privilege files.
  **/
 
-typedef enum
-{
-        LIBPOLKIT_RESULT_YES               = 1<<0,
-        LIBPOLKIT_RESULT_NO                = 1<<1,
-        LIBPOLKIT_RESULT_AUTH_REQ_ROOT     = 1<<2,
-        LIBPOLKIT_RESULT_AUTH_REQ_SELF     = 1<<3,
-        LIBPOLKIT_RESULT_AUTH_KEEP_SESSION = 1<<4,
-        LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS  = 1<<5
-} PolKitResult;
-
 /**
  * PolKitPrivilegeFile:
  *
@@ -81,34 +72,34 @@ parse_default (const char *key, char *s,
 {
         gboolean ret;
 
-        ret = TRUE;
+        ret = libpolkit_result_from_string_representation (s, target);
+        if (!ret) {
+                int n;
+                char *s2;
+                GString *str;
+
+                str = g_string_new (NULL);
+                for (n = 0; n < LIBPOLKIT_RESULT_N_RESULTS; n++) {
+                        if (n == LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW)
+                                continue;
+
+                        if (str->len > 0) {
+                                g_string_append (str, ", ");
+                        }
+                        g_string_append (str, libpolkit_result_to_string_representation (n));
+                }
+                s2 = g_string_free (str, FALSE);
 
-        if (strcmp (s, "yes") == 0) {
-                *target = LIBPOLKIT_RESULT_YES;
-        } else if (strcmp (s, "no") == 0) {
-                *target = LIBPOLKIT_RESULT_NO;
-        } else if (strcmp (s, "auth_root") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT;
-        } else if (strcmp (s, "auth_root_keep_session") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT | LIBPOLKIT_RESULT_AUTH_KEEP_SESSION;
-        } else if (strcmp (s, "auth_root_keep_always") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT | LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS;
-        } else if (strcmp (s, "auth_self") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF;
-        } else if (strcmp (s, "auth_self_keep_session") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF | LIBPOLKIT_RESULT_AUTH_KEEP_SESSION;
-        } else if (strcmp (s, "auth_self_keep_always") == 0) {
-                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF | LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS;
-        } else {
                 g_set_error (error, 
                              POLKIT_ERROR, 
                              POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE,
-                             "Value %s is not allowed for key %s - supported values are 'yes', 'no', 'auth_root', 'auth_root_keep_session', 'auth_root_keep_always', 'auth_self', 'auth_self_keep_session', 'auth_self_keep_always'", 
+                             "Value %s is not allowed for key %s - supported values are: %s", 
                              s, 
-                             key);
-                ret = FALSE;
+                             key,
+                             s2);
+                g_free (s2);
         }
-
+        
         g_free (s);
         return ret;
 }
@@ -183,7 +174,7 @@ error:
 
 /**
  * libpolkit_privilege_file_ref:
- * @privilege: the privilege object
+ * @privilege_file: the privilege file object
  * 
  * Increase reference count.
  * 
@@ -199,7 +190,7 @@ libpolkit_privilege_file_ref (PolKitPriv
 
 /**
  * libpolkit_privilege_file_unref:
- * @privilege: the privilege object
+ * @privilege_file: the privilege file object
  * 
  * Decreases the reference count of the object. If it becomes zero,
  * the object is freed. Before freeing, reference counts on embedded
diff --git a/libpolkit/libpolkit-result.c b/libpolkit/libpolkit-result.c
new file mode 100644
index 0000000..b04dc10
--- /dev/null
+++ b/libpolkit/libpolkit-result.c
@@ -0,0 +1,118 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-result.c : result codes from PolicyKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ **************************************************************************/
+
+/**
+ * SECTION:libpolkit-result
+ * @short_description: Result of PolicyKit queries
+ *
+ * These functions are used to manipulate PolicyKit results.
+ **/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include "libpolkit-result.h"
+
+
+static const struct {
+        PolKitResult result;
+        const char *str;
+} mapping[] = 
+{
+        {LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW, "not_authorized"},
+        {LIBPOLKIT_RESULT_YES, "yes"},
+        {LIBPOLKIT_RESULT_NO, "no"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH, "auth_root"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION, "auth_root_keep_session"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS, "auth_root_keep_always"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH, "auth_self"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION, "auth_self_keep_session"},
+        {LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS, "auth_self_keep_always"},
+        {0, NULL}
+};
+
+
+/**
+ * libpolkit_result_to_string_representation:
+ * @result: the given result to get a textual representation of
+ * 
+ * Gives a textual representation of a #PolKitResult object.
+ * 
+ * Returns: string representing the result (do not free) or #NULL if the given result is invalid
+ **/
+const char *
+libpolkit_result_to_string_representation (PolKitResult result)
+{
+        if (result < 0 || result >= LIBPOLKIT_RESULT_N_RESULTS) {
+                g_warning ("The passed result code, %d, is not valid", result);
+                return NULL;
+        }
+
+        return mapping[result].str;
+}
+
+/**
+ * libpolkit_result_from_string_representation:
+ * @string: textual representation of a #PolKitResult object
+ * @out_result: return location for #PolKitResult
+ * 
+ * Given a textual representation of a #PolKitResult object, find the #PolKitResult value.
+ * 
+ * Returns: TRUE if the textual representation was valid, otherwise FALSE
+ **/
+gboolean
+libpolkit_result_from_string_representation (const char *string, PolKitResult *out_result)
+{
+        int n;
+
+        g_return_val_if_fail (out_result != NULL, FALSE);
+
+        for (n = 0; n < LIBPOLKIT_RESULT_N_RESULTS; n++) {
+                if (mapping[n].str == NULL)
+                        break;
+                if (strcmp (mapping[n].str, string) == 0) {
+                        *out_result = mapping[n].result;
+                        goto found;
+                }
+        }
+
+        /* don't print a warning; this is used by polkit-privilege-file-validate */
+        return FALSE;
+
+found:
+        return TRUE;
+
+}
diff --git a/libpolkit/libpolkit-result.h b/libpolkit/libpolkit-result.h
new file mode 100644
index 0000000..b5b7ed6
--- /dev/null
+++ b/libpolkit/libpolkit-result.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-result.h : result codes from PolicyKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_RESULT_H
+#define LIBPOLKIT_RESULT_H
+
+#include <glib.h>
+
+/**
+ * PolKitResult:
+ * @LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW: The caller of libpolkit is not sufficiently privilege to know the answer.
+ * @LIBPOLKIT_RESULT_YES: Access granted.
+ * @LIBPOLKIT_RESULT_NO: Access denied.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH: Access denied, but authentication of the caller as 
+ * root will grant access to only that caller.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION: Access denied, but authentication of the caller as
+ * root will grant access for the remainder of the session the caller stems from.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS: Access denied, but authentication of the caller as
+ * root will grant access to the user of the caller in the future.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH: Access denied, but authentication of the caller as 
+ * his user will grant access to only that caller.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION: Access denied, but authentication of the caller as
+ * his user will grant access for the remainder of the session the caller stems from.
+ * @LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS: Access denied, but authentication of the caller as
+ * his user will grant access to the user of the caller in the future.
+ * @LIBPOLKIT_RESULT_N_RESULTS: Number of result codes
+ *
+ * Result codes from queries to PolicyKit.
+ */
+typedef enum
+{
+        LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
+        LIBPOLKIT_RESULT_YES,
+        LIBPOLKIT_RESULT_NO,
+        LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH,
+        LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_SESSION,
+        LIBPOLKIT_RESULT_ONLY_VIA_ROOT_AUTH_KEEP_ALWAYS,
+        LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH,
+        LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_SESSION,
+        LIBPOLKIT_RESULT_ONLY_VIA_SELF_AUTH_KEEP_ALWAYS,
+        LIBPOLKIT_RESULT_N_RESULTS
+} PolKitResult;
+
+const char *
+libpolkit_result_to_string_representation (PolKitResult result);
+
+gboolean
+libpolkit_result_from_string_representation (const char *string, PolKitResult *out_result);
+
+#endif /* LIBPOLKIT_RESULT_H */
diff --git a/libpolkit/libpolkit.c b/libpolkit/libpolkit.c
index bf521ea..9b03ba5 100644
--- a/libpolkit/libpolkit.c
+++ b/libpolkit/libpolkit.c
@@ -61,12 +61,20 @@
  * Typically, this information is used to e.g. bootstrap the system
  * insofar that it can be used to start login greeters on the given
  * video hardware (e.g. resources) on the given user-configured seats.
+ *
+ * If a resource is not associated with any seat, it is assumed to be
+ * available to any local seat.
+ *
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW or
+ * #LIBPOLKIT_RESULT_YES (if the callback was invoked)
  */
-void
+PolKitResult
 libpolkit_get_seat_resource_association (PolKitContext       *pk_context,
                                          PolKitSeatVisitorCB  visitor,
                                          gpointer            *user_data)
 {
+        return LIBPOLKIT_RESULT_YES;
 }
 
 /**
@@ -79,15 +87,16 @@ libpolkit_get_seat_resource_association 
  * same comments noted in libpolkit_get_seat_resource_association() about the
  * source purely being user configuration applies here as well.
  *
- * Returns: TRUE if, and only if, the given resource is
- * associated with the given seat.
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
+ * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
  */
-gboolean
+PolKitResult
 libpolkit_is_resource_associated_with_seat (PolKitContext   *pk_context,
                                             PolKitResource  *resource,
                                             PolKitSeat      *seat)
 {
-        return FALSE;
+        return LIBPOLKIT_RESULT_NO;
 }
 
 /**
@@ -99,16 +108,17 @@ libpolkit_is_resource_associated_with_se
  *
  * Determine if a given session can access a given resource in a given way.
  *
- * Returns: TRUE if, and only if, the given session can access the
- * given resource in the given way.
+ * Returns: A #PolKitResult - can only be one of
+ * #LIBPOLKIT_RESULT_NOT_AUTHORIZED_TO_KNOW,
+ * #LIBPOLKIT_RESULT_YES, #LIBPOLKIT_RESULT_NO.
  */
-gboolean
+PolKitResult
 libpolkit_can_session_access_resource (PolKitContext   *pk_context,
                                        PolKitPrivilege *privilege,
                                        PolKitResource  *resource,
                                        PolKitSession   *session)
 {
-        return FALSE;
+        return LIBPOLKIT_RESULT_NO;
 }
 
 /**
@@ -120,20 +130,14 @@ libpolkit_can_session_access_resource (P
  *
  * Determine if a given caller can access a given resource in a given way.
  *
- * Returns: TRUE if, and only if, the given caller can access the
- * given resource in the given way.
+ * Returns: A #PolKitResult specifying if, and how, the caller can
+ * access the resource in the given way
  */
-gboolean
+PolKitResult
 libpolkit_can_caller_access_resource (PolKitContext   *pk_context,
                                       PolKitPrivilege *privilege,
                                       PolKitResource  *resource,
                                       PolKitCaller    *caller)
 {
-        return FALSE;
-}
-
-GQuark
-libpolkit_error_quark (void)
-{
-        return g_quark_from_static_string ("libpolkit-error-quark");
+        return LIBPOLKIT_RESULT_NO;
 }
diff --git a/libpolkit/libpolkit.h b/libpolkit/libpolkit.h
index 7e3fa68..1fed4f1 100644
--- a/libpolkit/libpolkit.h
+++ b/libpolkit/libpolkit.h
@@ -31,6 +31,8 @@
 #include <sys/types.h>
 #include <glib.h>
 
+#include <libpolkit/libpolkit-error.h>
+#include <libpolkit/libpolkit-result.h>
 #include <libpolkit/libpolkit-context.h>
 #include <libpolkit/libpolkit-privilege.h>
 #include <libpolkit/libpolkit-resource.h>
@@ -38,8 +40,6 @@
 #include <libpolkit/libpolkit-session.h>
 #include <libpolkit/libpolkit-caller.h>
 
-
-
 /**
  * PolKitSeatVisitorCB:
  * @seat: the seat
@@ -47,43 +47,33 @@
  * @user_data: user data
  *
  * Visitor function for libpolkit_get_seat_resource_association(). The caller should _not_ unref the passed objects.
- *
  */
 typedef void (*PolKitSeatVisitorCB) (PolKitSeat      *seat,
                                      PolKitResource **resources_associated_with_seat,
                                      gpointer         user_data);
 
-void
+PolKitResult
 libpolkit_get_seat_resource_association (PolKitContext       *pk_context,
                                          PolKitSeatVisitorCB  visitor,
                                          gpointer            *user_data);
 
-gboolean
+PolKitResult
 libpolkit_is_resource_associated_with_seat (PolKitContext   *pk_context,
                                             PolKitResource  *resource,
                                             PolKitSeat      *seat);
 
-gboolean
+PolKitResult
 libpolkit_can_session_access_resource (PolKitContext   *pk_context,
                                        PolKitPrivilege *privilege,
                                        PolKitResource  *resource,
                                        PolKitSession   *session);
 
-gboolean
+PolKitResult
 libpolkit_can_caller_access_resource (PolKitContext   *pk_context,
                                       PolKitPrivilege *privilege,
                                       PolKitResource  *resource,
                                       PolKitCaller    *caller);
 
-typedef enum
-{
-        POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE
-} PolKitError;
-
-#define POLKIT_ERROR libpolkit_error_quark()
-
-GQuark libpolkit_error_quark (void);
-
 #endif /* LIBPOLKIT_H */
 
 
diff-tree 4de5d6c6d44b8cbe46530648e53d006b24b8942d (from 3df61e0e3fe823b1381f4744bea6ee19d7e1d055)
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Apr 4 03:08:09 2007 -0400

    add support for privilege files and provide a validation tool

diff --git a/libpolkit/Makefile.am b/libpolkit/Makefile.am
index 0c013e5..37c979a 100644
--- a/libpolkit/Makefile.am
+++ b/libpolkit/Makefile.am
@@ -22,16 +22,18 @@ libpolkitinclude_HEADERS =              
 	libpolkit-resource.h				\
 	libpolkit-seat.h				\
 	libpolkit-session.h				\
-	libpolkit-caller.h
+	libpolkit-caller.h				\
+	libpolkit-privilege-file.h
 
-libpolkit_la_SOURCES =                                	\
-	libpolkit.h		libpolkit.c		\
-	libpolkit-context.h	libpolkit-context.c	\
-	libpolkit-privilege.h	libpolkit-privilege.c	\
-	libpolkit-resource.h	libpolkit-resource.c	\
-	libpolkit-seat.h	libpolkit-seat.c	\
-	libpolkit-session.h	libpolkit-session.c	\
-	libpolkit-caller.h	libpolkit-caller.c
+libpolkit_la_SOURCES =                  	              		\
+	libpolkit.h			libpolkit.c			\
+	libpolkit-context.h		libpolkit-context.c		\
+	libpolkit-privilege.h		libpolkit-privilege.c		\
+	libpolkit-resource.h		libpolkit-resource.c		\
+	libpolkit-seat.h		libpolkit-seat.c		\
+	libpolkit-session.h		libpolkit-session.c		\
+	libpolkit-caller.h		libpolkit-caller.c		\
+	libpolkit-privilege-file.h	libpolkit-privilege-file.c
 
 libpolkit_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@
 
diff --git a/libpolkit/libpolkit-privilege-file.c b/libpolkit/libpolkit-privilege-file.c
new file mode 100644
index 0000000..eadbe1a
--- /dev/null
+++ b/libpolkit/libpolkit-privilege-file.c
@@ -0,0 +1,220 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-privilege-file.c : privilege files
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+#include "libpolkit.h"
+#include "libpolkit-privilege-file.h"
+
+/**
+ * SECTION:libpolkit-privilege-file
+ * @short_description: Privileges files.
+ *
+ * This class is used to represent a privilege files.
+ **/
+
+typedef enum
+{
+        LIBPOLKIT_RESULT_YES               = 1<<0,
+        LIBPOLKIT_RESULT_NO                = 1<<1,
+        LIBPOLKIT_RESULT_AUTH_REQ_ROOT     = 1<<2,
+        LIBPOLKIT_RESULT_AUTH_REQ_SELF     = 1<<3,
+        LIBPOLKIT_RESULT_AUTH_KEEP_SESSION = 1<<4,
+        LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS  = 1<<5
+} PolKitResult;
+
+/**
+ * PolKitPrivilegeFile:
+ *
+ * Objects of this class are used to record information about a
+ * privilege.
+ **/
+struct PolKitPrivilegeFile
+{
+        int refcount;
+        char *group;
+        char *identifier;
+        char *description;
+
+        PolKitResult default_remote_inactive;
+        PolKitResult default_remote_active;
+        PolKitResult default_local_inactive;
+        PolKitResult default_local_active;
+};
+
+static gboolean
+parse_default (const char *key, char *s, PolKitResult* target, GError **error)
+{
+        gboolean ret;
+
+        ret = TRUE;
+
+        if (strcmp (s, "yes") == 0) {
+                *target = LIBPOLKIT_RESULT_YES;
+        } else if (strcmp (s, "no") == 0) {
+                *target = LIBPOLKIT_RESULT_NO;
+        } else if (strcmp (s, "auth_root") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT;
+        } else if (strcmp (s, "auth_root_keep_session") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT | LIBPOLKIT_RESULT_AUTH_KEEP_SESSION;
+        } else if (strcmp (s, "auth_root_keep_always") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_ROOT | LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS;
+        } else if (strcmp (s, "auth_self") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF;
+        } else if (strcmp (s, "auth_self_keep_session") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF | LIBPOLKIT_RESULT_AUTH_KEEP_SESSION;
+        } else if (strcmp (s, "auth_self_keep_always") == 0) {
+                *target = LIBPOLKIT_RESULT_NO | LIBPOLKIT_RESULT_AUTH_REQ_SELF | LIBPOLKIT_RESULT_AUTH_KEEP_ALWAYS;
+        } else {
+                g_set_error (error, 
+                             POLKIT_ERROR, 
+                             POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE,
+                             "Value %s is not allowed for key %s - supported values are 'yes', 'no', 'auth_root', 'auth_root_keep_session', 'auth_root_keep_always', 'auth_self', 'auth_self_keep_session', 'auth_self_keep_always'", 
+                             s, 
+                             key);
+                ret = FALSE;
+        }
+
+        g_free (s);
+        return ret;
+}
+
+/**
+ * libpolkit_privilege_file_new:
+ * @path: path to privilege file
+ * @error: return location for error
+ * 
+ * Create a new #PolKitPrivilegeFile object. If the file does not
+ * validate, a human readable explanation of why will be set in
+ * @error.
+ * 
+ * Returns: the new object or #NULL if error is set
+ **/
+PolKitPrivilegeFile *
+libpolkit_privilege_file_new (const char *path, GError **error)
+{
+        GKeyFile *key_file;
+        PolKitPrivilegeFile *pf;
+        char *s;
+        const char *key;
+        const char *group;
+
+        pf = NULL;
+
+        key_file = g_key_file_new ();
+        if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, error))
+                goto error;
+
+        pf = g_new0 (PolKitPrivilegeFile, 1);
+        pf->refcount = 1;
+
+        group = "Privilege";
+        if ((pf->group = g_key_file_get_string (key_file, group, "Group", error)) == NULL)
+                goto error;
+        if ((pf->identifier = g_key_file_get_string (key_file, group, "Identifier", error)) == NULL)
+                goto error;
+        if ((pf->description = g_key_file_get_string (key_file, group, "Description", error)) == NULL)
+                goto error;
+
+        group = "Defaults";
+        key = "AllowRemoteInactive";
+        if ((s = g_key_file_get_string (key_file, group, key, error)) == NULL)
+                goto error;
+        if (!parse_default (key, s, &pf->default_remote_inactive, error))
+                goto error;
+        key = "AllowRemoteActive";
+        if ((s = g_key_file_get_string (key_file, group, key, error)) == NULL)
+                goto error;
+        if (!parse_default (key, s, &pf->default_remote_active, error))
+                goto error;
+        key = "AllowLocalInactive";
+        if ((s = g_key_file_get_string (key_file, group, key, error)) == NULL)
+                goto error;
+        if (!parse_default (key, s, &pf->default_local_inactive, error))
+                goto error;
+        key = "AllowLocalActive";
+        if ((s = g_key_file_get_string (key_file, group, key, error)) == NULL)
+                goto error;
+        if (!parse_default (key, s, &pf->default_local_active, error))
+                goto error;
+
+        g_key_file_free (key_file);
+        return pf;
+error:
+        g_key_file_free (key_file);
+        if (pf != NULL)
+                libpolkit_privilege_file_unref (pf);
+        return NULL;
+}
+
+/**
+ * libpolkit_privilege_file_ref:
+ * @privilege: the privilege object
+ * 
+ * Increase reference count.
+ * 
+ * Returns: the object
+ **/
+PolKitPrivilegeFile *
+libpolkit_privilege_file_ref (PolKitPrivilegeFile *privilege_file)
+{
+        g_return_val_if_fail (privilege_file != NULL, privilege_file);
+        privilege_file->refcount++;
+        return privilege_file;
+}
+
+/**
+ * libpolkit_privilege_file_unref:
+ * @privilege: the privilege object
+ * 
+ * Decreases the reference count of the object. If it becomes zero,
+ * the object is freed. Before freeing, reference counts on embedded
+ * objects are decresed by one.
+ **/
+void
+libpolkit_privilege_file_unref (PolKitPrivilegeFile *privilege_file)
+{
+        g_return_if_fail (privilege_file != NULL);
+        privilege_file->refcount--;
+        if (privilege_file->refcount > 0) 
+                return;
+        g_free (privilege_file->group);
+        g_free (privilege_file->identifier);
+        g_free (privilege_file->description);
+        g_free (privilege_file);
+}
+
diff --git a/libpolkit/libpolkit-privilege-file.h b/libpolkit/libpolkit-privilege-file.h
new file mode 100644
index 0000000..b536915
--- /dev/null
+++ b/libpolkit/libpolkit-privilege-file.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * libpolkit-privilege-file.h : privilege files
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifndef LIBPOLKIT_PRIVILEGE_FILE_H
+#define LIBPOLKIT_PRIVILEGE_FILE_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <glib.h>
+
+struct PolKitPrivilegeFile;
+typedef struct PolKitPrivilegeFile PolKitPrivilegeFile;
+
+PolKitPrivilegeFile *libpolkit_privilege_file_new   (const char          *path, GError **error);
+PolKitPrivilegeFile *libpolkit_privilege_file_ref   (PolKitPrivilegeFile *privilege_file);
+void                 libpolkit_privilege_file_unref (PolKitPrivilegeFile *privilege_file);
+
+#endif /* LIBPOLKIT_PRIVILEGE_FILE_H */
+
+
diff --git a/libpolkit/libpolkit.c b/libpolkit/libpolkit.c
index 2a1ff3c..bf521ea 100644
--- a/libpolkit/libpolkit.c
+++ b/libpolkit/libpolkit.c
@@ -132,3 +132,8 @@ libpolkit_can_caller_access_resource (Po
         return FALSE;
 }
 
+GQuark
+libpolkit_error_quark (void)
+{
+        return g_quark_from_static_string ("libpolkit-error-quark");
+}
diff --git a/libpolkit/libpolkit.h b/libpolkit/libpolkit.h
index 59c0352..7e3fa68 100644
--- a/libpolkit/libpolkit.h
+++ b/libpolkit/libpolkit.h
@@ -75,6 +75,15 @@ libpolkit_can_caller_access_resource (Po
                                       PolKitResource  *resource,
                                       PolKitCaller    *caller);
 
+typedef enum
+{
+        POLKIT_ERROR_PRIVILEGE_FILE_INVALID_VALUE
+} PolKitError;
+
+#define POLKIT_ERROR libpolkit_error_quark()
+
+GQuark libpolkit_error_quark (void);
+
 #endif /* LIBPOLKIT_H */
 
 
diff --git a/tools/Makefile.am b/tools/Makefile.am
index f4b443d..07c542d 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -11,7 +11,7 @@ INCLUDES = \
 	@GLIB_CFLAGS@ \
 	@DBUS_CFLAGS@
 
-bin_PROGRAMS = polkit-check-caller polkit-check-session
+bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-privilege-file-validate
 
 polkit_check_caller_SOURCES = polkit-check-caller.c
 polkit_check_caller_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
@@ -19,6 +19,10 @@ polkit_check_caller_LDADD = @GLIB_LIBS@ 
 polkit_check_session_SOURCES = polkit-check-session.c
 polkit_check_session_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
 
+polkit_privilege_file_validate_SOURCES = polkit-privilege-file-validate.c
+polkit_privilege_file_validate_LDADD = @GLIB_LIBS@ $(top_builddir)/libpolkit/libpolkit.la
+
+
 clean-local :
 	rm -f *~
 
diff --git a/tools/polkit-privilege-file-validate.c b/tools/polkit-privilege-file-validate.c
new file mode 100644
index 0000000..f4ea857
--- /dev/null
+++ b/tools/polkit-privilege-file-validate.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * polkit-privilege-file-validate.c : validate privilege file
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <libpolkit/libpolkit-privilege-file.h>
+
+static void
+usage (int argc, char *argv[])
+{
+	fprintf (stderr,
+                 "\n"
+                 "usage : polkit-privilege-file-validate --file <privilege-file>\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");
+}
+
+int
+main (int argc, char *argv[])
+{
+        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;
+        }
+
+        validated = TRUE;
+        libpolkit_privilege_file_unref (priv_file);
+
+out:
+        if (file != NULL)
+                g_free (file);
+
+        if (validated)
+                return 0;
+        else
+                return 1;
+}


More information about the hal-commit mailing list