source: libabac/abac_role.c @ 314869f

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 314869f 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
RevLine 
[7f25a67f]1#include <assert.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5
[0bf0e67]6#include "abac.h"
[3c251d0]7#include "abac_util.h"
[7f25a67f]8
9// typedef'd in role.h
[1743825]10struct _abac_role_t {
[7f25a67f]11    char *principal;
12    char *linked_role;
[dcc1a8e]13    char *abac_role_name;
[7e05a2f]14
15    char *string;
[d4cbf71]16    char *linked;
[7f25a67f]17};
18
19/**
20 * Create a new principal and initialize it.
21 */
[dcc1a8e]22abac_role_t *abac_role_principal_new(char *principal) {
[7f25a67f]23    assert(principal != NULL);
24
[1743825]25    abac_role_t *role;
[7f25a67f]26
27    if (strlen(principal) == 0)
28        return NULL;
29
[3c251d0]30    role = abac_xmalloc(sizeof(abac_role_t));
[7f25a67f]31
[3c251d0]32    role->principal = abac_xstrdup(principal);
[dcc1a8e]33    role->abac_role_name = NULL;
[7f25a67f]34    role->linked_role = NULL;
35
[3c251d0]36    role->string = abac_xstrdup(principal);
[d4cbf71]37    role->linked = NULL;
[7e05a2f]38
[7f25a67f]39    return role;
40}
41
42/**
43 * Create a new role and initialize it.
44 */
[dcc1a8e]45abac_role_t *abac_role_role_new(char *principal, char *abac_role_name) {
[7f25a67f]46    assert(principal != NULL);
[dcc1a8e]47    assert(abac_role_name != NULL);
[7f25a67f]48
[1743825]49    abac_role_t *role;
[7f25a67f]50
[dcc1a8e]51    if (strlen(principal) == 0 || strlen(abac_role_name) == 0)
[7f25a67f]52        return NULL;
53
[3c251d0]54    role = abac_xmalloc(sizeof(abac_role_t));
[7f25a67f]55
[3c251d0]56    role->principal = abac_xstrdup(principal);
57    role->abac_role_name = abac_xstrdup(abac_role_name);
[7f25a67f]58    role->linked_role = NULL;
59
[7e05a2f]60    int prin_len = strlen(principal);
[dcc1a8e]61    int abac_role_len = strlen(abac_role_name);
[7e05a2f]62
[3c251d0]63    role->string = abac_xmalloc(prin_len + 1 + abac_role_len + 1);
[7e05a2f]64    memcpy(role->string, principal, prin_len);
65    role->string[prin_len] = '.';
[dcc1a8e]66    memcpy(role->string + prin_len + 1, abac_role_name, abac_role_len);
67    role->string[prin_len + 1 + abac_role_len] = 0;
[7e05a2f]68
[d4cbf71]69    role->linked = NULL;
70
[7f25a67f]71    return role;
72}
73
74/**
75 * Created a new linking role and initialize it.
76 */
[dcc1a8e]77abac_role_t *abac_role_linking_new(char *principal, char *linked, char *abac_role_name) {
[7f25a67f]78    assert(principal != NULL);
79    assert(linked != NULL);
[dcc1a8e]80    assert(abac_role_name != NULL);
[7f25a67f]81
[1743825]82    abac_role_t *role;
[7f25a67f]83
[dcc1a8e]84    if (strlen(principal) == 0 || strlen(linked) == 0 || strlen(abac_role_name) == 0)
[7f25a67f]85        return NULL;
86
[3c251d0]87    role = abac_xmalloc(sizeof(abac_role_t));
[7f25a67f]88
[3c251d0]89    role->principal = abac_xstrdup(principal);
90    role->linked_role = abac_xstrdup(linked);
91    role->abac_role_name = abac_xstrdup(abac_role_name);
[7f25a67f]92
[7e05a2f]93    int prin_len = strlen(principal);
94    int link_len = strlen(linked);
[dcc1a8e]95    int abac_role_len = strlen(abac_role_name);
[7e05a2f]96
[3c251d0]97    role->string = abac_xmalloc(prin_len + 1 + link_len + 1 + abac_role_len + 1);
[7e05a2f]98
99    memcpy(role->string, principal, prin_len);
100    role->string[prin_len] = '.';
101    memcpy(role->string + prin_len + 1, linked, link_len);
[d4cbf71]102    role->string[prin_len + 1 + link_len] = 0;
103
104    // hack: linked role is first two parts of full string
[3c251d0]105    role->linked = abac_xstrdup(role->string);
[d4cbf71]106
[7e05a2f]107    role->string[prin_len + 1 + link_len] = '.';
[dcc1a8e]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;
[7e05a2f]110
[7f25a67f]111    return role;
112}
113
[c66e07c]114/**
115 * Free the memory used by a role.
116 */
[dcc1a8e]117void abac_role_free(abac_role_t *role) {
[c66e07c]118    if (role == NULL)
119        return;
120
121    free(role->principal);
122    free(role->linked_role);
[dcc1a8e]123    free(role->abac_role_name);
[c66e07c]124
[7e05a2f]125    free(role->string);
[be963dc]126    free(role->linked);
[7e05a2f]127
[c66e07c]128    free(role);
129}
130
[7f25a67f]131/**
132 * Create a role from a string. Handles principals, roles, and linking roles.
133 */
[dcc1a8e]134abac_role_t *abac_role_from_string(char *string) {
[7f25a67f]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)
[dcc1a8e]146        return abac_role_principal_new(string);
[7f25a67f]147
[1743825]148    abac_role_t *ret = NULL;
[7f25a67f]149
150    // make a copy so we can mess with it
[3c251d0]151    string = abac_xstrdup(string);
[7f25a67f]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
[dcc1a8e]162        char *abac_role_name = dot + 1;
[7f25a67f]163
164        // create the role (if possible)
[dcc1a8e]165        ret = abac_role_role_new(string, abac_role_name);
[7f25a67f]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
[dcc1a8e]182        char *abac_role_name = dot + 1;
[7f25a67f]183
[dcc1a8e]184        ret = abac_role_linking_new(principal, linked, abac_role_name);
[7f25a67f]185    }
186
187    // more than two dots: return NULL
188
189    free(string);
190
191    return ret;
192}
193
[ea401bc]194/**
195 * Duplicate a role.
196 */
[dcc1a8e]197abac_role_t *abac_role_dup(abac_role_t *role) {
[3c251d0]198    abac_role_t *ret = abac_xmalloc(sizeof(abac_role_t));
[ea401bc]199
[3c251d0]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);
[ea401bc]203
[3c251d0]204    ret->string = abac_xstrdup(role->string);
205    ret->linked = abac_xstrdup(role->linked);
[ea401bc]206
207    return ret;
208}
209
[7f25a67f]210/**
211 * True if a role is a principal.
212 */
[dcc1a8e]213int abac_role_is_principal(abac_role_t *role) {
[7f25a67f]214    assert(role != NULL);
[dcc1a8e]215    return role->abac_role_name == NULL && role->linked_role == NULL;
[7f25a67f]216}
217
218/**
219 * True if a role is a role.
220 */
[dcc1a8e]221int abac_role_is_role(abac_role_t *role) {
[7f25a67f]222    assert(role != NULL);
[dcc1a8e]223    return role->abac_role_name != NULL && role->linked_role == NULL; 
[7f25a67f]224}
225
226/**
227 * True if a role is a linked role.
228 */
[dcc1a8e]229int abac_role_is_linking(abac_role_t *role) {
[7f25a67f]230    assert(role != NULL);
231    return role->linked_role != NULL;
232}
233
[7e05a2f]234/**
235 * Returns the string representation of the role.
236 */
[dcc1a8e]237char *abac_role_string(abac_role_t *role) {
[7e05a2f]238    assert(role != NULL);
239    return role->string;
[7f25a67f]240}
[d4cbf71]241
[ebde9dd]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 */
[dcc1a8e]246char *abac_role_role_name(abac_role_t *role) {
[ebde9dd]247    assert(role != NULL);
[dcc1a8e]248    return role->abac_role_name;
[ebde9dd]249}
250
[d4cbf71]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 */
[dcc1a8e]255char *abac_role_linked_role(abac_role_t *role) {
[d4cbf71]256    assert(role != NULL);
257    return role->linked;
258}
[c03fe9b]259
260/**
261 * Returns the principal part of a role. The stuff before the first dot.
262 */
[dcc1a8e]263char *abac_role_principal(abac_role_t *role) {
[c03fe9b]264    assert(role != NULL);
265    return role->principal;
266}
[85f33fd]267
268/**
269 * Build an attribute key from head and tail roles. Static.
270 */
271#define ROLE_SEPARATOR " <- "
[dcc1a8e]272char *abac_role_attr_key(abac_role_t *head_role, abac_role_t *tail_role) {
273    char *head = abac_role_string(head_role);
[85f33fd]274    int head_len = strlen(head);
275
[dcc1a8e]276    char *tail = abac_role_string(tail_role);
[85f33fd]277    int tail_len = strlen(tail);
278
279    int sep_len = sizeof(ROLE_SEPARATOR) - 1;
280
281    // "head <- tail"
[3c251d0]282    char *ret = abac_xmalloc(head_len + tail_len + sep_len + 1);
[85f33fd]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.