Re: [PATCH v3 07/12] session_policy_local: Rework policy file handling
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
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
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,