Merge branch 'linus' into test
[linux-2.6] / security / selinux / ss / context.h
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         struct mls_range range;
31         char *str;      /* string representation if context cannot be mapped. */
32         u32 len;        /* length of string in bytes */
33 };
34
35 static inline void mls_context_init(struct context *c)
36 {
37         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         if (!selinux_mls_enabled)
45                 return 0;
46
47         dst->range.level[0].sens = src->range.level[0].sens;
48         rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
49         if (rc)
50                 goto out;
51
52         dst->range.level[1].sens = src->range.level[1].sens;
53         rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
54         if (rc)
55                 ebitmap_destroy(&dst->range.level[0].cat);
56 out:
57         return rc;
58 }
59
60 /*
61  * Sets both levels in the MLS range of 'dst' to the low level of 'src'.
62  */
63 static inline int mls_context_cpy_low(struct context *dst, struct context *src)
64 {
65         int rc;
66
67         if (!selinux_mls_enabled)
68                 return 0;
69
70         dst->range.level[0].sens = src->range.level[0].sens;
71         rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
72         if (rc)
73                 goto out;
74
75         dst->range.level[1].sens = src->range.level[0].sens;
76         rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[0].cat);
77         if (rc)
78                 ebitmap_destroy(&dst->range.level[0].cat);
79 out:
80         return rc;
81 }
82
83 static inline int mls_context_cmp(struct context *c1, struct context *c2)
84 {
85         if (!selinux_mls_enabled)
86                 return 1;
87
88         return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
89                 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
90                 (c1->range.level[1].sens == c2->range.level[1].sens) &&
91                 ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat));
92 }
93
94 static inline void mls_context_destroy(struct context *c)
95 {
96         if (!selinux_mls_enabled)
97                 return;
98
99         ebitmap_destroy(&c->range.level[0].cat);
100         ebitmap_destroy(&c->range.level[1].cat);
101         mls_context_init(c);
102 }
103
104 static inline void context_init(struct context *c)
105 {
106         memset(c, 0, sizeof(*c));
107 }
108
109 static inline int context_cpy(struct context *dst, struct context *src)
110 {
111         int rc;
112
113         dst->user = src->user;
114         dst->role = src->role;
115         dst->type = src->type;
116         if (src->str) {
117                 dst->str = kstrdup(src->str, GFP_ATOMIC);
118                 if (!dst->str)
119                         return -ENOMEM;
120                 dst->len = src->len;
121         } else {
122                 dst->str = NULL;
123                 dst->len = 0;
124         }
125         rc = mls_context_cpy(dst, src);
126         if (rc) {
127                 kfree(dst->str);
128                 return rc;
129         }
130         return 0;
131 }
132
133 static inline void context_destroy(struct context *c)
134 {
135         c->user = c->role = c->type = 0;
136         kfree(c->str);
137         c->str = NULL;
138         c->len = 0;
139         mls_context_destroy(c);
140 }
141
142 static inline int context_cmp(struct context *c1, struct context *c2)
143 {
144         if (c1->len && c2->len)
145                 return (c1->len == c2->len && !strcmp(c1->str, c2->str));
146         if (c1->len || c2->len)
147                 return 0;
148         return ((c1->user == c2->user) &&
149                 (c1->role == c2->role) &&
150                 (c1->type == c2->type) &&
151                 mls_context_cmp(c1, c2));
152 }
153
154 #endif  /* _SS_CONTEXT_H_ */
155