|
Chris PeBenito |
473ea7 |
#include "context_internal.h"
|
|
Chris PeBenito |
473ea7 |
#include <string.h>
|
|
Chris PeBenito |
473ea7 |
#include <stdio.h>
|
|
Chris PeBenito |
473ea7 |
#include <stdlib.h>
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
#define COMP_USER 0
|
|
Chris PeBenito |
473ea7 |
#define COMP_ROLE 1
|
|
Chris PeBenito |
473ea7 |
#define COMP_TYPE 2
|
|
Chris PeBenito |
473ea7 |
#define COMP_RANGE 3
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
typedef struct {
|
|
Chris PeBenito |
473ea7 |
char *current_str; /* This is made up-to-date only when needed */
|
|
Chris PeBenito |
473ea7 |
char *(component[4]);
|
|
Chris PeBenito |
473ea7 |
} context_private_t;
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/*
|
|
Chris PeBenito |
473ea7 |
* Allocate a new context, initialized from str. There must be 3 or
|
|
Chris PeBenito |
473ea7 |
* 4 colon-separated components and no whitespace in any component other
|
|
Chris PeBenito |
473ea7 |
* than the MLS component.
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
context_t
|
|
Chris PeBenito |
473ea7 |
context_new(const char *str)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
int i,count;
|
|
Chris PeBenito |
473ea7 |
context_private_t *n = (context_private_t*) malloc(sizeof(context_private_t));
|
|
Chris PeBenito |
473ea7 |
context_t result = (context_t) malloc(sizeof(context_s_t));
|
|
Chris PeBenito |
473ea7 |
const char *p,*tok;
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if (result)
|
|
Chris PeBenito |
473ea7 |
result->ptr = n;
|
|
Chris PeBenito |
473ea7 |
else
|
|
Chris PeBenito |
473ea7 |
free(n);
|
|
Chris PeBenito |
473ea7 |
if ( n == 0 || result == 0 ) { goto err; }
|
|
Chris PeBenito |
473ea7 |
n->current_str = n->component[0] = n->component[1] = n->component[2] =
|
|
Chris PeBenito |
473ea7 |
n->component[3] = 0;
|
|
Chris PeBenito |
473ea7 |
for ( i = count = 0, p = str; *p; p++ ) {
|
|
Chris PeBenito |
473ea7 |
switch ( *p ) {
|
|
Chris PeBenito |
473ea7 |
case ':': count++; break;
|
|
Chris PeBenito |
473ea7 |
case '\n': case '\t': case '\r': goto err; /* sanity check */
|
|
Chris PeBenito |
473ea7 |
case ' ': if (count < 3) goto err; /* sanity check */
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
/*
|
|
Chris PeBenito |
473ea7 |
* Could be anywhere from 2 - 5
|
|
Chris PeBenito |
473ea7 |
* e.g user:role:type to user:role:type:sens1:cata-sens2:catb
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
if ( count < 2 || count > 5 ) { /* might not have a range */
|
|
Chris PeBenito |
473ea7 |
goto err;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
n->component[3] = 0;
|
|
Chris PeBenito |
473ea7 |
for ( i = 0, tok = str; *tok; i++ ) {
|
|
Chris PeBenito |
473ea7 |
if (i<3)
|
|
Chris PeBenito |
473ea7 |
for ( p = tok; *p && *p != ':'; p++ ) { /* empty */ }
|
|
Chris PeBenito |
473ea7 |
else
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
/* MLS range is one component */
|
|
Chris PeBenito |
473ea7 |
for ( p = tok; *p; p++ ) { /* empty */ }
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
n->component[i] = (char*) malloc(p-tok+1);
|
|
Chris PeBenito |
473ea7 |
if (n->component[i] == 0)
|
|
Chris PeBenito |
473ea7 |
goto err;
|
|
Chris PeBenito |
473ea7 |
strncpy(n->component[i],tok,p-tok);
|
|
Chris PeBenito |
473ea7 |
n->component[i][p-tok] = '\0';
|
|
Chris PeBenito |
473ea7 |
tok = *p ? p+1 : p;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
return result;
|
|
Chris PeBenito |
473ea7 |
err:
|
|
Chris PeBenito |
473ea7 |
context_free(result);
|
|
Chris PeBenito |
473ea7 |
return 0;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
hidden_def(context_new)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
static void
|
|
Chris PeBenito |
473ea7 |
conditional_free(char** v)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
if ( *v ) {
|
|
Chris PeBenito |
473ea7 |
free(*v);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
*v = 0;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/*
|
|
Chris PeBenito |
473ea7 |
* free all storage used by a context. Safe to call with
|
|
Chris PeBenito |
473ea7 |
* null pointer.
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
void
|
|
Chris PeBenito |
473ea7 |
context_free(context_t context)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_private_t *n;
|
|
Chris PeBenito |
473ea7 |
int i;
|
|
Chris PeBenito |
473ea7 |
if ( context ) {
|
|
Chris PeBenito |
473ea7 |
n = context->ptr;
|
|
Chris PeBenito |
473ea7 |
if ( n ) {
|
|
Chris PeBenito |
473ea7 |
conditional_free(&n->current_str);
|
|
Chris PeBenito |
473ea7 |
for ( i = 0; i < 4; i++ ) {
|
|
Chris PeBenito |
473ea7 |
conditional_free(&n->component[i]);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
free(n);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
free(context);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
hidden_def(context_free)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/*
|
|
Chris PeBenito |
473ea7 |
* Return a pointer to the string value of the context.
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
char *
|
|
Chris PeBenito |
473ea7 |
context_str(context_t context)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_private_t *n = context->ptr;
|
|
Chris PeBenito |
473ea7 |
int i;
|
|
Chris PeBenito |
473ea7 |
size_t total = 0;
|
|
Chris PeBenito |
473ea7 |
conditional_free(&n->current_str);
|
|
Chris PeBenito |
473ea7 |
for ( i = 0; i < 4; i++ ) {
|
|
Chris PeBenito |
473ea7 |
if ( n->component[i] ) {
|
|
Chris PeBenito |
473ea7 |
total += strlen(n->component[i])+1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
n->current_str = malloc(total);
|
|
Chris PeBenito |
473ea7 |
if ( n->current_str != 0 ) {
|
|
Chris PeBenito |
473ea7 |
char *cp = n->current_str;
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
cp = stpcpy(cp, n->component[0]);
|
|
Chris PeBenito |
473ea7 |
for (i = 1; i < 4; i++) {
|
|
Chris PeBenito |
473ea7 |
if (n->component[i]) {
|
|
Chris PeBenito |
473ea7 |
*cp++ = ':';
|
|
Chris PeBenito |
473ea7 |
cp = stpcpy(cp, n->component[i]);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
return n->current_str;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
hidden_def(context_str)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* Returns nonzero iff failed */
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
static int set_comp(context_private_t* n,int index, const char *str)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
char *t = NULL;
|
|
Chris PeBenito |
473ea7 |
const char *p;
|
|
Chris PeBenito |
473ea7 |
if (str) {
|
|
Chris PeBenito |
473ea7 |
t = (char*) malloc(strlen(str)+1);
|
|
Chris PeBenito |
473ea7 |
if ( !t ) { return 1; }
|
|
Chris PeBenito |
473ea7 |
for ( p = str; *p; p++ ) {
|
|
Chris PeBenito |
473ea7 |
if ( *p == '\t' || *p == '\n' || *p == '\r' ||
|
|
Chris PeBenito |
473ea7 |
((*p == ':' || *p == ' ') && index != COMP_RANGE) ) {
|
|
Chris PeBenito |
473ea7 |
free(t);
|
|
Chris PeBenito |
473ea7 |
return 1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
strcpy(t,str);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
conditional_free(&n->component[index]);
|
|
Chris PeBenito |
473ea7 |
n->component[index] = t;
|
|
Chris PeBenito |
473ea7 |
return 0;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
#define def_get(name,tag) \
|
|
Chris PeBenito |
473ea7 |
const char * context_ ## name ## _get(context_t context) \
|
|
Chris PeBenito |
473ea7 |
{ \
|
|
Chris PeBenito |
473ea7 |
context_private_t *n = context->ptr; \
|
|
Chris PeBenito |
473ea7 |
return n->component[tag]; \
|
|
Chris PeBenito |
473ea7 |
} \
|
|
Chris PeBenito |
473ea7 |
hidden_def(context_ ## name ## _get)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
def_get(type,COMP_TYPE)
|
|
Chris PeBenito |
473ea7 |
def_get(user,COMP_USER)
|
|
Chris PeBenito |
473ea7 |
def_get(range,COMP_RANGE)
|
|
Chris PeBenito |
473ea7 |
def_get(role,COMP_ROLE)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
#define def_set(name,tag) \
|
|
Chris PeBenito |
473ea7 |
int context_ ## name ## _set(context_t context, const char* str) \
|
|
Chris PeBenito |
473ea7 |
{ \
|
|
Chris PeBenito |
473ea7 |
return set_comp(context->ptr,tag,str);\
|
|
Chris PeBenito |
473ea7 |
} \
|
|
Chris PeBenito |
473ea7 |
hidden_def(context_ ## name ## _set)
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
def_set(type,COMP_TYPE)
|
|
Chris PeBenito |
473ea7 |
def_set(role,COMP_ROLE)
|
|
Chris PeBenito |
473ea7 |
def_set(user,COMP_USER)
|
|
Chris PeBenito |
473ea7 |
def_set(range,COMP_RANGE)
|