Merge branch 'master' of oss.tresys.com:/home/git/selinux

This commit is contained in:
Joshua Brindle 2010-03-18 16:38:45 -04:00
commit e53b2cebf2
14 changed files with 476 additions and 8 deletions

View File

@ -1,3 +1,8 @@
2.0.93 2010-03-15
* Show strerror for security_getenforce() by Colin Waters.
* Merged selabel database support by KaiGai Kohei.
* Modify netlink socket blocking code by KaiGai Kohei.
2.0.92 2010-03-06 2.0.92 2010-03-06
* Fix from Eric Paris to fix leak on non-selinux systems. * Fix from Eric Paris to fix leak on non-selinux systems.
* regenerate swig wrappers * regenerate swig wrappers

View File

@ -1 +1 @@
2.0.92 2.0.93

View File

@ -29,6 +29,8 @@ struct selabel_handle;
#define SELABEL_CTX_MEDIA 1 #define SELABEL_CTX_MEDIA 1
/* x contexts */ /* x contexts */
#define SELABEL_CTX_X 2 #define SELABEL_CTX_X 2
/* db objects */
#define SELABEL_CTX_DB 3
/* /*
* Available options * Available options
@ -116,6 +118,16 @@ void selabel_stats(struct selabel_handle *handle);
#define SELABEL_X_POLYPROP 6 #define SELABEL_X_POLYPROP 6
#define SELABEL_X_POLYSELN 7 #define SELABEL_X_POLYSELN 7
/* DB backend */
#define SELABEL_DB_DATABASE 1
#define SELABEL_DB_SCHEMA 2
#define SELABEL_DB_TABLE 3
#define SELABEL_DB_COLUMN 4
#define SELABEL_DB_SEQUENCE 5
#define SELABEL_DB_VIEW 6
#define SELABEL_DB_PROCEDURE 7
#define SELABEL_DB_BLOB 8
#define SELABEL_DB_TUPLE 9
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -487,6 +487,7 @@ extern const char *selinux_media_context_path(void);
extern const char *selinux_virtual_domain_context_path(void); extern const char *selinux_virtual_domain_context_path(void);
extern const char *selinux_virtual_image_context_path(void); extern const char *selinux_virtual_image_context_path(void);
extern const char *selinux_x_context_path(void); extern const char *selinux_x_context_path(void);
extern const char *selinux_sepgsql_context_path(void);
extern const char *selinux_contexts_path(void); extern const char *selinux_contexts_path(void);
extern const char *selinux_securetty_types_path(void); extern const char *selinux_securetty_types_path(void);
extern const char *selinux_booleans_path(void); extern const char *selinux_booleans_path(void);

View File

@ -72,15 +72,19 @@ Note that an invalid context may not be treated as an error unless it is actuall
.TP .TP
.B SELABEL_CTX_FILE .B SELABEL_CTX_FILE
File contexts backend, described in File contexts backend, described in
.BR selabel_file (3). .BR selabel_file (5).
.TP .TP
.B SELABEL_CTX_MEDIA .B SELABEL_CTX_MEDIA
Media contexts backend, described in Media contexts backend, described in
.BR selabel_media (3). .BR selabel_media (5).
.TP .TP
.B SELABEL_CTX_X .B SELABEL_CTX_X
X Windows contexts backend, described in X Windows contexts backend, described in
.BR selabel_x (3). .BR selabel_x (5).
.TP
.B SELABEL_CTX_DB
Database objects contexts backend, described in
.BR selabel_db (5).
.SH "RETURN VALUE" .SH "RETURN VALUE"
A non-NULL handle value is returned on success. On error, NULL is returned and A non-NULL handle value is returned on success. On error, NULL is returned and

View File

@ -29,6 +29,8 @@ extern const char *selinux_usersconf_path(void);
extern const char *selinux_x_context_path(void); extern const char *selinux_x_context_path(void);
extern const char *selinux_sepgsql_context_path(void);
extern const char *selinux_file_context_path(void); extern const char *selinux_file_context_path(void);
extern const char *selinux_media_context_path(void); extern const char *selinux_media_context_path(void);
@ -66,6 +68,8 @@ selinux_usersconf_path() - file containing mapping between Linux Users and SELin
.sp .sp
selinux_x_context_path() - file containing configuration for XSELinux extension selinux_x_context_path() - file containing configuration for XSELinux extension
.sp .sp
selinux_sepgsql_context_path() - file containing configuration for SE-PostgreSQL
.sp
selinux_netfilter_context_path - default netfilter context selinux_netfilter_context_path - default netfilter context
.sp .sp
selinux_file_context_path() - default system file contexts configuration selinux_file_context_path() - default system file contexts configuration

View File

@ -0,0 +1,93 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\"
.\" Author: KaiGai Kohei <kaigai@ak.jp.nec.com> 2009
.TH "selabel_db" "5" "22 Nov 2009" "" "SELinux API documentation"
.SH "NAME"
selabel_db \- userspace SELinux labeling interface: DB objects contexts backend.
.SH "SYNOPSIS"
.B #include <selinux/selinux.h>
.B #include <selinux/label.h>
.sp
.BI "int selabel_lookup(struct selabel_handle *" hnd ,
.in +\w'int selabel_lookup('u
.BI "security_context_t *" context ,
.BI "const char *" object_name ", int " object_type ");"
.SH "DESCRIPTION"
The DB contexts backend maps from a pair of object name and class into security contexts. It is used to find the appropriate context for database objects when relabeling a certain database.
The
.I object_name
should be fully qualified name using the hierarchy of database objects.
For example, the
.B pg_class
table in the
.B postgres
database and
.B pg_catalog
schema should be qualified as
.B postgres.pg_catalog.pg_class .
The
.I object_type
argument should be set to one of the following values:
.TP
.B SELABEL_DB_DATABASE
The
.I object_name
argument specifies the name of a database itself, such as "postgres".
.TP
.B SELABEL_DB_SCHEMA
The
.I object_name
argument specifies the name of a schema object, such as "postgres.public".
.TP
.B SELABEL_DB_TABLE
The
.I object_name
argument specifies the name of a table object, such as "postgres.public.my_table"
.TP
.B SELABEL_DB_COLUMN
The
.I object_name
argument specifies the name of a column object, such as "postgres.public.my_table.user_id"
.TP
.B SELABEL_DB_TUPLE
The
.I object_name
argument specifies the name of a table object which contains the tuples to be relabeled, such as "postgresql.public.my_table". Note that we have no way to identify individual tuple objects, except for WHERE clause on DML statements, because it has no name.
.TP
.B SELABEL_DB_PROCEDURE
The
.I object_name
argument specifies the name of a procedure object, such as "postgres.public.my_func". Note that we don't support to lookup individual security contexts for each procedures which have same name but different arguments.
.TP
.B SELABEL_DB_SEQUENCE
The
.I object_name
argument specifies the name of a sequence object, such as "postgres.public.my_seq".
.TP
.B SELABEL_DB_BLOB
The
.I object_name
argument specifies the name of a large object, such as "postgres.16308".
Note that a large object does not have its name, so it is identified by its identifier value.
.SH "OPTIONS"
In addition to the global options described in
.BR selabel_open (3),
this backend recognizes the following options:
.TP
.B SELABEL_OPT_PATH
A non-null value for this option specifies a path to a file that will be opened in lieu of the standard DB contexts file.
It tries to open the specfile designed for SE-PostgreSQL in the default, so if another RDBMS uses this interface, it needs to give an explicit specfile designed for the RDBMS.
.SH "SEE ALSO"
.BR selabel_open (3),
.BR selabel_lookup (3),
.BR selabel_stats (3),
.BR selinux (8)

View File

@ -215,8 +215,9 @@ int avc_init(const char *prefix,
rc = security_getenforce(); rc = security_getenforce();
if (rc < 0) { if (rc < 0) {
avc_log(SELINUX_ERROR, avc_log(SELINUX_ERROR,
"%s: could not determine enforcing mode\n", "%s: could not determine enforcing mode: %s\n",
avc_prefix); avc_prefix,
strerror(errno));
goto out; goto out;
} }
avc_enforcing = rc; avc_enforcing = rc;

View File

@ -23,3 +23,4 @@ S_(BINPOLICY, "/policy/policy")
S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context") S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context")
S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context") S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context")
S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs") S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs")
S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts")

View File

@ -22,7 +22,8 @@ typedef int (*selabel_initfunc)(struct selabel_handle *rec,
static selabel_initfunc initfuncs[] = { static selabel_initfunc initfuncs[] = {
&selabel_file_init, &selabel_file_init,
&selabel_media_init, &selabel_media_init,
&selabel_x_init &selabel_x_init,
&selabel_db_init,
}; };
typedef struct selabel_sub { typedef struct selabel_sub {

336
libselinux/src/label_db.c Normal file
View File

@ -0,0 +1,336 @@
/*
* Media contexts backend for DB objects
*
* Author: KaiGai Kohei <kaigai@ak.jp.nec.com>
*/
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <fnmatch.h>
#include "callbacks.h"
#include "label_internal.h"
/*
* Regular database object's security context interface
*
* It provides applications a regular security context for the given
* database objects. The pair of object's name and a security context
* are described in the specfile. In the default, it shall be stored
* in the /etc/selinux/$POLICYTYPE/contexts/sepgsql_contexts .
* (It assumes SE-PostgreSQL in the default. For other RDBMS, use the
* SELABEL_OPT_PATH option to specify different specfile.)
*
* Each line has the following format:
* <object class> <object name/identifier> <security context>
*
* For example:
* ----------------------------------------
* #
* # It is an example specfile for database obejcts
* #
* db_database template1 system_u:object_r:sepgsql_db_t:s0
*
* db_schema *.pg_catalog system_u:object_r:sepgsql_sys_schema_t:s0
*
* db_table *.pg_catalog.* system_u:object_r:sepgsql_sysobj_t:s0
* db_column *.pg_catalog.*.* system_u:object_r:sepgsql_sysobj_t:s0
* ----------------------------------------
*
* All the characters after the '#' are dealt as comments.
*
* The first token is object class. SELABEL_DB_* declared in label.h are
* corresponding to a certain database object.
*
* The object name/identifier is compared to the given key.
* A database object can have its own namespace hierarchy.
* In the case of SE-PgSQL, database is the top level object, and schema
* is deployed just under a database. A schema can contains various kind
* of objects, such as tables, procedures and so on.
* Thus, when we lookup an expected security context for a table of
* "pg_class", it is necessary to assume selabel_lookup() is called with
* "postgres.pg_catalog.pg_class", not just a "pg_class".
*
* Wildcards ('*' or '?') are available on the patterns, so if you want
* to match a table within any schema, you should set '*' on the upper
* namespaces of the table.
*
* The structure of namespace depends on RDBMS.
* For example, Trusted-RUBIX has an idea of "catalog" which performs
* as a namespace between a database and individual schemas. In this
* case, a table has upper three layers.
*/
/*
* spec_t : It holds a pair of a key and an expected security context
*/
typedef struct spec {
struct selabel_lookup_rec lr;
char *key;
int type;
int matches;
} spec_t;
/*
* catalog_t : An array of spec_t
*/
typedef struct catalog {
unsigned int nspec; /* number of specs in use */
unsigned int limit; /* physical limitation of specs[] */
spec_t specs[0];
} catalog_t;
/*
* Helper function to parse a line read from the specfile
*/
static int
process_line(const char *path, char *line_buf, unsigned int line_num,
catalog_t *catalog)
{
spec_t *spec = &catalog->specs[catalog->nspec];
char *type, *key, *context, *temp;
int items;
/* Cut off comments */
temp = strchr(line_buf, '#');
if (temp)
*temp = '\0';
/*
* Every entry must have the following format
* <object class> <object name> <security context>
*/
type = key = context = temp = NULL;
items = sscanf(line_buf, "%as %as %as %as",
&type, &key, &context, &temp);
if (items != 3) {
if (items > 0)
selinux_log(SELINUX_WARNING,
"%s: line %d has invalid format, skipped",
path, line_num);
goto skip;
}
/*
* Set up individual spec entry
*/
memset(spec, 0, sizeof(spec_t));
if (!strcmp(type, "db_database"))
spec->type = SELABEL_DB_DATABASE;
else if (!strcmp(type, "db_schema"))
spec->type = SELABEL_DB_SCHEMA;
else if (!strcmp(type, "db_table"))
spec->type = SELABEL_DB_TABLE;
else if (!strcmp(type, "db_column"))
spec->type = SELABEL_DB_COLUMN;
else if (!strcmp(type, "db_sequence"))
spec->type = SELABEL_DB_SEQUENCE;
else if (!strcmp(type, "db_view"))
spec->type = SELABEL_DB_VIEW;
else if (!strcmp(type, "db_procedure"))
spec->type = SELABEL_DB_PROCEDURE;
else if (!strcmp(type, "db_blob"))
spec->type = SELABEL_DB_BLOB;
else if (!strcmp(type, "db_tuple"))
spec->type = SELABEL_DB_TUPLE;
else {
selinux_log(SELINUX_WARNING,
"%s: line %d has invalid object type %s\n",
path, line_num, type);
goto skip;
}
free(type);
spec->key = key;
spec->lr.ctx_raw = context;
catalog->nspec++;
return 0;
skip:
free(type);
free(key);
free(context);
free(temp);
return 0;
}
/*
* selabel_close() handler
*/
static void
db_close(struct selabel_handle *rec)
{
catalog_t *catalog = (catalog_t *)rec->data;
spec_t *spec;
unsigned int i;
for (i = 0; i < catalog->nspec; i++) {
spec = &catalog->specs[i];
free(spec->key);
free(spec->lr.ctx_raw);
free(spec->lr.ctx_trans);
}
free(catalog);
}
/*
* selabel_lookup() handler
*/
static struct selabel_lookup_rec *
db_lookup(struct selabel_handle *rec, const char *key, int type)
{
catalog_t *catalog = (catalog_t *)rec->data;
spec_t *spec;
unsigned int i;
for (i = 0; i < catalog->nspec; i++) {
spec = &catalog->specs[i];
if (spec->type != type)
continue;
if (!fnmatch(spec->key, key, 0)) {
spec->matches++;
return &spec->lr;
}
}
/* No found */
errno = ENOENT;
return NULL;
}
/*
* selabel_stats() handler
*/
static void
db_stats(struct selabel_handle *rec)
{
catalog_t *catalog = (catalog_t *)rec->data;
unsigned int i, total = 0;
for (i = 0; i < catalog->nspec; i++)
total += catalog->specs[i].matches;
selinux_log(SELINUX_INFO, "%u entries, %u matches made\n",
catalog->nspec, total);
}
/*
* selabel_open() handler
*/
static catalog_t *
db_init(struct selinux_opt *opts, unsigned nopts)
{
catalog_t *catalog;
FILE *filp;
const char *path = NULL;
char *line_buf = NULL;
size_t line_len = 0;
unsigned int line_num = 0;
unsigned int i;
/*
* Initialize catalog data structure
*/
catalog = malloc(sizeof(catalog_t) + 32 * sizeof(spec_t));
if (!catalog)
return NULL;
catalog->limit = 32;
catalog->nspec = 0;
/*
* Process arguments
*
* SELABEL_OPT_PATH:
* It allows to specify an alternative specification file instead of
* the default one. If RDBMS is not SE-PostgreSQL, it may need to
* specify an explicit specfile for database objects.
*/
while (nopts--) {
switch (opts[nopts].type) {
case SELABEL_OPT_PATH:
path = opts[nopts].value;
break;
}
}
/*
* Open the specification file
*/
if (!path)
path = selinux_sepgsql_context_path();
if ((filp = fopen(path, "rb")) == NULL) {
free(catalog);
return NULL;
}
/*
* Parse for each lines
*/
while (getline(&line_buf, &line_len, filp) > 0) {
/*
* Expand catalog array, if necessary
*/
if (catalog->limit == catalog->nspec) {
size_t length;
unsigned int new_limit = 2 * catalog->limit;
catalog_t *new_catalog;
length = sizeof(catalog_t)
+ new_limit * sizeof(spec_t);
new_catalog = realloc(catalog, length);
if (!new_catalog)
goto out_error;
catalog = new_catalog;
catalog->limit = new_limit;
}
/*
* Parse a line
*/
if (process_line(path, line_buf, ++line_num, catalog) < 0)
goto out_error;
}
free(line_buf);
fclose(filp);
return catalog;
out_error:
for (i = 0; i < catalog->nspec; i++) {
spec_t *spec = &catalog->specs[i];
free(spec->key);
free(spec->lr.ctx_raw);
free(spec->lr.ctx_trans);
}
free(catalog);
return NULL;
}
/*
* Initialize selabel_handle and load the entries of specfile
*/
int selabel_db_init(struct selabel_handle *rec,
struct selinux_opt *opts, unsigned nopts)
{
rec->func_close = &db_close;
rec->func_lookup = &db_lookup;
rec->func_stats = &db_stats;
rec->data = db_init(opts, nopts);
return !rec->data ? -1 : 0;
}

View File

@ -23,6 +23,8 @@ int selabel_media_init(struct selabel_handle *rec, struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) hidden;
int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts, int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
unsigned nopts) hidden; unsigned nopts) hidden;
int selabel_db_init(struct selabel_handle *rec,
struct selinux_opt *opts, unsigned nopts) hidden;
/* /*
* Labeling internal structures * Labeling internal structures

View File

@ -44,7 +44,8 @@
#define VIRTUAL_DOMAIN 21 #define VIRTUAL_DOMAIN 21
#define VIRTUAL_IMAGE 22 #define VIRTUAL_IMAGE 22
#define FILE_CONTEXT_SUBS 23 #define FILE_CONTEXT_SUBS 23
#define NEL 24 #define SEPGSQL_CONTEXTS 24
#define NEL 25
/* Part of one-time lazy init */ /* Part of one-time lazy init */
static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_once_t once = PTHREAD_ONCE_INIT;
@ -422,3 +423,9 @@ const char * selinux_file_context_subs_path(void) {
hidden_def(selinux_file_context_subs_path) hidden_def(selinux_file_context_subs_path)
const char *selinux_sepgsql_context_path()
{
return get_path(SEPGSQL_CONTEXTS);
}
hidden_def(selinux_sepgsql_context_path)

View File

@ -73,6 +73,7 @@ hidden_proto(selinux_mkload_policy)
hidden_proto(selinux_customizable_types_path) hidden_proto(selinux_customizable_types_path)
hidden_proto(selinux_media_context_path) hidden_proto(selinux_media_context_path)
hidden_proto(selinux_x_context_path) hidden_proto(selinux_x_context_path)
hidden_proto(selinux_sepgsql_context_path)
hidden_proto(selinux_path) hidden_proto(selinux_path)
hidden_proto(selinux_check_passwd_access) hidden_proto(selinux_check_passwd_access)
hidden_proto(selinux_check_securetty_context) hidden_proto(selinux_check_securetty_context)