147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "context_internal.h" 247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <string.h> 347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdio.h> 447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdlib.h> 547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <errno.h> 647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define COMP_USER 0 847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define COMP_ROLE 1 947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define COMP_TYPE 2 1047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define COMP_RANGE 3 1147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnertypedef struct { 1347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *current_str; /* This is made up-to-date only when needed */ 1447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *(component[4]); 1547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} context_private_t; 1647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner/* 1847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * Allocate a new context, initialized from str. There must be 3 or 1947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * 4 colon-separated components and no whitespace in any component other 2047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * than the MLS component. 2147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner */ 2247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnercontext_t context_new(const char *str) 2347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 2447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int i, count; 2547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = 0; 2647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_private_t *n = 2747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner (context_private_t *) malloc(sizeof(context_private_t)); 2847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_t result = (context_t) malloc(sizeof(context_s_t)); 2947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner const char *p, *tok; 3047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (result) 3247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner result->ptr = n; 3347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner else 3447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(n); 3547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n == 0 || result == 0) { 3647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err; 3747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 3847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->current_str = n->component[0] = n->component[1] = n->component[2] = 3947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->component[3] = 0; 4047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = count = 0, p = str; *p; p++) { 4147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner switch (*p) { 4247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner case ':': 4347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner count++; 4447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner break; 4547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner case '\n': 4647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner case '\t': 4747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner case '\r': 4847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err; /* sanity check */ 4947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner case ' ': 5047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (count < 3) 5147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err; /* sanity check */ 5247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 5347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 5447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* 5547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * Could be anywhere from 2 - 5 5647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * e.g user:role:type to user:role:type:sens1:cata-sens2:catb 5747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner */ 5847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (count < 2 || count > 5) { /* might not have a range */ 5947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err; 6047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 6147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 6247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->component[3] = 0; 6347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = 0, tok = str; *tok; i++) { 6447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (i < 3) 6547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (p = tok; *p && *p != ':'; p++) { /* empty */ 6647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } else { 6747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* MLS range is one component */ 6847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (p = tok; *p; p++) { /* empty */ 6947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 7047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 7147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->component[i] = (char *)malloc(p - tok + 1); 7247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n->component[i] == 0) 7347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err; 7447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strncpy(n->component[i], tok, p - tok); 7547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->component[i][p - tok] = '\0'; 7647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tok = *p ? p + 1 : p; 7747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 7847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return result; 7947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner err: 8047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (errno == 0) errno = EINVAL; 8147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_free(result); 8247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 0; 8347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 8447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerhidden_def(context_new) 8647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic void conditional_free(char **v) 8847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 8947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (*v) { 9047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(*v); 9147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 9247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner *v = 0; 9347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 9447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner/* 9647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * free all storage used by a context. Safe to call with 9747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * null pointer. 9847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner */ 9947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnervoid context_free(context_t context) 10047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 10147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_private_t *n; 10247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int i; 10347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (context) { 10447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n = context->ptr; 10547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n) { 10647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner conditional_free(&n->current_str); 10747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = 0; i < 4; i++) { 10847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner conditional_free(&n->component[i]); 10947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 11047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(n); 11147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 11247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(context); 11347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 11447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 11547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerhidden_def(context_free) 11747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner/* 11947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * Return a pointer to the string value of the context. 12047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner */ 12147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerchar *context_str(context_t context) 12247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 12347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_private_t *n = context->ptr; 12447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int i; 12547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t total = 0; 12647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner conditional_free(&n->current_str); 12747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = 0; i < 4; i++) { 12847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n->component[i]) { 12947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner total += strlen(n->component[i]) + 1; 13047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 13147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 13247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->current_str = malloc(total); 13347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n->current_str != 0) { 13447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *cp = n->current_str; 13547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 13647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strcpy(cp, n->component[0]); 13747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner cp += strlen(cp); 13847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = 1; i < 4; i++) { 13947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (n->component[i]) { 14047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner *cp++ = ':'; 14147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strcpy(cp, n->component[i]); 14247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner cp += strlen(cp); 14347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 14447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 14547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 14647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return n->current_str; 14747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 14847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 14947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerhidden_def(context_str) 15047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 15147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner/* Returns nonzero iff failed */ 15247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic int set_comp(context_private_t * n, int idx, const char *str) 15347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 15447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *t = NULL; 15547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner const char *p; 15647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (str) { 15747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner t = (char *)malloc(strlen(str) + 1); 15847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!t) { 15947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 1; 16047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 16147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (p = str; *p; p++) { 16247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (*p == '\t' || *p == '\n' || *p == '\r' || 16347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ((*p == ':' || *p == ' ') && idx != COMP_RANGE)) { 16447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(t); 16547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = EINVAL; 16647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 1; 16747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 16847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 16947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strcpy(t, str); 17047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 17147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner conditional_free(&n->component[idx]); 17247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner n->component[idx] = t; 17347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 0; 17447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 17547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 17647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define def_get(name,tag) \ 17747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerconst char * context_ ## name ## _get(context_t context) \ 17847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ \ 17947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner context_private_t *n = context->ptr; \ 18047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return n->component[tag]; \ 18147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} \ 18247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerhidden_def(context_ ## name ## _get) 18347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 18447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerdef_get(type, COMP_TYPE) 18547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_get(user, COMP_USER) 18647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_get(range, COMP_RANGE) 18747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_get(role, COMP_ROLE) 18847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define def_set(name,tag) \ 18947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerint context_ ## name ## _set(context_t context, const char* str) \ 19047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ \ 19147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return set_comp(context->ptr,tag,str);\ 19247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} \ 19347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerhidden_def(context_ ## name ## _set) 19447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_set(type, COMP_TYPE) 19547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_set(role, COMP_ROLE) 19647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_set(user, COMP_USER) 19747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner def_set(range, COMP_RANGE) 198