1f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "context_internal.h" 2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <string.h> 3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdio.h> 4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h> 5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h> 6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define COMP_USER 0 8f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define COMP_ROLE 1 9f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define COMP_TYPE 2 10f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define COMP_RANGE 3 11f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 12f074036424618c130dacb3464465a8b40bffef5Stephen Smalleytypedef struct { 13f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *current_str; /* This is made up-to-date only when needed */ 14f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *(component[4]); 15f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} context_private_t; 16f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 17f074036424618c130dacb3464465a8b40bffef5Stephen Smalley/* 18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * Allocate a new context, initialized from str. There must be 3 or 19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * 4 colon-separated components and no whitespace in any component other 20f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * than the MLS component. 21f074036424618c130dacb3464465a8b40bffef5Stephen Smalley */ 22f074036424618c130dacb3464465a8b40bffef5Stephen Smalleycontext_t context_new(const char *str) 23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 24f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int i, count; 25f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = 0; 26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_private_t *n = 27f074036424618c130dacb3464465a8b40bffef5Stephen Smalley (context_private_t *) malloc(sizeof(context_private_t)); 28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_t result = (context_t) malloc(sizeof(context_s_t)); 29f074036424618c130dacb3464465a8b40bffef5Stephen Smalley const char *p, *tok; 30f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 31f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (result) 32f074036424618c130dacb3464465a8b40bffef5Stephen Smalley result->ptr = n; 33f074036424618c130dacb3464465a8b40bffef5Stephen Smalley else 34f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(n); 35f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n == 0 || result == 0) { 36f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err; 37f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 38f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->current_str = n->component[0] = n->component[1] = n->component[2] = 39f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->component[3] = 0; 40f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = count = 0, p = str; *p; p++) { 41f074036424618c130dacb3464465a8b40bffef5Stephen Smalley switch (*p) { 42f074036424618c130dacb3464465a8b40bffef5Stephen Smalley case ':': 43f074036424618c130dacb3464465a8b40bffef5Stephen Smalley count++; 44f074036424618c130dacb3464465a8b40bffef5Stephen Smalley break; 45f074036424618c130dacb3464465a8b40bffef5Stephen Smalley case '\n': 46f074036424618c130dacb3464465a8b40bffef5Stephen Smalley case '\t': 47f074036424618c130dacb3464465a8b40bffef5Stephen Smalley case '\r': 48f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err; /* sanity check */ 49f074036424618c130dacb3464465a8b40bffef5Stephen Smalley case ' ': 50f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (count < 3) 51f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err; /* sanity check */ 52f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 53f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 54f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* 55f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * Could be anywhere from 2 - 5 56f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * e.g user:role:type to user:role:type:sens1:cata-sens2:catb 57f074036424618c130dacb3464465a8b40bffef5Stephen Smalley */ 58f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (count < 2 || count > 5) { /* might not have a range */ 59f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err; 60f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 61f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 62f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->component[3] = 0; 63f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = 0, tok = str; *tok; i++) { 64f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (i < 3) 65f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (p = tok; *p && *p != ':'; p++) { /* empty */ 66f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } else { 67f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* MLS range is one component */ 68f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (p = tok; *p; p++) { /* empty */ 69f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 70f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 71f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->component[i] = (char *)malloc(p - tok + 1); 72f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n->component[i] == 0) 73f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err; 74f074036424618c130dacb3464465a8b40bffef5Stephen Smalley strncpy(n->component[i], tok, p - tok); 75f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->component[i][p - tok] = '\0'; 76f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tok = *p ? p + 1 : p; 77f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 78f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return result; 79f074036424618c130dacb3464465a8b40bffef5Stephen Smalley err: 80f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (errno == 0) errno = EINVAL; 81f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_free(result); 82f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 0; 83f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 84f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 85f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(context_new) 86f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 87f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic void conditional_free(char **v) 88f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 89f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (*v) { 90f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(*v); 91f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 92f074036424618c130dacb3464465a8b40bffef5Stephen Smalley *v = 0; 93f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 94f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 95f074036424618c130dacb3464465a8b40bffef5Stephen Smalley/* 96f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * free all storage used by a context. Safe to call with 97f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * null pointer. 98f074036424618c130dacb3464465a8b40bffef5Stephen Smalley */ 99f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyvoid context_free(context_t context) 100f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 101f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_private_t *n; 102f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int i; 103f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (context) { 104f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n = context->ptr; 105f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n) { 106f074036424618c130dacb3464465a8b40bffef5Stephen Smalley conditional_free(&n->current_str); 107f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = 0; i < 4; i++) { 108f074036424618c130dacb3464465a8b40bffef5Stephen Smalley conditional_free(&n->component[i]); 109f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 110f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(n); 111f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 112f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(context); 113f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 114f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 115f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 116f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(context_free) 117f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 118f074036424618c130dacb3464465a8b40bffef5Stephen Smalley/* 119f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * Return a pointer to the string value of the context. 120f074036424618c130dacb3464465a8b40bffef5Stephen Smalley */ 121f074036424618c130dacb3464465a8b40bffef5Stephen Smalleychar *context_str(context_t context) 122f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 123f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_private_t *n = context->ptr; 124f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int i; 125f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t total = 0; 126f074036424618c130dacb3464465a8b40bffef5Stephen Smalley conditional_free(&n->current_str); 127f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = 0; i < 4; i++) { 128f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n->component[i]) { 129f074036424618c130dacb3464465a8b40bffef5Stephen Smalley total += strlen(n->component[i]) + 1; 130f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 131f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 132f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->current_str = malloc(total); 133f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n->current_str != 0) { 134f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *cp = n->current_str; 135f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 136f074036424618c130dacb3464465a8b40bffef5Stephen Smalley strcpy(cp, n->component[0]); 137f074036424618c130dacb3464465a8b40bffef5Stephen Smalley cp += strlen(cp); 138f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = 1; i < 4; i++) { 139f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (n->component[i]) { 140f074036424618c130dacb3464465a8b40bffef5Stephen Smalley *cp++ = ':'; 141f074036424618c130dacb3464465a8b40bffef5Stephen Smalley strcpy(cp, n->component[i]); 142f074036424618c130dacb3464465a8b40bffef5Stephen Smalley cp += strlen(cp); 143f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 144f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 145f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 146f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return n->current_str; 147f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 148f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 149f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(context_str) 150f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 151f074036424618c130dacb3464465a8b40bffef5Stephen Smalley/* Returns nonzero iff failed */ 152f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic int set_comp(context_private_t * n, int idx, const char *str) 153f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 154f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *t = NULL; 155f074036424618c130dacb3464465a8b40bffef5Stephen Smalley const char *p; 156f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (str) { 157f074036424618c130dacb3464465a8b40bffef5Stephen Smalley t = (char *)malloc(strlen(str) + 1); 158f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!t) { 159f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 1; 160f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 161f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (p = str; *p; p++) { 162f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (*p == '\t' || *p == '\n' || *p == '\r' || 163f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ((*p == ':' || *p == ' ') && idx != COMP_RANGE)) { 164f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(t); 165f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = EINVAL; 166f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 1; 167f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 168f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 169f074036424618c130dacb3464465a8b40bffef5Stephen Smalley strcpy(t, str); 170f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 171f074036424618c130dacb3464465a8b40bffef5Stephen Smalley conditional_free(&n->component[idx]); 172f074036424618c130dacb3464465a8b40bffef5Stephen Smalley n->component[idx] = t; 173f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 0; 174f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 175f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 176f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define def_get(name,tag) \ 177f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyconst char * context_ ## name ## _get(context_t context) \ 178f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ \ 179f074036424618c130dacb3464465a8b40bffef5Stephen Smalley context_private_t *n = context->ptr; \ 180f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return n->component[tag]; \ 181f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} \ 182f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(context_ ## name ## _get) 183f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 184f074036424618c130dacb3464465a8b40bffef5Stephen Smalleydef_get(type, COMP_TYPE) 185f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_get(user, COMP_USER) 186f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_get(range, COMP_RANGE) 187f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_get(role, COMP_ROLE) 188f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define def_set(name,tag) \ 189f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyint context_ ## name ## _set(context_t context, const char* str) \ 190f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ \ 191f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return set_comp(context->ptr,tag,str);\ 192f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} \ 193f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyhidden_def(context_ ## name ## _set) 194f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_set(type, COMP_TYPE) 195f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_set(role, COMP_ROLE) 196f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_set(user, COMP_USER) 197f074036424618c130dacb3464465a8b40bffef5Stephen Smalley def_set(range, COMP_RANGE) 198