From: Daniel Wagner <daniel.wag...@bmw-carit.de> When the session core ask to create a configuration, then we first ask the D-Bus server which UID the session belongs to. If possible we also ask for the SELinux context. Then we try to figure out which file containts the configuration for UID/SElinux identification.
The SELinux identification has higher priority than UID. It is possible to run a mixed configuration but not really recommended. There might be dragons. --- plugins/session_policy_local.c | 93 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 8 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index c28b856..aeb4bbf 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -27,6 +27,8 @@ #include <string.h> #include <sys/inotify.h> #include <sys/stat.h> +#include <sys/types.h> +#include <pwd.h> #include <glib.h> @@ -52,12 +54,18 @@ static GSList *policy_list; struct create_data { struct connman_session *session; + char *user; + uid_t uid; + gid_t gid; }; struct policy_data { int refcount; char *filename; char *lsm_ctx; /* The Linux Security Module Context */ + char *user; + uid_t uid; + gid_t gid; struct connman_session *session; struct connman_session_config *config; @@ -72,6 +80,7 @@ static void free_policy(gpointer user_data) g_free(policy->filename); g_free(policy->lsm_ctx); + g_free(policy->user); g_free(policy->config); g_free(policy); } @@ -152,7 +161,8 @@ static struct policy_data *find_policy_by_file(const char *filename) for (list = policy_list; list != NULL; list = list->next) { policy = list->data; - if (g_strcmp0(policy->lsm_ctx, filename) != 0) + if (g_strcmp0(policy->lsm_ctx, filename) != 0 && + g_strcmp0(policy->user, filename) != 0) continue; return policy; @@ -161,7 +171,8 @@ static struct policy_data *find_policy_by_file(const char *filename) return NULL; } -static struct policy_data *find_policy_by_session(const char *lsm_ctx) +static struct policy_data *find_policy_by_session(const char *lsm_ctx, + const char *user) { GSList *list; struct policy_data *policy; @@ -169,7 +180,8 @@ static struct policy_data *find_policy_by_session(const char *lsm_ctx) for (list = policy_list; list != NULL; list = list->next) { policy = list->data; - if (g_strcmp0(policy->filename, lsm_ctx) != 0) + if (g_strcmp0(policy->filename, lsm_ctx) != 0 && + g_strcmp0(policy->filename, user) != 0) continue; return policy; @@ -203,13 +215,16 @@ static void selinux_context_reply(int error, goto done; } - policy = find_policy_by_session(ident); + policy = find_policy_by_session(ident, data->user); if (policy == NULL) policy = create_policy(); else policy_ref(policy); policy->lsm_ctx = g_strdup(ident); + policy->user = data->user; + policy->uid = data->uid; + policy->gid = data->gid; policy->session = data->session; g_hash_table_replace(session_hash, data->session, policy); @@ -224,6 +239,69 @@ done: g_free(ctx); } +static void get_uid_reply(int error, unsigned int uid, void *user_data) +{ + struct cb_data *cbd = user_data; + connman_session_config_cb_t cb = cbd->cb; + struct create_data *data = cbd->data; + struct policy_data *policy; + const char *owner; + struct passwd *pwd; + struct connman_session_config *config = NULL; + + DBG("session %p uid %d", data->session, uid); + + if (error < 0) + goto done; + + errno = 0; + pwd = getpwuid((uid_t)uid); + if (pwd == NULL) { + if (errno != 0) + error = -errno; + else + error = -EINVAL; + goto done; + } + + data->user = g_strdup(pwd->pw_name); + data->uid = pwd->pw_uid; + data->gid = pwd->pw_gid; + + owner = connman_session_get_owner(data->session); + + error = connman_dbus_get_selinux_context(connection, owner, + selinux_context_reply, cbd); + if (error == 0) { + /* + * We are able to ask for a SELinux context. Let's defer the + * creation of the session config until we get the answer + * from D-Bus. + */ + return; + } + + policy = find_policy_by_session(NULL, data->user); + if (policy == NULL) + policy = create_policy(); + else + policy_ref(policy); + + policy->user = data->user; + policy->uid = data->uid; + policy->gid = data->gid; + policy->session = data->session; + + g_hash_table_replace(session_hash, data->session, policy); + + config = policy->config; +done: + (*cb)(error, data->session, config, cbd->user_data); + + g_free(data); + g_free(cbd); +} + static int policy_local_create(struct connman_session *session, connman_session_config_cb_t cb, void *user_data) @@ -242,11 +320,10 @@ static int policy_local_create(struct connman_session *session, owner = connman_session_get_owner(session); - err = connman_dbus_get_selinux_context(connection, owner, - selinux_context_reply, - cbd); + err = connman_dbus_get_connection_unix_user(connection, owner, + get_uid_reply, cbd); if (err < 0) { - connman_error("Could not get SELinux context"); + connman_error("Could not get UID"); g_free(data); g_free(cbd); return err; -- 1.8.1.3.566.gaa39828 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman