source: libabac/abac_role.c @ fbb591e

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

reference count roles and credentials

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