mirror of
https://github.com/SELinuxProject/selinux
synced 2025-02-19 19:17:10 +00:00
This patch moves the final files from inside /var/lib/selinux/<store>/[active|previous|tmp] to /var/lib/selinux/tmp/<store>. The move is done to facilitate using source control management on the /var/lib/selinux/<store> directory. If these files remain in /var/lib/selinux/<store> they will pose a size problem if an SCM like git is used as we'd be storing lots of binary diffs. We are suggesting making this change now, rather than later when source policy, SCM, and CIL[1] support are available, to ease the migration burden. These are the files that have been moved: /var/lib/selinux/<store>/active/... /var/lib/selinux/tmp/<store>/... file_contexts contexts/files/file_contexts file_contexts.homedirs contexts/files/file_contexts.homedirs file_contexts.local contexts/files/file_contexts.local netfilter_contexts contexts/netfilter_contexts policy.kern policy/policy.<policyversion> seusers.final seusers The layout of these files in /var/lib/selinux/tmp/<store> is designed to mirror their locations in /etc/selinux/<store>. This should help clarify the relationship between these final files and the files installed in etc. One consequence of this move is that reverting to the previous policy version requires a policy rebuild. Currently you can revert without rebuilding. [1] CIL RFC: http://marc.info/?l=selinux&m=124759244409438&w=2 Signed-off-by: Chad Sellers <csellers@tresys.com>
227 lines
4.9 KiB
C
227 lines
4.9 KiB
C
/* Copyright (C) 2005 Red Hat, Inc. */
|
|
|
|
struct semanage_user_base;
|
|
struct semanage_user_key;
|
|
typedef struct semanage_user_base record_t;
|
|
typedef struct semanage_user_key record_key_t;
|
|
#define DBASE_RECORD_DEFINED
|
|
|
|
struct dbase_file;
|
|
typedef struct dbase_file dbase_t;
|
|
#define DBASE_DEFINED
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <semanage/handle.h>
|
|
#include "user_internal.h"
|
|
#include "database_file.h"
|
|
#include "parse_utils.h"
|
|
#include "debug.h"
|
|
|
|
static int user_base_print(semanage_handle_t * handle,
|
|
semanage_user_base_t * user, FILE * str)
|
|
{
|
|
|
|
const char **roles = NULL;
|
|
unsigned int i, nroles;
|
|
|
|
const char *name = semanage_user_base_get_name(user);
|
|
const char *mls_level = semanage_user_base_get_mlslevel(user);
|
|
const char *mls_range = semanage_user_base_get_mlsrange(user);
|
|
|
|
if (fprintf(str, "user %s roles { ", name) < 0)
|
|
goto err;
|
|
|
|
if (semanage_user_base_get_roles(handle, user, &roles, &nroles) < 0)
|
|
goto err;
|
|
|
|
for (i = 0; i < nroles; i++) {
|
|
if (fprintf(str, "%s ", roles[i]) < 0)
|
|
goto err;
|
|
}
|
|
|
|
if (fprintf(str, "} ") < 0)
|
|
goto err;
|
|
|
|
/* MLS */
|
|
if (mls_level != NULL && mls_range != NULL)
|
|
if (fprintf(str, "level %s range %s", mls_level, mls_range) < 0)
|
|
goto err;
|
|
|
|
if (fprintf(str, ";\n") < 0)
|
|
goto err;
|
|
|
|
free(roles);
|
|
return STATUS_SUCCESS;
|
|
|
|
err:
|
|
free(roles);
|
|
ERR(handle, "could not print user %s to stream", name);
|
|
return STATUS_ERR;
|
|
}
|
|
|
|
static int user_base_parse(semanage_handle_t * handle,
|
|
parse_info_t * info, semanage_user_base_t * user)
|
|
{
|
|
|
|
int islist = 0;
|
|
char *str = NULL;
|
|
char *start;
|
|
char *name_str = NULL;
|
|
|
|
if (parse_skip_space(handle, info) < 0)
|
|
goto err;
|
|
if (!info->ptr)
|
|
goto last;
|
|
|
|
/* Parse user header */
|
|
if (parse_assert_str(handle, info, "user") < 0)
|
|
goto err;
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
|
|
/* Parse user name */
|
|
if (parse_fetch_string(handle, info, &name_str, ' ') < 0)
|
|
goto err;
|
|
|
|
if (semanage_user_base_set_name(handle, user, name_str) < 0) {
|
|
free(name_str);
|
|
goto err;
|
|
}
|
|
free(name_str);
|
|
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_assert_str(handle, info, "roles") < 0)
|
|
goto err;
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
|
|
islist = (parse_optional_ch(info, '{') != STATUS_NODATA);
|
|
|
|
/* For each role, loop */
|
|
do {
|
|
char delim;
|
|
|
|
if (parse_skip_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_assert_noeof(handle, info) < 0)
|
|
goto err;
|
|
|
|
start = info->ptr;
|
|
while (*(info->ptr) &&
|
|
*(info->ptr) != ';' &&
|
|
*(info->ptr) != '}' && !isspace(*(info->ptr)))
|
|
info->ptr++;
|
|
|
|
delim = *(info->ptr);
|
|
*(info->ptr)++ = '\0';
|
|
|
|
if (semanage_user_base_add_role(handle, user, start) < 0)
|
|
goto err;
|
|
|
|
if (delim && !isspace(delim)) {
|
|
if (islist && delim == '}')
|
|
break;
|
|
else if (!islist && delim == ';')
|
|
goto skip_semicolon;
|
|
else
|
|
goto err;
|
|
}
|
|
|
|
if (parse_skip_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_optional_ch(info, ';') != STATUS_NODATA)
|
|
goto skip_semicolon;
|
|
if (parse_optional_ch(info, '}') != STATUS_NODATA)
|
|
islist = 0;
|
|
|
|
} while (islist);
|
|
|
|
/* Handle mls */
|
|
/* Parse level header */
|
|
if (parse_skip_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_optional_str(info, "level") == STATUS_NODATA)
|
|
goto semicolon;
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
|
|
/* NOTE: does not allow spaces/multiline */
|
|
if (parse_fetch_string(handle, info, &str, ' ') < 0)
|
|
goto err;
|
|
if (semanage_user_base_set_mlslevel(handle, user, str) < 0)
|
|
goto err;
|
|
free(str);
|
|
str = NULL;
|
|
|
|
/* Parse range header */
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_assert_str(handle, info, "range") < 0)
|
|
goto err;
|
|
if (parse_assert_space(handle, info) < 0)
|
|
goto err;
|
|
|
|
/* NOTE: does not allow spaces/multiline */
|
|
if (parse_fetch_string(handle, info, &str, ';') < 0)
|
|
goto err;
|
|
if (semanage_user_base_set_mlsrange(handle, user, str) < 0)
|
|
goto err;
|
|
|
|
free(str);
|
|
str = NULL;
|
|
|
|
/* Check for semicolon */
|
|
semicolon:
|
|
if (parse_skip_space(handle, info) < 0)
|
|
goto err;
|
|
if (parse_assert_ch(handle, info, ';') < 0)
|
|
goto err;
|
|
|
|
skip_semicolon:
|
|
return STATUS_SUCCESS;
|
|
|
|
last:
|
|
parse_dispose_line(info);
|
|
return STATUS_NODATA;
|
|
|
|
err:
|
|
ERR(handle, "could not parse user record");
|
|
free(str);
|
|
parse_dispose_line(info);
|
|
return STATUS_ERR;
|
|
}
|
|
|
|
/* USER BASE record: FILE extension: method table */
|
|
record_file_table_t SEMANAGE_USER_BASE_FILE_RTABLE = {
|
|
.parse = user_base_parse,
|
|
.print = user_base_print,
|
|
};
|
|
|
|
int user_base_file_dbase_init(semanage_handle_t * handle,
|
|
const char *path_ro,
|
|
const char *path_rw,
|
|
dbase_config_t * dconfig)
|
|
{
|
|
|
|
if (dbase_file_init(handle,
|
|
path_ro,
|
|
path_rw,
|
|
&SEMANAGE_USER_BASE_RTABLE,
|
|
&SEMANAGE_USER_BASE_FILE_RTABLE,
|
|
&dconfig->dbase) < 0)
|
|
return STATUS_ERR;
|
|
|
|
dconfig->dtable = &SEMANAGE_FILE_DTABLE;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
void user_base_file_dbase_release(dbase_config_t * dconfig)
|
|
{
|
|
|
|
dbase_file_release(dconfig->dbase);
|
|
}
|