From f63bc1d2a0b7a48849d92f8291db351e3c153971 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Mon, 22 Nov 2010 08:31:41 -0800 Subject: [PATCH] Implemented labels API. --- src/smack.h | 4 +- src/smack_labels.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++---- src/smack_rules.c | 3 +- 3 files changed, 134 insertions(+), 13 deletions(-) diff --git a/src/smack.h b/src/smack.h index f48ca86..40722e5 100644 --- a/src/smack.h +++ b/src/smack.h @@ -188,7 +188,7 @@ extern int smack_xattr_get_from_proc(int pid, char **smack); * * @return handle to the rule set. Returns NULL if allocation fails. */ -extern SmackLabelSet *smack_label_set_new(void); +extern SmackLabelSet smack_label_set_new(void); /*! * Read labels from a given file. @@ -204,7 +204,7 @@ extern SmackLabelSet smack_label_set_new_from_file(const char *path, * * @param handle handle to a rules */ -void smack_label_set_delete(SmackLabelSet *handle); +void smack_label_set_delete(SmackLabelSet handle); /*! * Add new label to a label set. diff --git a/src/smack_labels.c b/src/smack_labels.c index 0bd0cca..0e981e7 100644 --- a/src/smack_labels.c +++ b/src/smack_labels.c @@ -1,38 +1,158 @@ +#include #include +#include +#include +#include #include "smack.h" -SmackLabelSet *smack_label_set_new(void) +#define SMACK64_LEN 23 +struct smack_label { + char *long_label; + char *short_label; + UT_hash_handle long_hh; + UT_hash_handle short_hh; +}; + +struct _SmackLabelSet { + struct smack_label *labels; +}; + +static int add_label(struct smack_label **labels, + const char *long_label, + const char *short_label); + +SmackLabelSet smack_label_set_new(void) { - return NULL; + struct _SmackLabelSet *result = + calloc(1, sizeof(struct _SmackLabelSet)); + return result; } extern SmackLabelSet smack_label_set_new_from_file(const char *path, const char *subject) { - return NULL; -} + SmackLabelSet labels; + FILE *file; + char *buf = NULL; + const char *ll, *sl; + size_t size; + int ret = 0; + file = fopen(path, "r"); + if (file == NULL) + return NULL; -void smack_label_set_delete(SmackLabelSet *handle) -{ + labels = smack_label_set_new(); + if (labels == NULL) { + fclose(file); + return NULL; + } + + while (ret == 0 && getline(&buf, &size, file) != -1) { + ll = strtok(buf, " \t\n"); + sl = strtok(NULL, " \t\n"); + + if (ll == NULL || sl == NULL || strtok(NULL, " \t\n") != NULL) { + ret = -1; + } else { + ret = add_label(&labels->labels, ll, sl); + } + + free(buf); + buf = NULL; + } + + if (ret != 0 || ferror(file)) { + smack_label_set_delete(labels); + labels = NULL; + } + + free(buf); + fclose(file); + return labels; } +void smack_label_set_delete(SmackLabelSet handle) +{ + struct smack_label *l, *tmp; + + HASH_ITER(long_hh, handle->labels, l, tmp) { + HASH_DELETE(long_hh, handle->labels, l); + HASH_DELETE(short_hh, handle->labels, l); + free(l->long_label); + free(l->short_label); + free(l); + } +} int smack_label_set_add(SmackLabelSet handle, const char *long_label) { - return 0; -} + char sl[SMACK64_LEN + 1]; + int pos, len ,ret; + + if (long_label == NULL || strlen(long_label) == 0) + return -EPERM; + len = strlen(long_label); + pos = (len > SMACK64_LEN) ? len - SMACK64_LEN : 0; + + strcpy(sl, &long_label[pos]); + + ret = add_label(&handle->labels, long_label, sl); + + return ret == 0 ? 0 : -1; +} const char *smack_label_set_to_short_label(SmackLabelSet handle, const char *long_label) { - return NULL; + struct smack_label *l; + HASH_FIND(long_hh, handle->labels, long_label, strlen(long_label), l); + return l->short_label; } const char *smack_label_set_to_long_label(SmackLabelSet handle, const char *short_label) { - return NULL; + struct smack_label *l; + HASH_FIND(short_hh, handle->labels, short_label, strlen(short_label), l); + return l->long_label; +} + +static int add_label(struct smack_label **labels, + const char *long_label, + const char *short_label) +{ + struct smack_label *l; + + if (strlen(short_label) > SMACK64_LEN) + return -ERANGE; + + HASH_FIND(long_hh, *labels, long_label, strlen(long_label), l); + if (l != NULL) + return -EEXIST; + + HASH_FIND(short_hh, *labels, short_label, strlen(short_label), l); + if (l != NULL) + return -EEXIST; + + l = calloc(1, sizeof(struct smack_label)); + if (l == NULL) + return -ENOMEM; + + l->long_label = strdup(long_label); + l->short_label = strdup(short_label); + + if (l->long_label == NULL || l->short_label == NULL) { + free(l->long_label); + free(l->short_label); + free(l); + return -ENOMEM; + } + + HASH_ADD_KEYPTR(long_hh, *labels, l->long_label, strlen(l->long_label), l); + HASH_ADD_KEYPTR(short_hh, *labels, l->short_label, strlen(l->short_label), l); + + return 0; } diff --git a/src/smack_rules.c b/src/smack_rules.c index 16a73e6..786b46f 100644 --- a/src/smack_rules.c +++ b/src/smack_rules.c @@ -70,6 +70,7 @@ SmackRuleSet smack_rule_set_new(void) SmackRuleSet smack_rule_set_new_from_file(const char *path, const char *subject_filter) { + SmackRuleSet rules; FILE *file; char *buf = NULL; const char *subject, *object, *access; @@ -81,7 +82,7 @@ SmackRuleSet smack_rule_set_new_from_file(const char *path, if (file == NULL) return NULL; - SmackRuleSet rules = smack_rule_set_new(); + rules = smack_rule_set_new(); if (rules == NULL) { fclose(file); return NULL; -- 2.7.4