Re: [RFC][PATCH] user_transition support for libsepol/checkpolicy

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stephen Smalley wrote:
> On Mon, 2008-03-24 at 13:40 -0400, Joshua Brindle wrote:
>> This implements user_transition in the toolchain. It should help on
>> distro's like Ubuntu that can't use run_init due to the user not knowing
>> the root password. It also seems like a more eloquent way to handle
>> service restarts than assigning system_r to user accounts and having the
>> daemons run as someuser:system_r:foo_t.
> 
> Yes, that's something that has been wanted in Fedora for quite some
> time.
> 
> The real issue with run_init isn't the re-authentication stage, as that
> can always be disabled via pam config (and was just a weak form of
> confirming user intent, not an authorization mechanism), but rather the
> difficulty in transparently interposing it into all situations where
> services get started/re-started.  Only Gentoo seemed to have a good
> story there.
> 
>> This has some issues in policy due to users not always being known in
>> the policy (eg., semanage users). I hope Chris or Dan will be able to
>> give some suggestions there.
> 
> I'm not sure why anyone needs to add users to policy via semanage users
> given the base set of generic users and the ability to map Linux users
> to them via seusers aka semanage login.
> 
Can we define users in modules?  I envision and have provided
modifications to do system-config-selinux for someone to take a guest_t
and create a new role/type guest_plussendmail_t for a limited privileged
login account that can connect to the sendmail port.

So once I have created this new User Type,  I need a way to define the
user.  In Fedora right now, we define the xguest and guest accounts in
the postinstall using semanage.

>> The kernel patch (forthcoming after this is accepted) so far only
>> implements the transition on process transitions. Later on I plan on
>> doing a patch to expand role_transition to object classes (this is a
>> change needed for policy rbac support to work). I suspect I'll do the
>> same for user at that time. The question here is, do we think its worth
>> it to do fine grained transitions like we did for range_trans? (I don't).
> 
> Offhand, I can't see a use for per-class user transitions, if that is
> what you mean.
> 
> I don't think per-class role transitions is really the fundamental
> obstacle to enabling use of roles on objects - more thought is required
> there.  What will be fun there is role/type and user/range validation,
> which presently gets to ignore everything that has object_r.
> 
>> Index: libsepol/include/sepol/policydb/policydb.h
>> ===================================================================
>> --- libsepol/include/sepol/policydb/policydb.h	(revision 2854)
>> +++ libsepol/include/sepol/policydb/policydb.h	(working copy)
>> @@ -156,6 +156,14 @@
>> 	mls_level_t exp_dfltlevel; /* expanded range used for validation */
>> } user_datum_t;
>>
>> +typedef struct user_trans {
>> +	uint32_t user;		/* current role */
>> +	uint32_t type;		/* program executable type */
>> +	uint32_t new_user;	/* new role */
>> +	struct user_trans *next;
>> +} user_trans_t;
>> +
>> +
>> /* Sensitivity attributes */
>> typedef struct level_datum {
>> 	mls_level_t *level;	/* sensitivity and associated categories */
>> @@ -225,6 +233,13 @@
>> 	struct role_trans_rule *next;
>> } role_trans_rule_t;
>>
>> +typedef struct user_trans_rule {
>> +	ebitmap_t users;	/* current role */
>> +	type_set_t types;	/* program executable type */
>> +	uint32_t new_user;	/* new role */
>> +	struct user_trans_rule *next;
>> +} user_trans_rule_t;
>> +
>> typedef struct role_allow_rule {
>> 	role_set_t roles;	/* current role */
>> 	role_set_t new_roles;	/* new roles */
>> @@ -348,6 +363,9 @@
>> 	char *module_name;
>>
>> 	struct avrule_decl *next;
>> +
>> +	user_trans_rule_t *user_tr_rules;
>> +	
>> } avrule_decl_t;
>>
>> typedef struct avrule_block {
>> @@ -470,6 +488,8 @@
>>
>> 	ebitmap_t policycaps;
>>
>> +	user_trans_t *user_tr;
>> +
>> 	unsigned policyvers;
>>
>> 	unsigned handle_unknown;
>> @@ -524,6 +544,9 @@
>> extern void role_trans_rule_init(role_trans_rule_t * x);
>> extern void role_trans_rule_list_destroy(role_trans_rule_t * x);
>>
>> +extern void user_trans_rule_init(user_trans_rule_t * x);
>> +extern void user_trans_rule_list_destroy(user_trans_rule_t * x);
>> +
>> extern void role_datum_init(role_datum_t * x);
>> extern void role_datum_destroy(role_datum_t * x);
>> extern void role_allow_rule_init(role_allow_rule_t * x);
>> @@ -588,10 +611,11 @@
>> #define POLICYDB_VERSION_AVTAB		20
>> #define POLICYDB_VERSION_RANGETRANS	21
>> #define POLICYDB_VERSION_POLCAP		22
>> +#define POLICYDB_VERSION_USERTRANS	23
>>
>> /* Range of policy versions we understand*/
>> #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
>> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_POLCAP
>> +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_USERTRANS
>>
>> /* Module versions and specific changes*/
>> #define MOD_POLICYDB_VERSION_BASE	   4
>> @@ -600,9 +624,10 @@
>> #define MOD_POLICYDB_VERSION_RANGETRANS	   6
>> #define MOD_POLICYDB_VERSION_MLS_USERS	   6
>> #define MOD_POLICYDB_VERSION_POLCAP	   7
>> +#define MOD_POLICYDB_VERSION_USERTRANS	   8
>>
>> #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
>> -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_POLCAP
>> +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_USERTRANS
>>
>> #define POLICYDB_CONFIG_MLS    1
>>
>> Index: libsepol/src/policydb.c
>> ===================================================================
>> --- libsepol/src/policydb.c	(revision 2854)
>> +++ libsepol/src/policydb.c	(working copy)
>> @@ -105,6 +105,12 @@
>> 	 .ocon_num = OCON_NODE6 + 1,
>> 	 },
>> 	{
>> +	 .type = POLICY_KERN,
>> +	 .version = POLICYDB_VERSION_USERTRANS,
>> +	 .sym_num = SYM_NUM,
>> +	 .ocon_num = OCON_NODE6 + 1,
>> +	 },
>> +	{
>> 	 .type = POLICY_BASE,
>> 	 .version = MOD_POLICYDB_VERSION_BASE,
>> 	 .sym_num = SYM_NUM,
>> @@ -129,6 +135,12 @@
>> 	 .ocon_num = OCON_NODE6 + 1,
>> 	 },
>> 	{
>> +	 .type = POLICY_BASE,
>> +	 .version = MOD_POLICYDB_VERSION_USERTRANS,
>> +	 .sym_num = SYM_NUM,
>> +	 .ocon_num = OCON_NODE6 + 1,
>> +	 },
>> +	{
>> 	 .type = POLICY_MOD,
>> 	 .version = MOD_POLICYDB_VERSION_BASE,
>> 	 .sym_num = SYM_NUM,
>> @@ -150,7 +162,14 @@
>> 	 .type = POLICY_MOD,
>> 	 .version = MOD_POLICYDB_VERSION_POLCAP,
>> 	 .sym_num = SYM_NUM,
>> -	 .ocon_num = 0},
>> +	 .ocon_num = 0
>> +	 },
>> +	{
>> +	 .type = POLICY_MOD,
>> +	 .version = MOD_POLICYDB_VERSION_USERTRANS,
>> +	 .sym_num = SYM_NUM,
>> +	 .ocon_num = 0
>> +	 },
>> };
>>
>> #if 0
>> @@ -348,6 +367,30 @@
>> 	}
>> }
>>
>> +void user_trans_rule_init(user_trans_rule_t * x)
>> +{
>> +	memset(x, 0, sizeof(*x));
>> +	ebitmap_init(&x->users);
>> +	type_set_init(&x->types);
>> +}
>> +
>> +void user_trans_rule_destroy(user_trans_rule_t * x)
>> +{
>> +	if (x != NULL) {
>> +		ebitmap_init(&x->users);
>> +		type_set_destroy(&x->types);
>> +	}
>> +}
>> +
>> +void user_trans_rule_list_destroy(user_trans_rule_t * x)
>> +{
>> +	while (x != NULL) {
>> +		user_trans_rule_t *next = x->next;
>> +		user_trans_rule_destroy(x);
>> +		free(x);
>> +		x = next;
>> +	}
>> +}
>> void role_allow_rule_init(role_allow_rule_t * x)
>> {
>> 	memset(x, 0, sizeof(role_allow_rule_t));
>> @@ -985,6 +1028,7 @@
>> 	unsigned int i;
>> 	role_allow_t *ra, *lra = NULL;
>> 	role_trans_t *tr, *ltr = NULL;
>> +	user_trans_t *ut, *lut = NULL;
>> 	range_trans_t *rt, *lrt = NULL;
>>
>> 	if (!p)
>> @@ -1058,6 +1102,14 @@
>> 	if (ltr)
>> 		free(ltr);
>>
>> +	for (ut = p->user_tr; ut; ut = ut->next) {
>> +		if (lut)
>> +			free(lut);
>> +		lut = ut;
>> +	}
>> +	if (lut)
>> +		free(lut);
>> +
>> 	for (ra = p->role_allow; ra; ra = ra->next) {
>> 		if (lra)
>> 			free(lra);
>> @@ -1983,6 +2035,40 @@
>> 	return 0;
>> }
>>
>> +int user_trans_read(user_trans_t ** t, struct policy_file *fp)
>> +{
>> +        unsigned int i;
>> +        uint32_t buf[3], nel;
>> +        user_trans_t *ut, *lut;
>> +        int rc;
>> +
>> +        rc = next_entry(buf, fp, sizeof(uint32_t));
>> +        if (rc < 0)
>> +                return -1;
>> +        nel = le32_to_cpu(buf[0]);
>> +        lut = NULL;
>> +        for (i = 0; i < nel; i++) {
>> +                ut = calloc(1, sizeof(struct user_trans));
>> +                if (!ut) {
>> +                        return -1;
>> +                }
>> +                if (lut) {
>> +                        lut->next = ut;
>> +                } else {
>> +                        *t = ut;
>> +                }
>> +                rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
>> +                if (rc < 0)
>> +                        return -1;
>> +                ut->user = le32_to_cpu(buf[0]);
>> +                ut->type = le32_to_cpu(buf[1]);
>> +                ut->new_user = le32_to_cpu(buf[2]);
>> +                lut = ut;
>> +        }
>> +        return 0;
>> +}
>> +
>> +
>> int role_allow_read(role_allow_t ** r, struct policy_file *fp)
>> {
>> 	unsigned int i;
>> @@ -2679,6 +2765,48 @@
>> 	return 0;
>> }
>>
>> +static int user_trans_rule_read(user_trans_rule_t ** u, struct 
>> policy_file *fp)
>> +{
>> +        uint32_t buf[1], nel;
>> +        unsigned int i;
>> +        user_trans_rule_t *ut, *lut;
>> +        int rc;
>> +
>> +        rc = next_entry(buf, fp, sizeof(uint32_t));
>> +        if (rc < 0)
>> +                return -1;
>> +        nel = le32_to_cpu(buf[0]);
>> +        lut = NULL;
>> +        for (i = 0; i < nel; i++) {
>> +                ut = malloc(sizeof(user_trans_rule_t));
>> +                if (!ut) {
>> +                        return -1;
>> +                }
>> +                user_trans_rule_init(ut);
>> +
>> +                if (lut) {
>> +                        lut->next = ut;
>> +                } else {
>> +                        *u = ut;
>> +                }
>> +
>> +                if (ebitmap_read(&ut->users, fp))
>> +                        return -1;
>> +
>> +                if (type_set_read(&ut->types, fp))
>> +                        return -1;
>> +
>> +                rc = next_entry(buf, fp, sizeof(uint32_t));
>> +                if (rc < 0)
>> +                        return -1;
>> +                ut->new_user = le32_to_cpu(buf[0]);
>> +                lut = ut;
>> +        }
>> +
>> +        return 0;
>> +}
>> +
>> +
>> static int role_allow_rule_read(role_allow_rule_t ** r, struct 
>> policy_file *fp)
>> {
>> 	unsigned int i;
>> @@ -2805,9 +2933,14 @@
>> 	if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
>> 	    avrule_read_list(p, &decl->avrules, fp) == -1 ||
>> 	    role_trans_rule_read(&decl->role_tr_rules, fp) == -1 ||
>> -	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
>> +	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1)
>> +	    {
>> 		return -1;
>> 	}
>> +	if (p->policyvers >= MOD_POLICYDB_VERSION_USERTRANS) {
>> +		if (user_trans_rule_read(&decl->user_tr_rules, fp))
>> +			return -1;
>> +	}
>> 	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
>> 	    range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
>> 		return -1;
>> @@ -3179,6 +3312,10 @@
>> 				goto bad;
>> 		if (role_trans_read(&p->role_tr, fp))
>> 			goto bad;
>> +		if (r_policyvers >= POLICYDB_VERSION_USERTRANS) {
>> +			if (user_trans_read(&p->user_tr, fp))
>> +				goto bad;
>> +		}
>> 		if (role_allow_read(&p->role_allow, fp))
>> 			goto bad;
>> 	} else {
>> Index: libsepol/src/expand.c
>> ===================================================================
>> --- libsepol/src/expand.c	(revision 2854)
>> +++ libsepol/src/expand.c	(working copy)
>> @@ -1060,6 +1060,80 @@
>> 	return 0;
>> }
>>
>> +static int copy_user_trans(expand_state_t * state, user_trans_rule_t * 
>> rules)
>> +{
>> +	unsigned int i, j;
>> +	user_trans_t *n, *l, *cur_trans;
>> +	user_trans_rule_t *cur;
>> +	ebitmap_t types;
>> +	ebitmap_node_t *rnode, *tnode;
>> +
>> +	/* start at the end of the list */
>> +	for (l = state->out->user_tr; l && l->next; l = l->next) ;
>> +
>> +	cur = rules;
>> +	while (cur) {
>> +		ebitmap_init(&types);
>> +
>> +		if (expand_convert_type_set
>> +		    (state->out, state->typemap, &cur->types, &types, 1)) {
>> +			ERR(state->handle, "Out of memory!");
>> +			return -1;
>> +		}
>> +		ebitmap_for_each_bit(&cur->users, rnode, i) {
>> +			if (!ebitmap_node_get_bit(rnode, i))
>> +				continue;
>> +			ebitmap_for_each_bit(&types, tnode, j) {
>> +				if (!ebitmap_node_get_bit(tnode, j))
>> +					continue;
>> +
>> +				cur_trans = state->out->user_tr;
>> +				while (cur_trans) {
>> +					if ((cur_trans->user == i + 1) &&
>> +					    (cur_trans->type == j + 1)) {
>> +						if (cur_trans->new_user ==
>> +						    cur->new_user) {
>> +							break;
>> +						} else {
>> +							ERR(state->handle,
>> +							    "Conflicting user trans rule %s %s : %s",
>> +							    state->out->p_user_val_to_name[i],
>> +							    state->out->p_type_val_to_name[j],
>> +							    state->out->p_user_val_to_name[cur->new_user - 1]);
>> +							return -1;
>> +						}
>> +					}
>> +					cur_trans = cur_trans->next;
>> +				}
>> +				if (cur_trans)
>> +					continue;
>> +
>> +				n = (user_trans_t *)
>> +				    malloc(sizeof(user_trans_t));
>> +				if (!n) {
>> +					ERR(state->handle, "Out of memory!");
>> +					return -1;
>> +				}
>> +				memset(n, 0, sizeof(user_trans_t));
>> +				n->user = i + 1;
>> +				n->type = j + 1;
>> +				n->new_user = cur->new_user;
>> +				if (l) {
>> +					l->next = n;
>> +				} else {
>> +					state->out->user_tr = n;
>> +				}
>> +				l = n;
>> +			}
>> +		}
>> +
>> +		ebitmap_destroy(&types);
>> +
>> +		cur = cur->next;
>> +	}
>> +	return 0;
>> +}
>> +
>> static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t 
>> tclass,
>> 			      mls_semantic_range_t * trange,
>> 			      expand_state_t * state)
>> @@ -2163,6 +2237,9 @@
>> 			goto cleanup;
>> 		}
>>
>> +		if (copy_user_trans(state, decl->user_tr_rules))
>> +			goto cleanup;
>> +
>> 		/* expand the range transition rules */
>> 		if (expand_range_trans(state, decl->range_tr_rules))
>> 			goto cleanup;
>> Index: libsepol/src/write.c
>> ===================================================================
>> --- libsepol/src/write.c	(revision 2854)
>> +++ libsepol/src/write.c	(working copy)
>> @@ -487,6 +487,31 @@
>> 	return POLICYDB_SUCCESS;
>> }
>>
>> +static int user_trans_write(user_trans_t * u, struct policy_file *fp)
>> +{
>> +	user_trans_t *tr;
>> +	uint32_t buf[3];
>> +	size_t nel, items;
>> +
>> +	nel = 0;
>> +	for (tr = u; tr; tr = tr->next)
>> +		nel++;
>> +	buf[0] = cpu_to_le32(nel);
>> +	items = put_entry(buf, sizeof(uint32_t), 1, fp);
>> +	if (items != 1)
>> +		return POLICYDB_ERROR;
>> +	for (tr = u; tr; tr = tr->next) {
>> +		buf[0] = cpu_to_le32(tr->user);
>> +		buf[1] = cpu_to_le32(tr->type);
>> +		buf[2] = cpu_to_le32(tr->new_user);
>> +		items = put_entry(buf, sizeof(uint32_t), 3, fp);
>> +		if (items != 3)
>> +			return POLICYDB_ERROR;
>> +	}
>> +
>> +	return POLICYDB_SUCCESS;
>> +}
>> +
>> static int role_allow_write(role_allow_t * r, struct policy_file *fp)
>> {
>> 	role_allow_t *ra;
>> @@ -1325,6 +1350,32 @@
>> 	return POLICYDB_SUCCESS;
>> }
>>
>> +static int user_trans_rule_write(user_trans_rule_t * t, struct 
>> policy_file *fp)
>> +{
>> +	int nel = 0;
>> +	size_t items;
>> +	uint32_t buf[1];
>> +	user_trans_rule_t *tr;
>> +
>> +	for (tr = t; tr; tr = tr->next)
>> +		nel++;
>> +	buf[0] = cpu_to_le32(nel);
>> +	items = put_entry(buf, sizeof(uint32_t), 1, fp);
>> +	if (items != 1)
>> +		return POLICYDB_ERROR;
>> +	for (tr = t; tr; tr = tr->next) {
>> +		if (ebitmap_write(&tr->users, fp))
>> +			return POLICYDB_ERROR;
>> +		if (type_set_write(&tr->types, fp))
>> +			return POLICYDB_ERROR;
>> +		buf[0] = cpu_to_le32(tr->new_user);
>> +		items = put_entry(buf, sizeof(uint32_t), 1, fp);
>> +		if (items != 1)
>> +			return POLICYDB_ERROR;
>> +	}
>> +	return POLICYDB_SUCCESS;
>> +}
>> +
>> static int role_allow_rule_write(role_allow_rule_t * r, struct 
>> policy_file *fp)
>> {
>> 	int nel = 0;
>> @@ -1414,6 +1465,10 @@
>> 	    role_allow_rule_write(decl->role_allow_rules, fp) == -1) {
>> 		return POLICYDB_ERROR;
>> 	}
>> +	if (p->policyvers >= MOD_POLICYDB_VERSION_USERTRANS) {
>> +		if (user_trans_rule_write(decl->user_tr_rules, fp))	
>> +			return POLICYDB_ERROR;
>> +	}
>> 	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
>> 	    range_trans_rule_write(decl->range_tr_rules, fp) == -1) {
>> 		return POLICYDB_ERROR;
>> @@ -1642,6 +1697,10 @@
>> 		}
>> 		if (role_trans_write(p->role_tr, fp))
>> 			return POLICYDB_ERROR;
>> +		if (p->policyvers >= POLICYDB_VERSION_USERTRANS) {
>> +			if (user_trans_write(p->user_tr, fp))
>> +				return POLICYDB_ERROR;
>> +		}
>> 		if (role_allow_write(p->role_allow, fp))
>> 			return POLICYDB_ERROR;
>> 	} else {
>> Index: libsepol/src/link.c
>> ===================================================================
>> --- libsepol/src/link.c	(revision 2854)
>> +++ libsepol/src/link.c	(working copy)
>> @@ -848,6 +848,34 @@
>> 	return -1;
>> }
>>
>> +static int user_bitmap_or_convert(ebitmap_t * users, ebitmap_t * dst,
>> +			       policy_module_t * mod, link_state_t * state)
>> +{
>> +	unsigned int i;
>> +	ebitmap_t tmp;
>> +	ebitmap_node_t *rnode;
>> +
>> +	ebitmap_init(&tmp);
>> +	ebitmap_for_each_bit(users, rnode, i) {
>> +		if (ebitmap_node_get_bit(rnode, i)) {
>> +			assert(mod->map[SYM_USERS][i]);
>> +			if (ebitmap_set_bit
>> +			    (&tmp, mod->map[SYM_USERS][i] - 1, 1)) {
>> +				goto cleanup;
>> +			}
>> +		}
>> +	}
>> +	if (ebitmap_union(dst, &tmp)) {
>> +		goto cleanup;
>> +	}
>> +	ebitmap_destroy(&tmp);
>> +	return 0;
>> +      cleanup:
>> +	ERR(state->handle, "Out of memory!");
>> +	ebitmap_destroy(&tmp);
>> +	return -1;
>> +}
>> +
>> static int mls_level_convert(mls_semantic_level_t * src, 
>> mls_semantic_level_t * dst,
>> 			     policy_module_t * mod, link_state_t * state)
>> {
>> @@ -1004,13 +1032,22 @@
>> 	link_state_t *state = (link_state_t *) data;
>> 	policy_module_t *mod = state->cur;
>> 	symtab_t *usertab;
>> +	scope_datum_t *scope;
>>
>> 	user = (user_datum_t *) datum;
>>
>> +	scope = hashtab_search(state->cur->policy->p_users_scope.table, key);
>> +	assert(scope);
>> +	if (scope->scope == SCOPE_REQ) {
>> +		//this is required user, no role or mls data
>> +		return 0;
>> +	}
>> +
>> 	if (state->dest_decl == NULL)
>> 		usertab = &state->base->p_users;
>> -	else
>> +	else {
>> 		usertab = &state->dest_decl->p_users;
>> +	}
>>
>> 	new_user = hashtab_search(usertab->table, id);
>> 	assert(new_user != NULL);
>> @@ -1173,6 +1210,49 @@
>> 	return -1;
>> }
>>
>> +static int copy_user_trans_list(user_trans_rule_t * list,
>> +                                user_trans_rule_t ** dst,
>> +                                policy_module_t * module, link_state_t 
>> * state)
>> +{
>> +        user_trans_rule_t *cur, *new_rule = NULL, *tail;
>> +
>> +        cur = list;
>> +        tail = *dst;
>> +        while (tail && tail->next) {
>> +                tail = tail->next;
>> +        }
>> +        while (cur) {
>> +                if ((new_rule =
>> +                     (user_trans_rule_t *) 
>> malloc(sizeof(user_trans_rule_t))) ==
>> +                    NULL) {
>> +                        goto cleanup;
>> +                }
>> +                user_trans_rule_init(new_rule);
>> +
>> +                if (user_bitmap_or_convert(&cur->users, 
>> &new_rule->users, module, state))
>> +			goto cleanup;
>> +		if (type_set_or_convert(&cur->types, &new_rule->types, module, state)) {
>> +                        goto cleanup;
>> +                }
>> +
>> +                new_rule->new_user = 
>> module->map[SYM_USERS][cur->new_user - 1];
>> +
>> +                if (*dst == NULL) {
>> +                        *dst = new_rule;
>> +                } else {
>> +                        tail->next = new_rule;
>> +                }
>> +                tail = new_rule;
>> +                cur = cur->next;
>> +        }
>> +        return 0;
>> +      cleanup:
>> +        ERR(state->handle, "Out of memory!");
>> +        user_trans_rule_list_destroy(new_rule);
>> +        return -1;
>> +}
>> +
>> +
>> static int copy_role_allow_list(role_allow_rule_t * list,
>> 				role_allow_rule_t ** dst,
>> 				policy_module_t * module, link_state_t * state)
>> @@ -1446,6 +1526,10 @@
>> 		return -1;
>> 	}
>>
>> +	if (copy_user_trans_list(src_decl->user_tr_rules, 
>> &dest_decl->user_tr_rules,
>> +				 module, state))
>> +		return -1;
>> +
>> 	if (copy_range_trans_list(src_decl->range_tr_rules,
>> 				  &dest_decl->range_tr_rules, module, state))
>> 		return -1;
>> Index: checkpolicy/test/dismod.c
>> ===================================================================
>> --- checkpolicy/test/dismod.c	(revision 2854)
>> +++ checkpolicy/test/dismod.c	(working copy)
>> @@ -354,6 +354,21 @@
>> 	return 0;
>> }
>>
>> +int display_user_set(ebitmap_t *u, policydb_t *p, FILE *fp)
>> +{
>> +	ebitmap_node_t *node;
>> +	int i;
>> +
>> +	fprintf(fp, " { ");
>> +	ebitmap_for_each_bit(u, node, i) {
>> +		if (ebitmap_node_get_bit(node, i)) {
>> +			display_id(p, fp, SYM_USERS, i, "");
>> +		}
>> +	}
>> +	fprintf(fp, " } ");
>> +	return 0;
>> +}
>> +
>> int display_bools(policydb_t * p, FILE * fp)
>> {
>> 	int i;
>> @@ -461,7 +476,18 @@
>> 		fprintf(fp, "\n");
>> 	}
>> }
>> +void display_user_trans(user_trans_rule_t * tr, policydb_t * p, FILE * fp)
>>
>> +{
>> +	for (; tr; tr = tr->next) {
>> +		fprintf(fp, "user transition ");
>> +		display_user_set(&tr->users, p, fp);
>> +		display_type_set(&tr->types, 0, p, fp);
>> +		display_id(p, fp, SYM_USERS, tr->new_user - 1, " :");
>> +		fprintf(fp, "\n");
>> +	}
>> +}
>> +
>> void display_role_allow(role_allow_rule_t * ra, policydb_t * p, FILE * fp)
>> {
>> 	for (; ra; ra = ra->next) {
>> @@ -641,6 +667,10 @@
>> 			}
>> 			break;
>> 		}
>> +	case 7:{
>> +			display_user_trans(decl->user_tr_rules, policy, out_fp);
>> +			break;
>> +		}
>> 	default:{
>> 			assert(0);
>> 		}
>> @@ -806,6 +836,7 @@
>> 	printf("c)  Display policy capabilities\n");
>> 	printf("l)  Link in a module\n");
>> 	printf("u)  Display the unknown handling setting\n");
>> +	printf("U)  Display user transitions\n");
>> 	printf("\n");
>> 	printf("f)  set output file\n");
>> 	printf("m)  display menu\n");
>> @@ -918,9 +949,11 @@
>> 			display_policycaps(&policydb, out_fp);
>> 			break;
>> 		case 'u':
>> -		case 'U':
>> 			display_handle_unknown(&policydb, out_fp);
>> 			break;
>> +		case 'U':
>> +			display_avblock(7, 0, &policydb, out_fp);
>> +			break;
>> 		case 'f':
>> 			printf
>> 			    ("\nFilename for output (<CR> for screen output): ");
>> Index: checkpolicy/test/dispol.c
>> ===================================================================
>> --- checkpolicy/test/dispol.c	(revision 2854)
>> +++ checkpolicy/test/dispol.c	(working copy)
>> @@ -299,6 +299,18 @@
>> 	return 0;
>> }
>>
>> +static void display_user_transitions(policydb_t *p, FILE *fp)
>> +{
>> +	user_trans_t *cur;
>> +	for (cur = p->user_tr; cur; cur = cur->next) {
>> +		fprintf(fp, "user_transition ");
>> +		fprintf(fp, "%s %s %s;\n",
>> +			p->p_user_val_to_name[cur->user - 1],
>> +			p->p_type_val_to_name[cur->type - 1],
>> +			p->p_user_val_to_name[cur->new_user - 1]);
>> +	}
>> +}
>> +
>> static void display_policycaps(policydb_t * p, FILE * fp)
>> {
>> 	ebitmap_node_t *node;
>> @@ -332,6 +344,7 @@
>> 	printf("\n");
>> 	printf("c)  display policy capabilities\n");
>> 	printf("u)  display unknown handling setting\n");
>> +	printf("U)  display user transitions\n");
>> 	printf("f)  set output file\n");
>> 	printf("m)  display menu\n");
>> 	printf("q)  quit\n");
>> @@ -448,9 +461,11 @@
>> 			display_policycaps(&policydb, out_fp);
>> 			break;
>> 		case 'u':
>> -		case 'U':
>> 			display_handle_unknown(&policydb, out_fp);
>> 			break;
>> +		case 'U':
>> +			display_user_transitions(&policydb, out_fp);
>> +			break;
>> 		case 'f':
>> 			printf
>> 			    ("\nFilename for output (<CR> for screen output): ");
>> Index: checkpolicy/test/Makefile
>> ===================================================================
>> --- checkpolicy/test/Makefile	(revision 2854)
>> +++ checkpolicy/test/Makefile	(working copy)
>> @@ -6,7 +6,7 @@
>> LIBDIR=$(PREFIX)/lib
>> INCLUDEDIR ?= $(PREFIX)/include
>>
>> -CFLAGS ?= -g -Wall -O2 -pipe
>> +CFLAGS ?= -g3 -gdwarf-2 -Wall -O0 -pipe
>> override CFLAGS += -I$(INCLUDEDIR)
>>
>> LDLIBS=-lfl -lsepol -lselinux $(LIBDIR)/libsepol.a -L$(LIBDIR)
>> Index: checkpolicy/policy_define.c
>> ===================================================================
>> --- checkpolicy/policy_define.c	(revision 2854)
>> +++ checkpolicy/policy_define.c	(working copy)
>> @@ -2020,6 +2020,76 @@
>> 	return -1;
>> }
>>
>> +int define_user_trans(void)
>> +{
>> +        char *id;
>> +        user_datum_t *user, *u;
>> +	ebitmap_t users;
>> +        type_set_t types;
>> +        struct user_trans_rule *rule = NULL;
>> +        int add = 1;
>> +
>> +        if (pass == 1) {
>> +                while ((id = queue_remove(id_queue)))
>> +                        free(id);
>> +                while ((id = queue_remove(id_queue)))
>> +                        free(id);
>> +                id = queue_remove(id_queue);
>> +                free(id);
>> +                return 0;
>> +        }
>> +
>> +        ebitmap_init(&users);
>> +        type_set_init(&types);
>> +
>> +	while ((id = queue_remove(id_queue))) {
>> +		u = hashtab_search(policydbp->p_users.table, id);
>> +		if (!u) {
>> +			yyerror2("unknown user %s", id);
>> +			free(id);
>> +			return -1;
>> +		}
>> +		if (ebitmap_set_bit(&users, u->s.value - 1, TRUE))
>> +			return -1;
>> +	}
>> +	while ((id = queue_remove(id_queue))) {
>> +		if (set_types(&types, id, &add, 0))
>> +			return -1;
>> +	}
>> +	id = (char *)queue_remove(id_queue);
>> +	if (!id) {
>> +		yyerror("no new user in transition definition?");
>> +		goto bad;
>> +	}
>> +	if (!is_id_in_scope(SYM_USERS, id)) {
>> +		yyerror2("user %s is not within scope", id);
>> +		free(id);
>> +		goto bad;
>> +	}
>> +	user = hashtab_search(policydbp->p_users.table, id);
>> +	if (!user) {
>> +		yyerror2("unknown user %s used in transition definition", id);
>> +		goto bad;
>> +	}
>> +	rule = malloc(sizeof(struct user_trans_rule));
>> +	if (!rule) {
>> +		yyerror("out of memory");
>> +		return -1;
>> +	}
>> +	memset(rule, 0, sizeof(struct user_trans_rule));
>> +	rule->users = users;
>> +	rule->types = types;
>> +	rule->new_user = user->s.value;
>> +
>> +	append_user_trans(rule);
>> +
>> +	return 0;
>> +
>> +      bad:
>> +	return -1;
>> +}
>> +
>> +
>> int define_role_allow(void)
>> {
>> 	char *id;
>> Index: checkpolicy/policy_scan.l
>> ===================================================================
>> --- checkpolicy/policy_scan.l	(revision 2854)
>> +++ checkpolicy/policy_scan.l	(working copy)
>> @@ -102,6 +102,8 @@
>> type_change			{ return(TYPE_CHANGE); }
>> ROLE_TRANSITION |
>> role_transition			{ return(ROLE_TRANSITION); }
>> +USER_TRANSITION |
>> +user_transition			{ return(USER_TRANSITION); }
>> RANGE_TRANSITION |
>> range_transition		{ return(RANGE_TRANSITION); }
>> SENSITIVITY |
>> Index: checkpolicy/policy_define.h
>> ===================================================================
>> --- checkpolicy/policy_define.h	(revision 2854)
>> +++ checkpolicy/policy_define.h	(working copy)
>> @@ -42,6 +42,7 @@
>> int define_role_allow(void);
>> int define_role_trans(void);
>> int define_role_types(void);
>> +int define_user_trans(void);
>> int define_sens(void);
>> int define_te_avtab(int which);
>> int define_typealias(void);
>> Index: checkpolicy/module_compiler.c
>> ===================================================================
>> --- checkpolicy/module_compiler.c	(revision 2854)
>> +++ checkpolicy/module_compiler.c	(working copy)
>> @@ -1214,6 +1214,17 @@
>> 	decl->role_tr_rules = role_tr_rules;
>> }
>>
>> +void append_user_trans(user_trans_rule_t * user_tr_rules)
>> +{
>> +	avrule_decl_t *decl = stack_top->decl;
>> +
>> +	/* role transitions are not allowed within conditionals */
>> +	assert(stack_top->type == 1);
>> +
>> +	user_tr_rules->next = decl->user_tr_rules;
>> +	decl->user_tr_rules = user_tr_rules;
>> +}
>> +
>> /* this doesn't actually append, but really prepends it */
>> void append_role_allow(role_allow_rule_t * role_allow_rules)
>> {
>> Index: checkpolicy/policy_parse.y
>> ===================================================================
>> --- checkpolicy/policy_parse.y	(revision 2854)
>> +++ checkpolicy/policy_parse.y	(working copy)
>> @@ -103,6 +103,7 @@
>> %token TYPE_MEMBER
>> %token TYPE_CHANGE
>> %token ROLE_TRANSITION
>> +%token USER_TRANSITION
>> %token RANGE_TRANSITION
>> %token SENSITIVITY
>> %token DOMINANCE
>> @@ -261,6 +262,7 @@
>>                          | transition_def
>>                          | range_trans_def
>>                          | te_avtab_def
>> +			| user_trans_def
>> 			;
>> attribute_def           : ATTRIBUTE identifier ';'
>>                          { if (define_attrib()) return -1;}
>> @@ -411,6 +413,9 @@
>> role_trans_def		: ROLE_TRANSITION names names identifier ';'
>> 			{if (define_role_trans()) return -1; }
>> 			;
>> +user_trans_def		: USER_TRANSITION names names identifier ';'
>> +			{ if (define_user_trans()) return -1; }
>> +			;
>> role_allow_def		: ALLOW names names ';'
>> 			{if (define_role_allow()) return -1; }
>> 			;
>> Index: checkpolicy/module_compiler.h
>> ===================================================================
>> --- checkpolicy/module_compiler.h	(revision 2854)
>> +++ checkpolicy/module_compiler.h	(working copy)
>> @@ -80,6 +80,7 @@
>> void append_role_trans(role_trans_rule_t * role_tr_rules);
>> void append_role_allow(role_allow_rule_t * role_allow_rules);
>> void append_range_trans(range_trans_rule_t * range_tr_rules);
>> +void append_user_trans(user_trans_rule_t * user_tr_rules);
>>
>> /* Create a new optional block and add it to the global policy.
>>   * During the second pass resolve the block's requirements.  Return 0
>>
>>

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkfqDBQACgkQrlYvE4MpobNITACfVxCGgzhZqkqNE4YfgIa1Gt/T
z1kAn2Y7kxJFDnimNarKxbZyafpZzlJR
=xZWX
-----END PGP SIGNATURE-----

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux