source: libabac/abac_role.c @ 15200be

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 15200be was 15200be, checked in by Mike Ryan <mikeryan@…>, 14 years ago

move libabac into its own directory

  • Property mode set to 100644
File size: 6.9 KB
Line 
1#include <assert.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5
6#include "abac.h"
7#include "abac_util.h"
8
9// typedef'd in role.h
10struct _abac_role_t {
11    char *principal;
12    char *linked_role;
13    char *abac_role_name;
14
15    char *string;
16    char *linked;
17};
18
19/**
20 * Create a new principal and initialize it.
21 */
22abac_role_t *abac_role_principal_new(char *principal) {
23    assert(principal != NULL);
24
25    abac_role_t *role;
26
27    if (strlen(principal) == 0)
28        return NULL;
29
30    role = abac_xmalloc(sizeof(abac_role_t));
31
32    role->principal = abac_xstrdup(principal);
33    role->abac_role_name = NULL;
34    role->linked_role = NULL;
35
36    role->string = abac_xstrdup(principal);
37    role->linked = NULL;
38
39    return role;
40}
41
42/**
43 * Create a new role and initialize it.
44 */
45abac_role_t *abac_role_role_new(char *principal, char *abac_role_name) {
46    assert(principal != NULL);
47    assert(abac_role_name != NULL);
48
49    abac_role_t *role;
50
51    if (strlen(principal) == 0 || strlen(abac_role_name) == 0)
52        return NULL;
53
54    role = abac_xmalloc(sizeof(abac_role_t));
55
56    role->principal = abac_xstrdup(principal);
57    role->abac_role_name = abac_xstrdup(abac_role_name);
58    role->linked_role = NULL;
59
60    int prin_len = strlen(principal);
61    int abac_role_len = strlen(abac_role_name);
62
63    role->string = abac_xmalloc(prin_len + 1 + abac_role_len + 1);
64    memcpy(role->string, principal, prin_len);
65    role->string[prin_len] = '.';
66    memcpy(role->string + prin_len + 1, abac_role_name, abac_role_len);
67    role->string[prin_len + 1 + abac_role_len] = 0;
68
69    role->linked = NULL;
70
71    return role;
72}
73
74/**
75 * Created a new linking role and initialize it.
76 */
77abac_role_t *abac_role_linking_new(char *principal, char *linked, char *abac_role_name) {
78    assert(principal != NULL);
79    assert(linked != NULL);
80    assert(abac_role_name != NULL);
81
82    abac_role_t *role;
83
84    if (strlen(principal) == 0 || strlen(linked) == 0 || strlen(abac_role_name) == 0)
85        return NULL;
86
87    role = abac_xmalloc(sizeof(abac_role_t));
88
89    role->principal = abac_xstrdup(principal);
90    role->linked_role = abac_xstrdup(linked);
91    role->abac_role_name = abac_xstrdup(abac_role_name);
92
93    int prin_len = strlen(principal);
94    int link_len = strlen(linked);
95    int abac_role_len = strlen(abac_role_name);
96
97    role->string = abac_xmalloc(prin_len + 1 + link_len + 1 + abac_role_len + 1);
98
99    memcpy(role->string, principal, prin_len);
100    role->string[prin_len] = '.';
101    memcpy(role->string + prin_len + 1, linked, link_len);
102    role->string[prin_len + 1 + link_len] = 0;
103
104    // hack: linked role is first two parts of full string
105    role->linked = abac_xstrdup(role->string);
106
107    role->string[prin_len + 1 + link_len] = '.';
108    memcpy(role->string + prin_len + 1 + link_len + 1, abac_role_name, abac_role_len);
109    role->string[prin_len + 1 + link_len + 1 + abac_role_len] = 0;
110
111    return role;
112}
113
114/**
115 * Free the memory used by a role.
116 */
117void abac_role_free(abac_role_t *role) {
118    if (role == NULL)
119        return;
120
121    free(role->principal);
122    free(role->linked_role);
123    free(role->abac_role_name);
124
125    free(role->string);
126    free(role->linked);
127
128    free(role);
129}
130
131/**
132 * Create a role from a string. Handles principals, roles, and linking roles.
133 */
134abac_role_t *abac_role_from_string(char *string) {
135    int num_dots = 0;
136    char *dot = string;
137
138    // count the dots
139    while ((dot = strchr(dot, '.')) != NULL) {
140        ++num_dots;
141        ++dot;
142    }
143
144    // no dots: easy case, principal
145    if (num_dots == 0)
146        return abac_role_principal_new(string);
147
148    abac_role_t *ret = NULL;
149
150    // make a copy so we can mess with it
151    string = abac_xstrdup(string);
152
153    // a role has exactly 1 dot
154    if (num_dots == 1) {
155        char *principal = string;
156
157        // terminate the principal part
158        dot = strchr(principal, '.');
159        *dot = 0;
160
161        // role name comes after the dot
162        char *abac_role_name = dot + 1;
163
164        // create the role (if possible)
165        ret = abac_role_role_new(string, abac_role_name);
166    }
167
168    // a linked role has 2 dots
169    else if (num_dots == 2) {
170        char *principal = string;
171
172        // terminate the principal part
173        dot = strchr(principal, '.');
174        *dot = 0;
175
176        // linked name is next, terminate it
177        char *linked = dot + 1;
178        dot = strchr(linked, '.');
179        *dot = 0;
180
181        // role name is last, already terminated
182        char *abac_role_name = dot + 1;
183
184        ret = abac_role_linking_new(principal, linked, abac_role_name);
185    }
186
187    // more than two dots: return NULL
188
189    free(string);
190
191    return ret;
192}
193
194/**
195 * Duplicate a role.
196 */
197abac_role_t *abac_role_dup(abac_role_t *role) {
198    abac_role_t *ret = abac_xmalloc(sizeof(abac_role_t));
199
200    ret->principal = abac_xstrdup(role->principal);
201    ret->linked_role = abac_xstrdup(role->linked_role);
202    ret->abac_role_name = abac_xstrdup(role->abac_role_name);
203
204    ret->string = abac_xstrdup(role->string);
205    ret->linked = abac_xstrdup(role->linked);
206
207    return ret;
208}
209
210/**
211 * True if a role is a principal.
212 */
213int abac_role_is_principal(abac_role_t *role) {
214    assert(role != NULL);
215    return role->abac_role_name == NULL && role->linked_role == NULL;
216}
217
218/**
219 * True if a role is a role.
220 */
221int abac_role_is_role(abac_role_t *role) {
222    assert(role != NULL);
223    return role->abac_role_name != NULL && role->linked_role == NULL; 
224}
225
226/**
227 * True if a role is a linked role.
228 */
229int abac_role_is_linking(abac_role_t *role) {
230    assert(role != NULL);
231    return role->linked_role != NULL;
232}
233
234/**
235 * Returns the string representation of the role.
236 */
237char *abac_role_string(abac_role_t *role) {
238    assert(role != NULL);
239    return role->string;
240}
241
242/**
243 * Returns the name of a role. If the role is A.r1 then return r1. If the role
244 * is A.r1.r2 then return r2.
245 */
246char *abac_role_role_name(abac_role_t *role) {
247    assert(role != NULL);
248    return role->abac_role_name;
249}
250
251/**
252 * Returns the linked part of a linking role. For instance, if the role is
253 * A.r1.r2, this returns A.r1.
254 */
255char *abac_role_linked_role(abac_role_t *role) {
256    assert(role != NULL);
257    return role->linked;
258}
259
260/**
261 * Returns the principal part of a role. The stuff before the first dot.
262 */
263char *abac_role_principal(abac_role_t *role) {
264    assert(role != NULL);
265    return role->principal;
266}
267
268/**
269 * Build an attribute key from head and tail roles. Static.
270 */
271#define ROLE_SEPARATOR " <- "
272char *abac_role_attr_key(abac_role_t *head_role, abac_role_t *tail_role) {
273    char *head = abac_role_string(head_role);
274    int head_len = strlen(head);
275
276    char *tail = abac_role_string(tail_role);
277    int tail_len = strlen(tail);
278
279    int sep_len = sizeof(ROLE_SEPARATOR) - 1;
280
281    // "head <- tail"
282    char *ret = abac_xmalloc(head_len + tail_len + sep_len + 1);
283    memcpy(ret, head, head_len);
284    memcpy(ret + head_len, ROLE_SEPARATOR, sep_len);
285    memcpy(ret + head_len + sep_len, tail, tail_len);
286    ret[head_len + sep_len + tail_len] = 0;
287
288    return ret;
289}
Note: See TracBrowser for help on using the repository browser.