libsemanage: patch for MCS/MLS in user files
The attached patch makes the /etc/selinux/default/contexts/files/file_contexts.homedirs generation process include the MCS/MLS level. This means that if you have a user with a MCS/MLS level that isn't SystemLow then their home directory will be labeled such that they can have read/write access to it by default. Unless anyone has any better ideas for how to solve this problem I will upload this to Debian shortly. What do the MLS users do in this situation? Just relabel home directories manually? Finally it seems that when you run "semanage user -m" the file_contexts.homedirs doesn't get updated, it's only when you run "semanage login -m" that it takes affect. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Russell Coker <russell@coker.com.au> Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
34d9c258da
commit
d784fd71b5
1 changed files with 38 additions and 10 deletions
|
@ -76,9 +76,11 @@
|
||||||
#define TEMPLATE_USER "USER"
|
#define TEMPLATE_USER "USER"
|
||||||
#define TEMPLATE_ROLE "ROLE"
|
#define TEMPLATE_ROLE "ROLE"
|
||||||
#define TEMPLATE_SEUSER "system_u"
|
#define TEMPLATE_SEUSER "system_u"
|
||||||
|
#define TEMPLATE_LEVEL "s0"
|
||||||
|
|
||||||
#define FALLBACK_USER "user_u"
|
#define FALLBACK_USER "user_u"
|
||||||
#define FALLBACK_USER_PREFIX "user"
|
#define FALLBACK_USER_PREFIX "user"
|
||||||
|
#define FALLBACK_USER_LEVEL "s0"
|
||||||
#define DEFAULT_LOGIN "__default__"
|
#define DEFAULT_LOGIN "__default__"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -87,6 +89,7 @@ typedef struct {
|
||||||
const char *homedir_template_path;
|
const char *homedir_template_path;
|
||||||
char *fallback_user;
|
char *fallback_user;
|
||||||
char *fallback_user_prefix;
|
char *fallback_user_prefix;
|
||||||
|
char *fallback_user_level;
|
||||||
semanage_handle_t *h_semanage;
|
semanage_handle_t *h_semanage;
|
||||||
sepol_policydb_t *policydb;
|
sepol_policydb_t *policydb;
|
||||||
} genhomedircon_settings_t;
|
} genhomedircon_settings_t;
|
||||||
|
@ -96,6 +99,7 @@ typedef struct user_entry {
|
||||||
char *sename;
|
char *sename;
|
||||||
char *prefix;
|
char *prefix;
|
||||||
char *home;
|
char *home;
|
||||||
|
char *level;
|
||||||
struct user_entry *next;
|
struct user_entry *next;
|
||||||
} genhomedircon_user_entry_t;
|
} genhomedircon_user_entry_t;
|
||||||
|
|
||||||
|
@ -487,12 +491,13 @@ static int check_line(genhomedircon_settings_t * s, Ustr *line)
|
||||||
static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out,
|
static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out,
|
||||||
semanage_list_t * tpl, const char *user,
|
semanage_list_t * tpl, const char *user,
|
||||||
const char *seuser, const char *home,
|
const char *seuser, const char *home,
|
||||||
const char *role_prefix)
|
const char *role_prefix, const char *level)
|
||||||
{
|
{
|
||||||
replacement_pair_t repl[] = {
|
replacement_pair_t repl[] = {
|
||||||
{.search_for = TEMPLATE_SEUSER,.replace_with = seuser},
|
{.search_for = TEMPLATE_SEUSER,.replace_with = seuser},
|
||||||
{.search_for = TEMPLATE_HOME_DIR,.replace_with = home},
|
{.search_for = TEMPLATE_HOME_DIR,.replace_with = home},
|
||||||
{.search_for = TEMPLATE_ROLE,.replace_with = role_prefix},
|
{.search_for = TEMPLATE_ROLE,.replace_with = role_prefix},
|
||||||
|
{.search_for = TEMPLATE_LEVEL,.replace_with = level},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
Ustr *line = USTR_NULL;
|
Ustr *line = USTR_NULL;
|
||||||
|
@ -584,13 +589,15 @@ static int name_user_cmp(char *key, semanage_user_t ** val)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
|
static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
|
||||||
const char *sen, const char *pre, const char *h)
|
const char *sen, const char *pre, const char *h,
|
||||||
|
const char *l)
|
||||||
{
|
{
|
||||||
genhomedircon_user_entry_t *temp = NULL;
|
genhomedircon_user_entry_t *temp = NULL;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *sename = NULL;
|
char *sename = NULL;
|
||||||
char *prefix = NULL;
|
char *prefix = NULL;
|
||||||
char *home = NULL;
|
char *home = NULL;
|
||||||
|
char *level = NULL;
|
||||||
|
|
||||||
temp = malloc(sizeof(genhomedircon_user_entry_t));
|
temp = malloc(sizeof(genhomedircon_user_entry_t));
|
||||||
if (!temp)
|
if (!temp)
|
||||||
|
@ -607,11 +614,15 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
|
||||||
home = strdup(h);
|
home = strdup(h);
|
||||||
if (!home)
|
if (!home)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
level = strdup(l);
|
||||||
|
if (!level)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
temp->name = name;
|
temp->name = name;
|
||||||
temp->sename = sename;
|
temp->sename = sename;
|
||||||
temp->prefix = prefix;
|
temp->prefix = prefix;
|
||||||
temp->home = home;
|
temp->home = home;
|
||||||
|
temp->level = level;
|
||||||
temp->next = (*list);
|
temp->next = (*list);
|
||||||
(*list) = temp;
|
(*list) = temp;
|
||||||
|
|
||||||
|
@ -622,6 +633,7 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
|
||||||
free(sename);
|
free(sename);
|
||||||
free(prefix);
|
free(prefix);
|
||||||
free(home);
|
free(home);
|
||||||
|
free(level);
|
||||||
free(temp);
|
free(temp);
|
||||||
return STATUS_ERR;
|
return STATUS_ERR;
|
||||||
}
|
}
|
||||||
|
@ -639,25 +651,30 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list)
|
||||||
free(temp->sename);
|
free(temp->sename);
|
||||||
free(temp->prefix);
|
free(temp->prefix);
|
||||||
free(temp->home);
|
free(temp->home);
|
||||||
|
free(temp->level);
|
||||||
free(temp);
|
free(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_fallback_user(genhomedircon_settings_t *s,
|
static int set_fallback_user(genhomedircon_settings_t *s, const char *user,
|
||||||
const char *user, const char *prefix)
|
const char *prefix, const char *level)
|
||||||
{
|
{
|
||||||
char *fallback_user = strdup(user);
|
char *fallback_user = strdup(user);
|
||||||
char *fallback_user_prefix = strdup(prefix);
|
char *fallback_user_prefix = strdup(prefix);
|
||||||
|
char *fallback_user_level = strdup(level);
|
||||||
|
|
||||||
if (fallback_user == NULL || fallback_user_prefix == NULL) {
|
if (fallback_user == NULL || fallback_user_prefix == NULL || fallback_user_level == NULL) {
|
||||||
free(fallback_user);
|
free(fallback_user);
|
||||||
free(fallback_user_prefix);
|
free(fallback_user_prefix);
|
||||||
|
free(fallback_user_level);
|
||||||
return STATUS_ERR;
|
return STATUS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(s->fallback_user);
|
free(s->fallback_user);
|
||||||
free(s->fallback_user_prefix);
|
free(s->fallback_user_prefix);
|
||||||
|
free(s->fallback_user_level);
|
||||||
s->fallback_user = fallback_user;
|
s->fallback_user = fallback_user;
|
||||||
s->fallback_user_prefix = fallback_user_prefix;
|
s->fallback_user_prefix = fallback_user_prefix;
|
||||||
|
s->fallback_user_level = fallback_user_level;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,6 +687,7 @@ static int setup_fallback_user(genhomedircon_settings_t * s)
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
const char *seuname = NULL;
|
const char *seuname = NULL;
|
||||||
const char *prefix = NULL;
|
const char *prefix = NULL;
|
||||||
|
const char *level = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int retval;
|
int retval;
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
|
@ -692,11 +710,17 @@ static int setup_fallback_user(genhomedircon_settings_t * s)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (semanage_user_query(s->h_semanage, key, &u) < 0)
|
if (semanage_user_query(s->h_semanage, key, &u) < 0)
|
||||||
|
{
|
||||||
prefix = name;
|
prefix = name;
|
||||||
|
level = "s0";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
prefix = semanage_user_get_prefix(u);
|
prefix = semanage_user_get_prefix(u);
|
||||||
|
level = semanage_user_get_mlslevel(u);
|
||||||
|
}
|
||||||
|
|
||||||
if (set_fallback_user(s, seuname, prefix) != 0)
|
if (set_fallback_user(s, seuname, prefix, level) != 0)
|
||||||
errors = STATUS_ERR;
|
errors = STATUS_ERR;
|
||||||
semanage_user_key_free(key);
|
semanage_user_key_free(key);
|
||||||
if (u)
|
if (u)
|
||||||
|
@ -724,6 +748,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
const char *seuname = NULL;
|
const char *seuname = NULL;
|
||||||
const char *prefix = NULL;
|
const char *prefix = NULL;
|
||||||
|
const char *level = NULL;
|
||||||
struct passwd pwstorage, *pwent = NULL;
|
struct passwd pwstorage, *pwent = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
long rbuflen;
|
long rbuflen;
|
||||||
|
@ -775,8 +800,10 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
|
||||||
&name_user_cmp);
|
&name_user_cmp);
|
||||||
if (u) {
|
if (u) {
|
||||||
prefix = semanage_user_get_prefix(*u);
|
prefix = semanage_user_get_prefix(*u);
|
||||||
|
level = semanage_user_get_mlslevel(*u);
|
||||||
} else {
|
} else {
|
||||||
prefix = name;
|
prefix = name;
|
||||||
|
level = "s0";
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
|
retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
|
||||||
|
@ -803,7 +830,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (push_user_entry(&head, name, seuname,
|
if (push_user_entry(&head, name, seuname,
|
||||||
prefix, pwent->pw_dir) != STATUS_SUCCESS) {
|
prefix, pwent->pw_dir, level) != STATUS_SUCCESS) {
|
||||||
*errors = STATUS_ERR;
|
*errors = STATUS_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -846,7 +873,7 @@ static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out,
|
||||||
if (write_home_dir_context(s, out, homedir_context_tpl,
|
if (write_home_dir_context(s, out, homedir_context_tpl,
|
||||||
users->name,
|
users->name,
|
||||||
users->sename, users->home,
|
users->sename, users->home,
|
||||||
users->prefix)) {
|
users->prefix, users->level)) {
|
||||||
return STATUS_ERR;
|
return STATUS_ERR;
|
||||||
}
|
}
|
||||||
if (write_user_context(s, out, user_context_tpl, users->name,
|
if (write_user_context(s, out, user_context_tpl, users->name,
|
||||||
|
@ -910,7 +937,7 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out)
|
||||||
homedir_context_tpl,
|
homedir_context_tpl,
|
||||||
s->fallback_user, s->fallback_user,
|
s->fallback_user, s->fallback_user,
|
||||||
ustr_cstr(temp),
|
ustr_cstr(temp),
|
||||||
s->fallback_user_prefix) !=
|
s->fallback_user_prefix, s->fallback_user_level) !=
|
||||||
STATUS_SUCCESS) {
|
STATUS_SUCCESS) {
|
||||||
ustr_sc_free(&temp);
|
ustr_sc_free(&temp);
|
||||||
retval = STATUS_ERR;
|
retval = STATUS_ERR;
|
||||||
|
@ -967,7 +994,8 @@ int semanage_genhomedircon(semanage_handle_t * sh,
|
||||||
|
|
||||||
s.fallback_user = strdup(FALLBACK_USER);
|
s.fallback_user = strdup(FALLBACK_USER);
|
||||||
s.fallback_user_prefix = strdup(FALLBACK_USER_PREFIX);
|
s.fallback_user_prefix = strdup(FALLBACK_USER_PREFIX);
|
||||||
if (s.fallback_user == NULL || s.fallback_user_prefix == NULL)
|
s.fallback_user_level = strdup(FALLBACK_USER_LEVEL);
|
||||||
|
if (s.fallback_user == NULL || s.fallback_user_prefix == NULL || s.fallback_user_level == NULL)
|
||||||
return STATUS_ERR;
|
return STATUS_ERR;
|
||||||
|
|
||||||
s.usepasswd = usepasswd;
|
s.usepasswd = usepasswd;
|
||||||
|
|
Loading…
Reference in a new issue