struct semanage_fcontext;
struct semanage_fcontext_key;
typedef struct semanage_fcontext record_t;
typedef struct semanage_fcontext_key record_key_t;
#define DBASE_RECORD_DEFINED
#include <stdlib.h>
#include <string.h>
#include "fcontext_internal.h"
#include "context_internal.h"
#include "debug.h"
struct semanage_fcontext {
/* Matching expression */
char *expr;
/* Type of object */
int type;
/* Context */
semanage_context_t *con;
};
struct semanage_fcontext_key {
/* Matching expression */
char *expr;
/* Type of object */
int type;
};
/* Key */
int semanage_fcontext_key_create(semanage_handle_t * handle,
const char *expr,
int type, semanage_fcontext_key_t ** key_ptr)
{
semanage_fcontext_key_t *tmp_key =
(semanage_fcontext_key_t *) malloc(sizeof(semanage_fcontext_key_t));
if (!tmp_key) {
ERR(handle, "out of memory, could not "
"create file context key");
return STATUS_ERR;
}
tmp_key->expr = strdup(expr);
if (!tmp_key->expr) {
ERR(handle, "out of memory, could not create file context key.");
free(tmp_key);
return STATUS_ERR;
}
tmp_key->type = type;
*key_ptr = tmp_key;
return STATUS_SUCCESS;
}
hidden_def(semanage_fcontext_key_create)
int semanage_fcontext_key_extract(semanage_handle_t * handle,
const semanage_fcontext_t * fcontext,
semanage_fcontext_key_t ** key_ptr)
{
if (semanage_fcontext_key_create(handle, fcontext->expr,
fcontext->type, key_ptr) < 0) {
ERR(handle, "could not extract key from "
"file context %s (%s)", fcontext->expr,
semanage_fcontext_get_type_str(fcontext->type));
return STATUS_ERR;
}
return STATUS_SUCCESS;
}
hidden_def(semanage_fcontext_key_extract)
void semanage_fcontext_key_free(semanage_fcontext_key_t * key)
{
free(key->expr);
free(key);
}
hidden_def(semanage_fcontext_key_free)
int semanage_fcontext_compare(const semanage_fcontext_t * fcontext,
const semanage_fcontext_key_t * key)
{
int rv = strcmp(fcontext->expr, key->expr);
if (rv != 0)
return rv;
else {
if (fcontext->type < key->type)
return -1;
else if (key->type < fcontext->type)
return 1;
else
return 0;
}
}
hidden_def(semanage_fcontext_compare)
int semanage_fcontext_compare2(const semanage_fcontext_t * fcontext,
const semanage_fcontext_t * fcontext2)
{
int rv = strcmp(fcontext->expr, fcontext2->expr);
if (rv != 0)
return rv;
else {
if (fcontext->type < fcontext2->type)
return -1;
else if (fcontext2->type < fcontext->type)
return 1;
else
return 0;
}
}
hidden_def(semanage_fcontext_compare2)
static int semanage_fcontext_compare2_qsort(const semanage_fcontext_t **
fcontext,
const semanage_fcontext_t **
fcontext2)
{
return semanage_fcontext_compare2(*fcontext, *fcontext2);
}
/* Create */
int semanage_fcontext_create(semanage_handle_t * handle,
semanage_fcontext_t ** fcontext)
{
semanage_fcontext_t *tmp_fcontext =
(semanage_fcontext_t *) malloc(sizeof(semanage_fcontext_t));
if (!tmp_fcontext) {
ERR(handle, "out of memory, could not create "
"file context record");
return STATUS_ERR;
}
tmp_fcontext->expr = NULL;
tmp_fcontext->type = SEMANAGE_FCONTEXT_ALL;
tmp_fcontext->con = NULL;
*fcontext = tmp_fcontext;
return STATUS_SUCCESS;
}
hidden_def(semanage_fcontext_create)
/* Regexp */
const char *semanage_fcontext_get_expr(const semanage_fcontext_t * fcontext)
{
return fcontext->expr;
}
hidden_def(semanage_fcontext_get_expr)
int semanage_fcontext_set_expr(semanage_handle_t * handle,
semanage_fcontext_t * fcontext, const char *expr)
{
char *tmp_expr = strdup(expr);
if (!tmp_expr) {
ERR(handle, "out of memory, " "could not set regexp string");
return STATUS_ERR;
}
free(fcontext->expr);
fcontext->expr = tmp_expr;
return STATUS_SUCCESS;
}
hidden_def(semanage_fcontext_set_expr)
/* Type */
int semanage_fcontext_get_type(const semanage_fcontext_t * fcontext)
{
return fcontext->type;
}
hidden_def(semanage_fcontext_get_type)
const char *semanage_fcontext_get_type_str(int type)
{
switch (type) {
case SEMANAGE_FCONTEXT_ALL:
return "all files";
case SEMANAGE_FCONTEXT_REG:
return "regular file";
case SEMANAGE_FCONTEXT_DIR:
return "directory";
case SEMANAGE_FCONTEXT_CHAR:
return "character device";
case SEMANAGE_FCONTEXT_BLOCK:
return "block device";
case SEMANAGE_FCONTEXT_SOCK:
return "socket";
case SEMANAGE_FCONTEXT_LINK:
return "symbolic link";
case SEMANAGE_FCONTEXT_PIPE:
return "named pipe";
default:
return "????";
}
}
hidden_def(semanage_fcontext_get_type_str)
void semanage_fcontext_set_type(semanage_fcontext_t * fcontext, int type)
{
fcontext->type = type;
}
hidden_def(semanage_fcontext_set_type)
/* Context */
semanage_context_t *semanage_fcontext_get_con(const semanage_fcontext_t *
fcontext)
{
return fcontext->con;
}
hidden_def(semanage_fcontext_get_con)
int semanage_fcontext_set_con(semanage_handle_t * handle,
semanage_fcontext_t * fcontext,
semanage_context_t * con)
{
semanage_context_t *newcon;
if (semanage_context_clone(handle, con, &newcon) < 0) {
ERR(handle, "out of memory, could not set file context");
return STATUS_ERR;
}
semanage_context_free(fcontext->con);
fcontext->con = newcon;
return STATUS_SUCCESS;
}
hidden_def(semanage_fcontext_set_con)
/* Deep copy clone */
int semanage_fcontext_clone(semanage_handle_t * handle,
const semanage_fcontext_t * fcontext,
semanage_fcontext_t ** fcontext_ptr)
{
semanage_fcontext_t *new_fcontext = NULL;
if (semanage_fcontext_create(handle, &new_fcontext) < 0)
goto err;
if (semanage_fcontext_set_expr(handle, new_fcontext, fcontext->expr) <
0)
goto err;
new_fcontext->type = fcontext->type;
if (fcontext->con &&
(semanage_context_clone(handle, fcontext->con, &new_fcontext->con) <
0))
goto err;
*fcontext_ptr = new_fcontext;
return STATUS_SUCCESS;
err:
ERR(handle, "could not clone file context record");
semanage_fcontext_free(new_fcontext);
return STATUS_ERR;
}
hidden_def(semanage_fcontext_clone)
/* Destroy */
void semanage_fcontext_free(semanage_fcontext_t * fcontext)
{
if (!fcontext)
return;
free(fcontext->expr);
semanage_context_free(fcontext->con);
free(fcontext);
}
hidden_def(semanage_fcontext_free)
/* Record base functions */
record_table_t SEMANAGE_FCONTEXT_RTABLE = {
.create = semanage_fcontext_create,
.key_extract = semanage_fcontext_key_extract,
.key_free = semanage_fcontext_key_free,
.clone = semanage_fcontext_clone,
.compare = semanage_fcontext_compare,
.compare2 = semanage_fcontext_compare2,
.compare2_qsort = semanage_fcontext_compare2_qsort,
.free = semanage_fcontext_free,
};