Re: [PATCH v3 07/12] session_policy_local: Rework policy file handling

2013-05-15 Thread Patrik Flykt

Hi,

On Tue, 2013-05-07 at 10:27 +0200, Daniel Wagner wrote:
 From: Daniel Wagner daniel.wag...@bmw-carit.de
 
 The old assumption was that a config file is associtated
 with one session only. With introducing UID/GID support a policy
 might be used for several sessions. Furthermore, it was assumed
 that the file name is the key/ident to identify a session and
 a file containts exactly one policy.
 
 Here are the new rules for writing a policy file.
 
 - A valid file name contains letters or numbers and must have a '.policy'
   suffix.
 - The file name has not semantical meaning
 - A policy file may contain contain more than 1 policy
 - Each policy entry starts with 'policy_'
 - Each policy entry shall have one and exactly one valid key (e.g. selinux)
 
 And now some comments on the implementation. We have two main hash
 tables, file_hash and session_hash which own 'the file' respectively
 the session config. Additionally we have a hash table which connects a
 policy with a session (selinux_hash).
 ---
  plugins/session_policy_local.c | 402 
 ++---
  1 file changed, 258 insertions(+), 144 deletions(-)
 
 diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c
 index 6cd876c..f0e4ff4 100644
 --- a/plugins/session_policy_local.c
 +++ b/plugins/session_policy_local.c
 @@ -46,33 +46,78 @@
  
  static DBusConnection *connection;
  
 -static GHashTable *policy_hash;
 -static GHashTable *session_hash;
 +static GHashTable *file_hash;/* (filename, policy_file) */
 +static GHashTable *session_hash; /* (connman_session, policy_config) */
 +
 +/* Global lookup table for mapping sessions to policies */
 +static GHashTable *selinux_hash; /* (lsm context, policy_group) */
  
  struct create_data {
   struct connman_session *session;
  };
  
 -struct policy_data {
 - int refcount;
 - char *ident;
 +/*
 + * A instance of struct policy_file is created per file in
 + * POLICYDIR.
 + */
 +struct policy_file {
 + /*
 +  * A valid file is a keyfile with one ore more groups. All
 +  * groups are keept in this list.
 +  */
 + GSList *groups;
 +};
  
 - struct connman_session *session;
 +struct policy_group {
 + char *selinux;
 +
 + /*
 +  * Each policy_group owns a config and is not shared with
 +  * sessions. Instead each session copies the valued from this
 +  * object.
 +  */
   struct connman_session_config *config;
 +
 + /* All 'users' of this policy. */
 + GSList *sessions;
 +};
 +
 +/* A struct policy_config object is created and owned by a session. */
 +struct policy_config {
 + char *selinux;
 +
 + /* The policy config owned by the session */
 + struct connman_session_config *config;
 +
 + /* To which policy belongs this policy_config */
 + struct connman_session *session;
 + /*
 +  * Points to the policy_group when a config has been applied
 +  * from a file.
 +  */
 + struct policy_group *group;
  };
  
 -static void cleanup_policy(gpointer user_data)
 +static void copy_session_config(struct connman_session_config *dst,
 + struct connman_session_config *src)
  {
 - struct policy_data *policy = user_data;
 + g_slist_free(dst-allowed_bearers);
 + dst-allowed_bearers = g_slist_copy(src-allowed_bearers);
 + dst-ecall = src-ecall;
 + dst-type = src-type;
 + dst-roaming_policy = src-roaming_policy;
 + dst-priority = src-priority;
 +}
  
 - DBG(policy %p, policy);
 +static void set_policy(struct policy_config *policy,
 + struct policy_group *group)
 +{
 + DBG(policy %p group %p, policy, group);
  
 - if (policy-config != NULL)
 - g_slist_free(policy-config-allowed_bearers);
 + group-sessions = g_slist_prepend(group-sessions, policy);
 + policy-group = group;
  
 - g_free(policy-ident);
 - g_free(policy-config);
 - g_free(policy);
 + copy_session_config(policy-config, group-config);
  }
  
  static char *parse_selinux_type(const char *context)
 @@ -111,51 +156,27 @@ static char *parse_selinux_type(const char *context)
   return ident;
  }
  
 -static struct policy_data *create_policy(const char *ident)
 +static struct policy_config *create_policy(void)
  {
 - struct policy_data *policy;
 + struct policy_config *policy;
  
 - DBG(ident %s, ident);
 -
 - policy = g_new0(struct policy_data, 1);
 - policy-refcount = 1;
 + policy = g_new0(struct policy_config, 1);
  
   DBG(policy %p, policy);
  
   policy-config = connman_session_create_default_config();
 - policy-ident = g_strdup(ident);
 -
 - g_hash_table_replace(policy_hash, policy-ident, policy);
  
   return policy;
  }
  
 -static struct policy_data *policy_ref(struct policy_data *policy)
 -{
 - DBG(%p %s ref %d, policy, policy-ident, policy-refcount + 1);
 -
 - __sync_fetch_and_add(policy-refcount, 1);
 -
 - return 

Re: [PATCH v3 07/12] session_policy_local: Rework policy file handling

2013-05-15 Thread Daniel Wagner

Hi Patrik,

On 05/15/2013 04:57 PM, Patrik Flykt wrote:

+static void recheck_sessions(void)
+{
+   GHashTableIter iter;
+   gpointer value, key;
+   struct policy_group *group = NULL;
+
+   g_hash_table_iter_init(iter, session_hash);
+   while (g_hash_table_iter_next(iter, key, value) == TRUE) {
+   struct policy_config *policy = value;
+
+   if (policy-group != NULL)
+   continue;
+
+   group = g_hash_table_lookup(selinux_hash, policy-selinux);
+   if (group != NULL)
+   set_policy(policy, group);
+
+   update_session(policy);


If group == NULL after the hash table lookup, do we need to
update_session(policy) even though nothing has changed or is it an
error?


Good catch. recheck_session() tries to find a configuration for a 
session which has no configuration attached yet. Therefore, if no 
configuration is found, nothing has to be done.


cheers,
daniel
___
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman


[PATCH v3 07/12] session_policy_local: Rework policy file handling

2013-05-07 Thread Daniel Wagner
From: Daniel Wagner daniel.wag...@bmw-carit.de

The old assumption was that a config file is associtated
with one session only. With introducing UID/GID support a policy
might be used for several sessions. Furthermore, it was assumed
that the file name is the key/ident to identify a session and
a file containts exactly one policy.

Here are the new rules for writing a policy file.

- A valid file name contains letters or numbers and must have a '.policy'
  suffix.
- The file name has not semantical meaning
- A policy file may contain contain more than 1 policy
- Each policy entry starts with 'policy_'
- Each policy entry shall have one and exactly one valid key (e.g. selinux)

And now some comments on the implementation. We have two main hash
tables, file_hash and session_hash which own 'the file' respectively
the session config. Additionally we have a hash table which connects a
policy with a session (selinux_hash).
---
 plugins/session_policy_local.c | 402 ++---
 1 file changed, 258 insertions(+), 144 deletions(-)

diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c
index 6cd876c..f0e4ff4 100644
--- a/plugins/session_policy_local.c
+++ b/plugins/session_policy_local.c
@@ -46,33 +46,78 @@
 
 static DBusConnection *connection;
 
-static GHashTable *policy_hash;
-static GHashTable *session_hash;
+static GHashTable *file_hash;/* (filename, policy_file) */
+static GHashTable *session_hash; /* (connman_session, policy_config) */
+
+/* Global lookup table for mapping sessions to policies */
+static GHashTable *selinux_hash; /* (lsm context, policy_group) */
 
 struct create_data {
struct connman_session *session;
 };
 
-struct policy_data {
-   int refcount;
-   char *ident;
+/*
+ * A instance of struct policy_file is created per file in
+ * POLICYDIR.
+ */
+struct policy_file {
+   /*
+* A valid file is a keyfile with one ore more groups. All
+* groups are keept in this list.
+*/
+   GSList *groups;
+};
 
-   struct connman_session *session;
+struct policy_group {
+   char *selinux;
+
+   /*
+* Each policy_group owns a config and is not shared with
+* sessions. Instead each session copies the valued from this
+* object.
+*/
struct connman_session_config *config;
+
+   /* All 'users' of this policy. */
+   GSList *sessions;
+};
+
+/* A struct policy_config object is created and owned by a session. */
+struct policy_config {
+   char *selinux;
+
+   /* The policy config owned by the session */
+   struct connman_session_config *config;
+
+   /* To which policy belongs this policy_config */
+   struct connman_session *session;
+   /*
+* Points to the policy_group when a config has been applied
+* from a file.
+*/
+   struct policy_group *group;
 };
 
-static void cleanup_policy(gpointer user_data)
+static void copy_session_config(struct connman_session_config *dst,
+   struct connman_session_config *src)
 {
-   struct policy_data *policy = user_data;
+   g_slist_free(dst-allowed_bearers);
+   dst-allowed_bearers = g_slist_copy(src-allowed_bearers);
+   dst-ecall = src-ecall;
+   dst-type = src-type;
+   dst-roaming_policy = src-roaming_policy;
+   dst-priority = src-priority;
+}
 
-   DBG(policy %p, policy);
+static void set_policy(struct policy_config *policy,
+   struct policy_group *group)
+{
+   DBG(policy %p group %p, policy, group);
 
-   if (policy-config != NULL)
-   g_slist_free(policy-config-allowed_bearers);
+   group-sessions = g_slist_prepend(group-sessions, policy);
+   policy-group = group;
 
-   g_free(policy-ident);
-   g_free(policy-config);
-   g_free(policy);
+   copy_session_config(policy-config, group-config);
 }
 
 static char *parse_selinux_type(const char *context)
@@ -111,51 +156,27 @@ static char *parse_selinux_type(const char *context)
return ident;
 }
 
-static struct policy_data *create_policy(const char *ident)
+static struct policy_config *create_policy(void)
 {
-   struct policy_data *policy;
+   struct policy_config *policy;
 
-   DBG(ident %s, ident);
-
-   policy = g_new0(struct policy_data, 1);
-   policy-refcount = 1;
+   policy = g_new0(struct policy_config, 1);
 
DBG(policy %p, policy);
 
policy-config = connman_session_create_default_config();
-   policy-ident = g_strdup(ident);
-
-   g_hash_table_replace(policy_hash, policy-ident, policy);
 
return policy;
 }
 
-static struct policy_data *policy_ref(struct policy_data *policy)
-{
-   DBG(%p %s ref %d, policy, policy-ident, policy-refcount + 1);
-
-   __sync_fetch_and_add(policy-refcount, 1);
-
-   return policy;
-}
-
-static void policy_unref(struct policy_data *policy)
-{
-   DBG( %p %s ref %d, policy,