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