1/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */
2
3/* FLASK */
4
5/*
6 * A security context is a set of security attributes
7 * associated with each subject and object controlled
8 * by the security policy.  Security contexts are
9 * externally represented as variable-length strings
10 * that can be interpreted by a user or application
11 * with an understanding of the security policy.
12 * Internally, the security server uses a simple
13 * structure.  This structure is private to the
14 * security server and can be changed without affecting
15 * clients of the security server.
16 */
17
18#ifndef _SEPOL_POLICYDB_CONTEXT_H_
19#define _SEPOL_POLICYDB_CONTEXT_H_
20
21#include <stddef.h>
22#include <sepol/policydb/ebitmap.h>
23#include <sepol/policydb/mls_types.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/*
30 * A security context consists of an authenticated user
31 * identity, a role, a type and a MLS range.
32 */
33typedef struct context_struct {
34	uint32_t user;
35	uint32_t role;
36	uint32_t type;
37	mls_range_t range;
38} context_struct_t;
39
40static inline void mls_context_init(context_struct_t * c)
41{
42	mls_range_init(&c->range);
43}
44
45static inline int mls_context_cpy(context_struct_t * dst,
46				  context_struct_t * src)
47{
48
49	if (mls_range_cpy(&dst->range, &src->range) < 0)
50		return -1;
51
52	return 0;
53}
54
55/*
56 * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
57 */
58static inline int mls_context_cpy_low(context_struct_t *dst, context_struct_t *src)
59{
60	int rc;
61
62	dst->range.level[0].sens = src->range.level[0].sens;
63	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
64	if (rc)
65		goto out;
66
67	dst->range.level[1].sens = src->range.level[0].sens;
68	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
69	if (rc)
70		ebitmap_destroy(&dst->range.level[0].cat);
71out:
72	return rc;
73}
74
75/*
76 * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
77 */
78static inline int mls_context_cpy_high(context_struct_t *dst, context_struct_t *src)
79{
80	int rc;
81
82	dst->range.level[0].sens = src->range.level[1].sens;
83	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
84	if (rc)
85		goto out;
86
87	dst->range.level[1].sens = src->range.level[1].sens;
88	rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
89	if (rc)
90		ebitmap_destroy(&dst->range.level[0].cat);
91out:
92	return rc;
93}
94
95static inline int mls_context_cmp(context_struct_t * c1, context_struct_t * c2)
96{
97	return (mls_level_eq(&c1->range.level[0], &c2->range.level[0]) &&
98		mls_level_eq(&c1->range.level[1], &c2->range.level[1]));
99
100}
101
102static inline void mls_context_destroy(context_struct_t * c)
103{
104	if (c == NULL)
105		return;
106
107	mls_range_destroy(&c->range);
108	mls_context_init(c);
109}
110
111static inline void context_init(context_struct_t * c)
112{
113	memset(c, 0, sizeof(*c));
114}
115
116static inline int context_cpy(context_struct_t * dst, context_struct_t * src)
117{
118	dst->user = src->user;
119	dst->role = src->role;
120	dst->type = src->type;
121	return mls_context_cpy(dst, src);
122}
123
124static inline void context_destroy(context_struct_t * c)
125{
126	if (c == NULL)
127		return;
128
129	c->user = c->role = c->type = 0;
130	mls_context_destroy(c);
131}
132
133static inline int context_cmp(context_struct_t * c1, context_struct_t * c2)
134{
135	return ((c1->user == c2->user) &&
136		(c1->role == c2->role) &&
137		(c1->type == c2->type) && mls_context_cmp(c1, c2));
138}
139
140#ifdef __cplusplus
141}
142#endif
143
144#endif
145