PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Thu Sep 27 10:39:30 PDT 2007


 doc/TODO                    |    4 --
 polkit/polkit-config.c      |   32 +++++++++++++++++-----
 polkit/polkit-policy-file.c |   63 +++++++++++++++++++-------------------------
 3 files changed, 53 insertions(+), 46 deletions(-)

New commits:
diff-tree b420cc512b3277cac57c2c2231adf80cefd7e764 (from 4714fe721988d533a912ac62df5088f24f5bc699)
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Sep 27 13:36:11 2007 -0400

    don't fail on unknown XML tags, just skip them
    
    This change will futureproof libpolkit for extensions; e.g. if there's
    an OS upgrade where
    
     a) the PolicyKit package is upgraded to a version where support for a
        new tag <allow_foo> is added; and
    
     b) another package, using PolicyKit, is upgraded dropping a .policy
        file using the new <allow_foo> tag; then
    
    existing running processes using libpolkit will not fail. They will,
    however, not honor the new tags until the daemon process itself is
    restarted using e.g. condrestart.
    
    We also log to the system logger whenever we encouter unknown tags.

diff --git a/doc/TODO b/doc/TODO
index fd2df59..38698b0 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,8 +1,4 @@
 
- - Make both XML parsers cope with unknown elements; this is necessary
-   to keep old processes linking in libpolkit work when doing upgrade
-   of PolicyKit where e.g. .policy files with new elements are added.
-
  - Have someone review the external API
 
  - Verify the security model
diff --git a/polkit/polkit-config.c b/polkit/polkit-config.c
index 2a61e1b..ce404ba 100644
--- a/polkit/polkit-config.c
+++ b/polkit/polkit-config.c
@@ -37,6 +37,7 @@
 #include <errno.h>
 #include <sys/inotify.h>
 #include <regex.h>
+#include <syslog.h>
 
 #include <expat.h>
 
@@ -58,6 +59,7 @@
 
 enum {
         STATE_NONE,
+        STATE_UNKNOWN_TAG,
         STATE_IN_CONFIG,
         STATE_IN_MATCH,
         STATE_IN_RETURN,
@@ -87,6 +89,7 @@ typedef struct {
         XML_Parser parser;
         int state;
         PolKitConfig *pk_config;
+        const char *path;
 
         int state_stack[PARSER_MAX_DEPTH];
         ConfigNode *node_stack[PARSER_MAX_DEPTH];
@@ -95,6 +98,7 @@ typedef struct {
 } ParserData;
 
 enum {
+        NODE_TYPE_NOP,
         NODE_TYPE_TOP,
         NODE_TYPE_MATCH,
         NODE_TYPE_RETURN,
@@ -165,6 +169,9 @@ config_node_dump_real (ConfigNode *node,
         buf[n] = '\0';
         
         switch (node->node_type) {
+        case NODE_TYPE_NOP:
+                _pk_debug ("%sNOP", buf);
+                break;
         case NODE_TYPE_TOP:
                 _pk_debug ("%sTOP", buf);
                 break;
@@ -210,6 +217,8 @@ config_node_unref (ConfigNode *node)
         GSList *i;
 
         switch (node->node_type) {
+        case NODE_TYPE_NOP:
+                break;
         case NODE_TYPE_TOP:
                 break;
         case NODE_TYPE_MATCH:
@@ -245,7 +254,8 @@ _start (void *data, const char *el, cons
                 ;
 
         state = STATE_NONE;
-        node = NULL;
+        node = config_node_new ();
+        node->node_type = NODE_TYPE_NOP;
 
         switch (pd->state) {
         case STATE_NONE:
@@ -258,7 +268,6 @@ _start (void *data, const char *el, cons
                                 goto error;
                         }
 
-                        node = config_node_new ();
                         node->node_type = NODE_TYPE_TOP;
                         pd->pk_config->top_config_node = node;
                 }
@@ -267,7 +276,6 @@ _start (void *data, const char *el, cons
         case STATE_IN_MATCH:
                 if ((strcmp (el, "match") == 0) && (num_attr == 2)) {
 
-                        node = config_node_new ();
                         node->node_type = NODE_TYPE_MATCH;
                         if (strcmp (attr[0], "action") == 0) {
                                 node->data.node_match.match_type = MATCH_TYPE_ACTION;
@@ -292,7 +300,6 @@ _start (void *data, const char *el, cons
 
                 } else if ((strcmp (el, "return") == 0) && (num_attr == 2)) {
 
-                        node = config_node_new ();
                         node->node_type = NODE_TYPE_RETURN;
 
                         if (strcmp (attr[0], "result") == 0) {
@@ -313,7 +320,6 @@ _start (void *data, const char *el, cons
                                    node->data.node_return.result);
                 } else if ((strcmp (el, "define_admin_auth") == 0) && (num_attr == 2)) {
 
-                        node = config_node_new ();
                         node->node_type = NODE_TYPE_DEFINE_ADMIN_AUTH;
                         if (strcmp (attr[0], "user") == 0) {
                                 node->data.node_define_admin_auth.admin_type = POLKIT_CONFIG_ADMIN_AUTH_TYPE_USER;
@@ -337,8 +343,13 @@ _start (void *data, const char *el, cons
                 break;
         }
 
-        if (state == STATE_NONE || node == NULL)
-                goto error;
+        if (state == STATE_NONE || node == NULL) {
+                g_warning ("skipping unknown tag <%s> at line %d of %s", 
+                           el, (int) XML_GetCurrentLineNumber (pd->parser), pd->path);
+                syslog (LOG_ALERT, "libpolkit: skipping unknown tag <%s> at line %d of %s", 
+                        el, (int) XML_GetCurrentLineNumber (pd->parser), pd->path);
+                state = STATE_UNKNOWN_TAG;
+        }
 
         if (pd->stack_depth < 0 || pd->stack_depth >= PARSER_MAX_DEPTH) {
                 _pk_debug ("reached max depth?");
@@ -442,6 +453,7 @@ polkit_config_new (const char *path, Pol
         pd.pk_config = pk_config;
         pd.node_stack[0] = NULL;
         pd.stack_depth = 0;
+        pd.path = path;
 
         xml_res = XML_Parse (pd.parser, buf, buflen, 1);
 
@@ -588,6 +600,9 @@ config_node_test (ConfigNode *node, 
         result = POLKIT_RESULT_UNKNOWN;
 
         switch (node->node_type) {
+        case NODE_TYPE_NOP:
+                recurse = FALSE;
+                break;
         case NODE_TYPE_TOP:
                 recurse = TRUE;
                 break;
@@ -682,6 +697,9 @@ config_node_determine_admin_auth (Config
         result_set = FALSE;
 
         switch (node->node_type) {
+        case NODE_TYPE_NOP:
+                recurse = FALSE;
+                break;
         case NODE_TYPE_TOP:
                 recurse = TRUE;
                 break;
diff --git a/polkit/polkit-policy-file.c b/polkit/polkit-policy-file.c
index 5f7bcd1..73ca781 100644
--- a/polkit/polkit-policy-file.c
+++ b/polkit/polkit-policy-file.c
@@ -35,6 +35,7 @@
 #include <grp.h>
 #include <unistd.h>
 #include <errno.h>
+#include <syslog.h>
 
 #include <expat.h>
 
@@ -73,6 +74,7 @@ extern PolKitPolicyFileEntry *_polkit_po
 
 enum {
         STATE_NONE,
+        STATE_UNKNOWN_TAG,
         STATE_IN_POLICY_CONFIG,
         STATE_IN_ACTION,
         STATE_IN_ACTION_DESCRIPTION,
@@ -84,9 +86,15 @@ enum {
         STATE_IN_ANNOTATE
 };
 
+#define PARSER_MAX_DEPTH 32
+
 typedef struct {
         XML_Parser parser;
         int state;
+        int state_stack[PARSER_MAX_DEPTH];
+        int stack_depth;
+
+        const char *path;
 
         char *action_id;
 
@@ -223,11 +231,17 @@ _start (void *data, const char *el, cons
                 break;
         }
 
-        if (state == STATE_NONE)
-                goto error;
+        if (state == STATE_NONE) {
+                g_warning ("skipping unknown tag <%s> at line %d of %s", 
+                           el, (int) XML_GetCurrentLineNumber (pd->parser), pd->path);
+                syslog (LOG_ALERT, "libpolkit: skipping unknown tag <%s> at line %d of %s", 
+                        el, (int) XML_GetCurrentLineNumber (pd->parser), pd->path);
+                state = STATE_UNKNOWN_TAG;
+        }
 
         pd->state = state;
-
+        pd->state_stack[pd->stack_depth] = pd->state;
+        pd->stack_depth++;
         return;
 error:
         XML_StopParser (pd->parser, FALSE);
@@ -349,20 +363,12 @@ out:
 static void
 _end (void *data, const char *el)
 {
-        int state;
         ParserData *pd = data;
 
-        state = STATE_NONE;
-
         g_free (pd->elem_lang);
         pd->elem_lang = NULL;
 
         switch (pd->state) {
-        case STATE_NONE:
-                break;
-        case STATE_IN_POLICY_CONFIG:
-                state = STATE_NONE;
-                break;
         case STATE_IN_ACTION:
         {
                 const char *policy_description;
@@ -394,36 +400,21 @@ _end (void *data, const char *el)
                                                                     policy_message);
 
                 pd->pf->entries = g_slist_prepend (pd->pf->entries, pfe);
-
-                state = STATE_IN_POLICY_CONFIG;
                 break;
         }
-        case STATE_IN_ACTION_DESCRIPTION:
-                state = STATE_IN_ACTION;
-                break;
-        case STATE_IN_ACTION_MESSAGE:
-                state = STATE_IN_ACTION;
-                break;
-        case STATE_IN_DEFAULTS:
-                state = STATE_IN_ACTION;
-                break;
-        case STATE_IN_DEFAULTS_ALLOW_ANY:
-                state = STATE_IN_DEFAULTS;
-                break;
-        case STATE_IN_DEFAULTS_ALLOW_INACTIVE:
-                state = STATE_IN_DEFAULTS;
-                break;
-        case STATE_IN_DEFAULTS_ALLOW_ACTIVE:
-                state = STATE_IN_DEFAULTS;
-                break;
-        case STATE_IN_ANNOTATE:
-                state = STATE_IN_ACTION;
-                break;
         default:
                 break;
         }
 
-        pd->state = state;
+        --pd->stack_depth;
+        if (pd->stack_depth < 0 || pd->stack_depth >= PARSER_MAX_DEPTH) {
+                _pk_debug ("reached max depth?");
+                goto error;
+        }
+        if (pd->stack_depth > 0)
+                pd->state = pd->state_stack[pd->stack_depth - 1];
+        else
+                pd->state = STATE_NONE;
 
         return;
 error:
@@ -474,7 +465,9 @@ polkit_policy_file_new (const char *path
         /* clear parser data */
         memset (&pd, 0, sizeof (ParserData));
 
+        pd.path = path;
         pd.parser = XML_ParserCreate (NULL);
+        pd.stack_depth = 0;
         if (pd.parser == NULL) {
                 polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY,
                                         "Cannot load PolicyKit policy file at '%s': %s",


More information about the hal-commit mailing list