16cd6a6acSopenharmony_ci/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */
26cd6a6acSopenharmony_ci
36cd6a6acSopenharmony_ci/* FLASK */
46cd6a6acSopenharmony_ci
56cd6a6acSopenharmony_ci/*
66cd6a6acSopenharmony_ci * A security context is a set of security attributes
76cd6a6acSopenharmony_ci * associated with each subject and object controlled
86cd6a6acSopenharmony_ci * by the security policy.  Security contexts are
96cd6a6acSopenharmony_ci * externally represented as variable-length strings
106cd6a6acSopenharmony_ci * that can be interpreted by a user or application
116cd6a6acSopenharmony_ci * with an understanding of the security policy.
126cd6a6acSopenharmony_ci * Internally, the security server uses a simple
136cd6a6acSopenharmony_ci * structure.  This structure is private to the
146cd6a6acSopenharmony_ci * security server and can be changed without affecting
156cd6a6acSopenharmony_ci * clients of the security server.
166cd6a6acSopenharmony_ci */
176cd6a6acSopenharmony_ci
186cd6a6acSopenharmony_ci#ifndef _SEPOL_POLICYDB_CONTEXT_H_
196cd6a6acSopenharmony_ci#define _SEPOL_POLICYDB_CONTEXT_H_
206cd6a6acSopenharmony_ci
216cd6a6acSopenharmony_ci#include <stddef.h>
226cd6a6acSopenharmony_ci#include <sepol/policydb/ebitmap.h>
236cd6a6acSopenharmony_ci#include <sepol/policydb/mls_types.h>
246cd6a6acSopenharmony_ci
256cd6a6acSopenharmony_ci#ifdef __cplusplus
266cd6a6acSopenharmony_ciextern "C" {
276cd6a6acSopenharmony_ci#endif
286cd6a6acSopenharmony_ci
296cd6a6acSopenharmony_ci/*
306cd6a6acSopenharmony_ci * A security context consists of an authenticated user
316cd6a6acSopenharmony_ci * identity, a role, a type and a MLS range.
326cd6a6acSopenharmony_ci */
336cd6a6acSopenharmony_citypedef struct context_struct {
346cd6a6acSopenharmony_ci	uint32_t user;
356cd6a6acSopenharmony_ci	uint32_t role;
366cd6a6acSopenharmony_ci	uint32_t type;
376cd6a6acSopenharmony_ci	mls_range_t range;
386cd6a6acSopenharmony_ci} context_struct_t;
396cd6a6acSopenharmony_ci
406cd6a6acSopenharmony_cistatic inline void mls_context_init(context_struct_t * c)
416cd6a6acSopenharmony_ci{
426cd6a6acSopenharmony_ci	mls_range_init(&c->range);
436cd6a6acSopenharmony_ci}
446cd6a6acSopenharmony_ci
456cd6a6acSopenharmony_cistatic inline int mls_context_cpy(context_struct_t * dst,
466cd6a6acSopenharmony_ci				  const context_struct_t * src)
476cd6a6acSopenharmony_ci{
486cd6a6acSopenharmony_ci
496cd6a6acSopenharmony_ci	if (mls_range_cpy(&dst->range, &src->range) < 0)
506cd6a6acSopenharmony_ci		return -1;
516cd6a6acSopenharmony_ci
526cd6a6acSopenharmony_ci	return 0;
536cd6a6acSopenharmony_ci}
546cd6a6acSopenharmony_ci
556cd6a6acSopenharmony_ci/*
566cd6a6acSopenharmony_ci * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
576cd6a6acSopenharmony_ci */
586cd6a6acSopenharmony_cistatic inline int mls_context_cpy_low(context_struct_t *dst, const context_struct_t *src)
596cd6a6acSopenharmony_ci{
606cd6a6acSopenharmony_ci	int rc;
616cd6a6acSopenharmony_ci
626cd6a6acSopenharmony_ci	dst->range.level[0].sens = src->range.level[0].sens;
636cd6a6acSopenharmony_ci	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
646cd6a6acSopenharmony_ci	if (rc)
656cd6a6acSopenharmony_ci		goto out;
666cd6a6acSopenharmony_ci
676cd6a6acSopenharmony_ci	dst->range.level[1].sens = src->range.level[0].sens;
686cd6a6acSopenharmony_ci	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
696cd6a6acSopenharmony_ci	if (rc)
706cd6a6acSopenharmony_ci		ebitmap_destroy(&dst->range.level[0].cat);
716cd6a6acSopenharmony_ciout:
726cd6a6acSopenharmony_ci	return rc;
736cd6a6acSopenharmony_ci}
746cd6a6acSopenharmony_ci
756cd6a6acSopenharmony_ci/*
766cd6a6acSopenharmony_ci * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
776cd6a6acSopenharmony_ci */
786cd6a6acSopenharmony_cistatic inline int mls_context_cpy_high(context_struct_t *dst, const context_struct_t *src)
796cd6a6acSopenharmony_ci{
806cd6a6acSopenharmony_ci	int rc;
816cd6a6acSopenharmony_ci
826cd6a6acSopenharmony_ci	dst->range.level[0].sens = src->range.level[1].sens;
836cd6a6acSopenharmony_ci	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
846cd6a6acSopenharmony_ci	if (rc)
856cd6a6acSopenharmony_ci		goto out;
866cd6a6acSopenharmony_ci
876cd6a6acSopenharmony_ci	dst->range.level[1].sens = src->range.level[1].sens;
886cd6a6acSopenharmony_ci	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
896cd6a6acSopenharmony_ci	if (rc)
906cd6a6acSopenharmony_ci		ebitmap_destroy(&dst->range.level[0].cat);
916cd6a6acSopenharmony_ciout:
926cd6a6acSopenharmony_ci	return rc;
936cd6a6acSopenharmony_ci}
946cd6a6acSopenharmony_ci
956cd6a6acSopenharmony_cistatic inline int mls_context_glblub(context_struct_t *dst, const context_struct_t *c1, const context_struct_t *c2)
966cd6a6acSopenharmony_ci{
976cd6a6acSopenharmony_ci	return mls_range_glblub(&dst->range, &c1->range, &c2->range);
986cd6a6acSopenharmony_ci}
996cd6a6acSopenharmony_ci
1006cd6a6acSopenharmony_cistatic inline int mls_context_cmp(const context_struct_t * c1, const context_struct_t * c2)
1016cd6a6acSopenharmony_ci{
1026cd6a6acSopenharmony_ci	return (mls_level_eq(&c1->range.level[0], &c2->range.level[0]) &&
1036cd6a6acSopenharmony_ci		mls_level_eq(&c1->range.level[1], &c2->range.level[1]));
1046cd6a6acSopenharmony_ci
1056cd6a6acSopenharmony_ci}
1066cd6a6acSopenharmony_ci
1076cd6a6acSopenharmony_cistatic inline void mls_context_destroy(context_struct_t * c)
1086cd6a6acSopenharmony_ci{
1096cd6a6acSopenharmony_ci	if (c == NULL)
1106cd6a6acSopenharmony_ci		return;
1116cd6a6acSopenharmony_ci
1126cd6a6acSopenharmony_ci	mls_range_destroy(&c->range);
1136cd6a6acSopenharmony_ci	mls_context_init(c);
1146cd6a6acSopenharmony_ci}
1156cd6a6acSopenharmony_ci
1166cd6a6acSopenharmony_cistatic inline void context_init(context_struct_t * c)
1176cd6a6acSopenharmony_ci{
1186cd6a6acSopenharmony_ci	memset(c, 0, sizeof(*c));
1196cd6a6acSopenharmony_ci}
1206cd6a6acSopenharmony_ci
1216cd6a6acSopenharmony_cistatic inline int context_cpy(context_struct_t * dst, const context_struct_t * src)
1226cd6a6acSopenharmony_ci{
1236cd6a6acSopenharmony_ci	dst->user = src->user;
1246cd6a6acSopenharmony_ci	dst->role = src->role;
1256cd6a6acSopenharmony_ci	dst->type = src->type;
1266cd6a6acSopenharmony_ci	return mls_context_cpy(dst, src);
1276cd6a6acSopenharmony_ci}
1286cd6a6acSopenharmony_ci
1296cd6a6acSopenharmony_cistatic inline void context_destroy(context_struct_t * c)
1306cd6a6acSopenharmony_ci{
1316cd6a6acSopenharmony_ci	if (c == NULL)
1326cd6a6acSopenharmony_ci		return;
1336cd6a6acSopenharmony_ci
1346cd6a6acSopenharmony_ci	c->user = c->role = c->type = 0;
1356cd6a6acSopenharmony_ci	mls_context_destroy(c);
1366cd6a6acSopenharmony_ci}
1376cd6a6acSopenharmony_ci
1386cd6a6acSopenharmony_cistatic inline int context_cmp(const context_struct_t * c1, const context_struct_t * c2)
1396cd6a6acSopenharmony_ci{
1406cd6a6acSopenharmony_ci	return ((c1->user == c2->user) &&
1416cd6a6acSopenharmony_ci		(c1->role == c2->role) &&
1426cd6a6acSopenharmony_ci		(c1->type == c2->type) && mls_context_cmp(c1, c2));
1436cd6a6acSopenharmony_ci}
1446cd6a6acSopenharmony_ci
1456cd6a6acSopenharmony_ci#ifdef __cplusplus
1466cd6a6acSopenharmony_ci}
1476cd6a6acSopenharmony_ci#endif
1486cd6a6acSopenharmony_ci
1496cd6a6acSopenharmony_ci#endif
150