X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=plugins%2Fsession_policy_local.c;h=32b9c697975a33d2d2e03b19d4ea92a97c11b27d;hb=7fbf7773fa5b52f15c9dbbddd10f55b57ce91f2d;hp=d9f9aefc2ce8e1bc1c5fe3f69bf80b6a116b9999;hpb=9c5cb53a5d85f9416bbbe4ebdc350474f61274b7;p=platform%2Fupstream%2Fconnman.git diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c old mode 100644 new mode 100755 index d9f9aef..32b9c69 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2012 BMW Car IT GbmH. All rights reserved. + * Copyright (C) 2012-2014 BMW Car IT GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -42,6 +42,8 @@ #include #include +#include "src/shared/util.h" + #define POLICYDIR STORAGEDIR "/session_policy_local" #define MODE (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | \ @@ -64,7 +66,7 @@ static GHashTable *gid_hash; /* (gid, policy_group) */ struct policy_file { /* * A valid file is a keyfile with one ore more groups. All - * groups are keept in this list. + * groups are kept in this list. */ GSList *groups; }; @@ -88,6 +90,7 @@ struct policy_group { /* A struct policy_config object is created and owned by a session. */ struct policy_config { char *selinux; + char *selinux_context; char *uid; GSList *gids; @@ -131,7 +134,7 @@ static char *parse_selinux_type(const char *context) /* * SELinux combines Role-Based Access Control (RBAC), Type - * Enforcment (TE) and optionally Multi-Level Security (MLS). + * Enforcement (TE) and optionally Multi-Level Security (MLS). * * When SELinux is enabled all processes and files are labeled * with a contex that contains information such as user, role @@ -142,7 +145,7 @@ static char *parse_selinux_type(const char *context) * * For identifyng application we (ab)using the type * information. In the above example the haifux_exec_t type - * will be transfered to haifux_t as defined in the domain + * will be transferred to haifux_t as defined in the domain * transition and thus we are able to identify the application * as haifux_t. */ @@ -167,29 +170,42 @@ static void finish_create(struct policy_config *policy, connman_session_config_func_t cb, void *user_data) { - struct policy_group *group; + struct policy_group *group = NULL; GSList *list; - group = g_hash_table_lookup(selinux_hash, policy->selinux); - if (group != NULL) { + if (policy->selinux) + group = g_hash_table_lookup(selinux_hash, policy->selinux); + + if (group) { set_policy(policy, group); + + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_LSM; + policy->config->id = g_strdup(policy->selinux_context); goto done; } - group = g_hash_table_lookup(uid_hash, policy->uid); - if (group != NULL) { + if (policy->uid) + group = g_hash_table_lookup(uid_hash, policy->uid); + + if (group) { set_policy(policy, group); + + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_UID; + policy->config->id = g_strdup(policy->uid); goto done; } - for (list = policy->gids; list != NULL; list = list->next) { + for (list = policy->gids; list; list = list->next) { char *gid = list->data; group = g_hash_table_lookup(gid_hash, gid); - if (group == NULL) + if (!group) continue; set_policy(policy, group); + + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_GID; + policy->config->id = g_strdup(gid); break; } done: @@ -217,15 +233,22 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, DBG("session %p", policy->session); + if (err == -EIO) { + /* No SELinux support, drop back to UID/GID only mode */ + finish_create(policy, cb, cbd->user_data); + goto done; + } + if (err < 0) { - failed_create(policy, cb, user_data, err); + failed_create(policy, cb, cbd->user_data, err); goto done; } DBG("SELinux context %s", context); - ident = parse_selinux_type((const char*)context); - if (ident != NULL) + policy->selinux_context = g_strdup((const char *)context); + ident = parse_selinux_type(policy->selinux_context); + if (ident) policy->selinux = g_strdup(ident); finish_create(policy, cb, cbd->user_data); @@ -248,13 +271,11 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err) DBG("session %p uid %d", policy->session, uid); - if (err < 0) { - cleanup_config(policy); + if (err < 0) goto err; - } pwd = getpwuid((uid_t)uid); - if (pwd == NULL) { + if (!pwd) { if (errno != 0) err = -errno; else @@ -267,7 +288,7 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err) nrgroups = 0; getgrouplist(pwd->pw_name, pwd->pw_gid, NULL, &nrgroups); groups = g_try_new0(gid_t, nrgroups); - if (groups == NULL) { + if (!groups) { err = -ENOMEM; goto err; } @@ -278,7 +299,7 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err) for (i = 0; i < nrgroups; i++) { grp = getgrgid(groups[i]); - if (grp == NULL) { + if (!grp) { if (errno != 0) err = -errno; else @@ -310,7 +331,7 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err) return; err: - failed_create(NULL, cb, user_data, err); + failed_create(policy, cb, cbd->user_data, err); g_free(cbd); g_free(groups); } @@ -353,7 +374,7 @@ static void policy_local_destroy(struct connman_session *session) DBG("session %p", session); policy = g_hash_table_lookup(session_hash, session); - if (policy == NULL) + if (!policy) return; g_hash_table_remove(session_hash, session); @@ -373,7 +394,7 @@ static int load_keyfile(const char *pathname, GKeyFile **keyfile) *keyfile = g_key_file_new(); - if (g_key_file_load_from_file(*keyfile, pathname, 0, &error) == FALSE) + if (!g_key_file_load_from_file(*keyfile, pathname, 0, &error)) goto err; return 0; @@ -410,7 +431,7 @@ static int load_policy(GKeyFile *keyfile, const char *groupname, group->uid = g_key_file_get_string(keyfile, groupname, "uid", NULL); - if (group->selinux == NULL && group->gid == NULL && group->uid == NULL) + if (!group->selinux && !group->gid && !group->uid) return -EINVAL; config->priority = g_key_file_get_boolean(keyfile, groupname, @@ -418,14 +439,14 @@ static int load_policy(GKeyFile *keyfile, const char *groupname, str = g_key_file_get_string(keyfile, groupname, "RoamingPolicy", NULL); - if (str != NULL) { + if (str) { config->roaming_policy = connman_session_parse_roaming_policy(str); g_free(str); } str = g_key_file_get_string(keyfile, groupname, "ConnectionType", NULL); - if (str != NULL) { + if (str) { config->type = connman_session_parse_connection_type(str); g_free(str); } @@ -435,10 +456,12 @@ static int load_policy(GKeyFile *keyfile, const char *groupname, str = g_key_file_get_string(keyfile, groupname, "AllowedBearers", NULL); - if (str != NULL) { + if (str) { + g_slist_free(config->allowed_bearers); + config->allowed_bearers = NULL; tokens = g_strsplit(str, " ", 0); - for (i = 0; tokens[i] != NULL; i++) { + for (i = 0; tokens[i]; i++) { err = connman_session_parse_bearers(tokens[i], &config->allowed_bearers); if (err < 0) @@ -459,7 +482,7 @@ static void update_session(struct policy_config *policy) { DBG("policy %p session %p", policy, policy->session); - if (policy->session == NULL) + if (!policy->session) return; if (connman_session_config_update(policy->session) < 0) @@ -481,12 +504,14 @@ static void cleanup_config(gpointer user_data) DBG("policy %p group %p", policy, policy->group); - if (policy->group != NULL) + if (policy->group) policy->group->sessions = g_slist_remove(policy->group->sessions, policy); g_slist_free(policy->config->allowed_bearers); + g_free(policy->config->id); g_free(policy->config); + g_free(policy->selinux_context); g_free(policy->selinux); g_free(policy->uid); g_slist_free_full(policy->gids, g_free); @@ -502,12 +527,13 @@ static void cleanup_group(gpointer user_data) g_slist_free_full(group->sessions, set_default_config); g_slist_free(group->config->allowed_bearers); + g_free(group->config->id); g_free(group->config); - if (group->selinux != NULL) + if (group->selinux) g_hash_table_remove(selinux_hash, group->selinux); - if (group->uid != NULL) + if (group->uid) g_hash_table_remove(uid_hash, group->uid); - if (group->gid != NULL) + if (group->gid) g_hash_table_remove(gid_hash, group->gid); g_free(group->selinux); g_free(group->uid); @@ -530,18 +556,48 @@ static void recheck_sessions(void) GHashTableIter iter; gpointer value, key; struct policy_group *group = NULL; + GSList *list; g_hash_table_iter_init(&iter, session_hash); - while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + while (g_hash_table_iter_next(&iter, &key, &value)) { struct policy_config *policy = value; - if (policy->group != NULL) + if (policy->group) continue; - group = g_hash_table_lookup(selinux_hash, policy->selinux); - if (group != NULL) { + if (policy->selinux) + group = g_hash_table_lookup(selinux_hash, + policy->selinux); + if (group) { + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_LSM; + g_free(policy->config->id); + policy->config->id = g_strdup(policy->selinux_context); + update_session(policy); + continue; + } + + group = g_hash_table_lookup(uid_hash, policy->uid); + if (group) { set_policy(policy, group); + + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_UID; + g_free(policy->config->id); + policy->config->id = g_strdup(policy->uid); update_session(policy); + continue; + } + + for (list = policy->gids; list; list = list->next) { + char *gid = list->data; + group = g_hash_table_lookup(gid_hash, gid); + if (group) { + set_policy(policy, group); + + policy->config->id_type = CONNMAN_SESSION_ID_TYPE_GID; + g_free(policy->config->id); + policy->config->id = g_strdup(gid); + update_session(policy); + } } } } @@ -565,9 +621,9 @@ static int load_file(const char *filename, struct policy_file *file) groupnames = g_key_file_get_groups(keyfile, NULL); - for (i = 0; groupnames[i] != NULL; i++) { + for (i = 0; groupnames[i]; i++) { group = g_new0(struct policy_group, 1); - group->config = g_new0(struct connman_session_config, 1); + group->config = connman_session_create_default_config(); err = load_policy(keyfile, groupnames[i], group); if (err < 0) { @@ -575,13 +631,13 @@ static int load_file(const char *filename, struct policy_file *file) g_free(group); break; } - if (group->selinux != NULL) + if (group->selinux) g_hash_table_replace(selinux_hash, group->selinux, group); - if (group->uid != NULL) + if (group->uid) g_hash_table_replace(uid_hash, group->uid, group); - if (group->gid != NULL) + if (group->gid) g_hash_table_replace(gid_hash, group->gid, group); file->groups = g_slist_prepend(file->groups, group); @@ -597,18 +653,18 @@ static int load_file(const char *filename, struct policy_file *file) return err; } -static connman_bool_t is_filename_valid(const char *filename) +static bool is_filename_valid(const char *filename) { - if (filename == NULL) - return FALSE; + if (!filename) + return false; if (filename[0] == '.') - return FALSE; + return false; return g_str_has_suffix(filename, ".policy"); } -static int read_policies() +static int read_policies(void) { GDir *dir; const gchar *filename; @@ -617,11 +673,11 @@ static int read_policies() DBG(""); dir = g_dir_open(POLICYDIR, 0, NULL); - if (dir == NULL) + if (!dir) return -EINVAL; - while ((filename = g_dir_read_name(dir)) != NULL) { - if (is_filename_valid(filename) == FALSE) + while ((filename = g_dir_read_name(dir))) { + if (!is_filename_valid(filename)) continue; file = g_new0(struct policy_file, 1); @@ -649,7 +705,7 @@ static void notify_handler(struct inotify_event *event, if (event->mask & IN_CREATE) return; - if (is_filename_valid(filename) == FALSE) + if (!is_filename_valid(filename)) return; /* @@ -683,7 +739,7 @@ static int session_policy_local_init(void) DBG(""); /* If the dir doesn't exist, create it */ - if (g_file_test(POLICYDIR, G_FILE_TEST_IS_DIR) == FALSE) { + if (!g_file_test(POLICYDIR, G_FILE_TEST_IS_DIR)) { if (mkdir(POLICYDIR, MODE) < 0) { if (errno != EEXIST) return -errno; @@ -691,7 +747,7 @@ static int session_policy_local_init(void) } connection = connman_dbus_get_connection(); - if (connection == NULL) + if (!connection) return -EIO; file_hash = g_hash_table_new_full(g_str_hash, g_str_equal, @@ -722,19 +778,19 @@ err_notify: connman_inotify_unregister(POLICYDIR, notify_handler); err: - if (file_hash != NULL) + if (file_hash) g_hash_table_destroy(file_hash); - if (session_hash != NULL) + if (session_hash) g_hash_table_destroy(session_hash); - if (selinux_hash != NULL) + if (selinux_hash) g_hash_table_destroy(selinux_hash); - if (uid_hash != NULL) + if (uid_hash) g_hash_table_destroy(uid_hash); - if (gid_hash != NULL) + if (gid_hash) g_hash_table_destroy(gid_hash); connman_session_policy_unregister(&session_policy_local);