mirror of
https://github.com/SELinuxProject/selinux
synced 2024-12-26 07:52:07 +00:00
Merge branch 'master' of oss.tresys.com:/home/git/selinux
This commit is contained in:
commit
e53b2cebf2
@ -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
|
||||
* Fix from Eric Paris to fix leak on non-selinux systems.
|
||||
* regenerate swig wrappers
|
||||
|
@ -1 +1 @@
|
||||
2.0.92
|
||||
2.0.93
|
||||
|
@ -29,6 +29,8 @@ struct selabel_handle;
|
||||
#define SELABEL_CTX_MEDIA 1
|
||||
/* x contexts */
|
||||
#define SELABEL_CTX_X 2
|
||||
/* db objects */
|
||||
#define SELABEL_CTX_DB 3
|
||||
|
||||
/*
|
||||
* Available options
|
||||
@ -116,6 +118,16 @@ void selabel_stats(struct selabel_handle *handle);
|
||||
#define SELABEL_X_POLYPROP 6
|
||||
#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
|
||||
}
|
||||
|
@ -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_image_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_securetty_types_path(void);
|
||||
extern const char *selinux_booleans_path(void);
|
||||
|
@ -72,15 +72,19 @@ Note that an invalid context may not be treated as an error unless it is actuall
|
||||
.TP
|
||||
.B SELABEL_CTX_FILE
|
||||
File contexts backend, described in
|
||||
.BR selabel_file (3).
|
||||
.BR selabel_file (5).
|
||||
.TP
|
||||
.B SELABEL_CTX_MEDIA
|
||||
Media contexts backend, described in
|
||||
.BR selabel_media (3).
|
||||
.BR selabel_media (5).
|
||||
.TP
|
||||
.B SELABEL_CTX_X
|
||||
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"
|
||||
A non-NULL handle value is returned on success. On error, NULL is returned and
|
||||
|
@ -29,6 +29,8 @@ extern const char *selinux_usersconf_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_media_context_path(void);
|
||||
@ -66,6 +68,8 @@ selinux_usersconf_path() - file containing mapping between Linux Users and SELin
|
||||
.sp
|
||||
selinux_x_context_path() - file containing configuration for XSELinux extension
|
||||
.sp
|
||||
selinux_sepgsql_context_path() - file containing configuration for SE-PostgreSQL
|
||||
.sp
|
||||
selinux_netfilter_context_path - default netfilter context
|
||||
.sp
|
||||
selinux_file_context_path() - default system file contexts configuration
|
||||
|
93
libselinux/man/man5/selabel_db.5
Normal file
93
libselinux/man/man5/selabel_db.5
Normal 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)
|
||||
|
@ -215,8 +215,9 @@ int avc_init(const char *prefix,
|
||||
rc = security_getenforce();
|
||||
if (rc < 0) {
|
||||
avc_log(SELINUX_ERROR,
|
||||
"%s: could not determine enforcing mode\n",
|
||||
avc_prefix);
|
||||
"%s: could not determine enforcing mode: %s\n",
|
||||
avc_prefix,
|
||||
strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
avc_enforcing = rc;
|
||||
|
@ -23,3 +23,4 @@ S_(BINPOLICY, "/policy/policy")
|
||||
S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context")
|
||||
S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context")
|
||||
S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs")
|
||||
S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts")
|
||||
|
@ -22,7 +22,8 @@ typedef int (*selabel_initfunc)(struct selabel_handle *rec,
|
||||
static selabel_initfunc initfuncs[] = {
|
||||
&selabel_file_init,
|
||||
&selabel_media_init,
|
||||
&selabel_x_init
|
||||
&selabel_x_init,
|
||||
&selabel_db_init,
|
||||
};
|
||||
|
||||
typedef struct selabel_sub {
|
||||
|
336
libselinux/src/label_db.c
Normal file
336
libselinux/src/label_db.c
Normal 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;
|
||||
}
|
@ -23,6 +23,8 @@ int selabel_media_init(struct selabel_handle *rec, struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
|
||||
unsigned nopts) hidden;
|
||||
int selabel_db_init(struct selabel_handle *rec,
|
||||
struct selinux_opt *opts, unsigned nopts) hidden;
|
||||
|
||||
/*
|
||||
* Labeling internal structures
|
||||
|
@ -44,7 +44,8 @@
|
||||
#define VIRTUAL_DOMAIN 21
|
||||
#define VIRTUAL_IMAGE 22
|
||||
#define FILE_CONTEXT_SUBS 23
|
||||
#define NEL 24
|
||||
#define SEPGSQL_CONTEXTS 24
|
||||
#define NEL 25
|
||||
|
||||
/* Part of one-time lazy 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)
|
||||
|
||||
const char *selinux_sepgsql_context_path()
|
||||
{
|
||||
return get_path(SEPGSQL_CONTEXTS);
|
||||
}
|
||||
|
||||
hidden_def(selinux_sepgsql_context_path)
|
||||
|
@ -73,6 +73,7 @@ hidden_proto(selinux_mkload_policy)
|
||||
hidden_proto(selinux_customizable_types_path)
|
||||
hidden_proto(selinux_media_context_path)
|
||||
hidden_proto(selinux_x_context_path)
|
||||
hidden_proto(selinux_sepgsql_context_path)
|
||||
hidden_proto(selinux_path)
|
||||
hidden_proto(selinux_check_passwd_access)
|
||||
hidden_proto(selinux_check_securetty_context)
|
||||
|
Loading…
Reference in New Issue
Block a user