aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2015-10-28 13:14:22 -0700
committerJeff Vander Stoep <jeffv@google.com>2015-10-28 13:14:22 -0700
commit10ca689116d6e66f21749acf40b2f2f04da2768c (patch)
tree128f1c89737136b60096dd200db590ccaaa2001e
parent3d252fdd97fe3a2f5c5085057302304a132a2ed0 (diff)
parent8dc4c05b7906326c32fe28dd091e5173fb0249be (diff)
downloadselinux-brillo-m7-release.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into mymergebrillo-m7-releasebrillo-m7-mr-devbrillo-m7-dev
-rw-r--r--checkpolicy/Android.mk1
-rw-r--r--checkpolicy/ChangeLog5
-rw-r--r--checkpolicy/policy_define.c390
-rw-r--r--checkpolicy/policy_define.h2
-rw-r--r--checkpolicy/policy_parse.y48
-rw-r--r--checkpolicy/policy_scan.l8
-rw-r--r--checkpolicy/test/dispol.c67
-rw-r--r--libselinux/ChangeLog27
-rw-r--r--libselinux/include/selinux/label.h44
-rw-r--r--libselinux/man/man3/selabel_digest.361
-rw-r--r--libselinux/man/man3/selabel_open.37
-rw-r--r--libselinux/man/man8/sefcontext_compile.860
-rw-r--r--libselinux/src/Makefile9
-rw-r--r--libselinux/src/checkAccess.c27
-rw-r--r--libselinux/src/label.c104
-rw-r--r--libselinux/src/label_android_property.c93
-rw-r--r--libselinux/src/label_db.c17
-rw-r--r--libselinux/src/label_file.c410
-rw-r--r--libselinux/src/label_file.h180
-rw-r--r--libselinux/src/label_internal.h54
-rw-r--r--libselinux/src/label_media.c16
-rw-r--r--libselinux/src/label_support.c113
-rw-r--r--libselinux/src/label_x.c13
-rw-r--r--libselinux/src/procattr.c41
-rw-r--r--libselinux/src/selinux_internal.h2
-rw-r--r--libselinux/src/selinuxswig_python.i9
-rw-r--r--libselinux/src/sha1.c214
-rw-r--r--libselinux/src/sha1.h85
-rw-r--r--libselinux/src/stringrep.c22
-rw-r--r--libselinux/utils/Makefile2
-rw-r--r--libselinux/utils/sefcontext_compile.c299
-rw-r--r--libselinux/utils/selabel_digest.c188
-rw-r--r--libsemanage/ChangeLog9
-rw-r--r--libsemanage/include/semanage/modules.h17
-rw-r--r--libsemanage/src/booleans_policydb.c6
-rw-r--r--libsemanage/src/direct_api.c425
-rw-r--r--libsemanage/src/interfaces_policydb.c6
-rw-r--r--libsemanage/src/libsemanage.map1
-rw-r--r--libsemanage/src/modules.c23
-rw-r--r--libsemanage/src/nodes_policydb.c6
-rw-r--r--libsemanage/src/policy.h8
-rw-r--r--libsemanage/src/ports_policydb.c6
-rw-r--r--libsemanage/src/semanage_store.c30
-rw-r--r--libsemanage/src/semanage_store.h6
-rw-r--r--libsemanage/src/semanageswig_python.i5
-rw-r--r--libsemanage/src/users_base_policydb.c6
-rwxr-xr-xlibsemanage/utils/semanage_migrate_store18
-rw-r--r--libsepol/Android.mk1
-rw-r--r--libsepol/ChangeLog19
-rw-r--r--libsepol/cil/src/cil.c112
-rw-r--r--libsepol/cil/src/cil_binary.c1159
-rw-r--r--libsepol/cil/src/cil_binary.h15
-rw-r--r--libsepol/cil/src/cil_build_ast.c335
-rw-r--r--libsepol/cil/src/cil_build_ast.h8
-rw-r--r--libsepol/cil/src/cil_copy_ast.c113
-rw-r--r--libsepol/cil/src/cil_copy_ast.h2
-rw-r--r--libsepol/cil/src/cil_find.c305
-rw-r--r--libsepol/cil/src/cil_find.h39
-rw-r--r--libsepol/cil/src/cil_flavor.h4
-rw-r--r--libsepol/cil/src/cil_fqn.c1
-rw-r--r--libsepol/cil/src/cil_internal.h53
-rw-r--r--libsepol/cil/src/cil_policy.c5
-rw-r--r--libsepol/cil/src/cil_post.c352
-rw-r--r--libsepol/cil/src/cil_reset_ast.c33
-rw-r--r--libsepol/cil/src/cil_resolve_ast.c440
-rw-r--r--libsepol/cil/src/cil_resolve_ast.h1
-rw-r--r--libsepol/cil/src/cil_tree.c22
-rw-r--r--libsepol/cil/src/cil_verify.c37
-rw-r--r--libsepol/include/sepol/policydb/avtab.h27
-rw-r--r--libsepol/include/sepol/policydb/ebitmap.h1
-rw-r--r--libsepol/include/sepol/policydb/hierarchy.h11
-rw-r--r--libsepol/include/sepol/policydb/policydb.h43
-rw-r--r--libsepol/include/sepol/policydb/util.h8
-rw-r--r--libsepol/src/assertion.c456
-rw-r--r--libsepol/src/avtab.c57
-rw-r--r--libsepol/src/ebitmap.c22
-rw-r--r--libsepol/src/expand.c149
-rw-r--r--libsepol/src/hierarchy.c996
-rw-r--r--libsepol/src/module_to_cil.c61
-rw-r--r--libsepol/src/policydb.c6
-rw-r--r--libsepol/src/util.c170
-rw-r--r--libsepol/src/write.c30
-rw-r--r--policycoreutils/ChangeLog8
-rwxr-xr-xpolicycoreutils/audit2allow/audit2allow141
-rwxr-xr-xpolicycoreutils/audit2allow/audit2why133
-rw-r--r--policycoreutils/audit2allow/sepolgen-ifgen26
-rw-r--r--policycoreutils/audit2allow/test_audit2allow.py29
-rw-r--r--policycoreutils/gui/booleansPage.py69
-rw-r--r--policycoreutils/gui/domainsPage.py24
-rw-r--r--policycoreutils/gui/fcontextPage.py83
-rw-r--r--policycoreutils/gui/html_util.py19
-rw-r--r--policycoreutils/gui/loginsPage.py45
-rw-r--r--policycoreutils/gui/mappingsPage.py6
-rw-r--r--policycoreutils/gui/modulesPage.py33
-rw-r--r--policycoreutils/gui/polgengui.py201
-rw-r--r--policycoreutils/gui/portsPage.py48
-rw-r--r--policycoreutils/gui/semanagePage.py29
-rw-r--r--policycoreutils/gui/statusPage.py40
-rw-r--r--policycoreutils/gui/system-config-selinux.py33
-rw-r--r--policycoreutils/gui/usersPage.py30
-rw-r--r--policycoreutils/mcstrans/share/util/mlscolor-test18
-rw-r--r--policycoreutils/mcstrans/share/util/mlstrans-test27
-rw-r--r--policycoreutils/newrole/newrole.c76
-rw-r--r--policycoreutils/sandbox/sandbox608
-rw-r--r--policycoreutils/sandbox/start10
-rw-r--r--policycoreutils/sandbox/test_sandbox.py45
-rwxr-xr-xpolicycoreutils/scripts/chcat177
-rw-r--r--policycoreutils/semanage/semanage279
-rw-r--r--policycoreutils/semanage/seobject.py4315
-rw-r--r--policycoreutils/semanage/test-semanage.py291
-rw-r--r--policycoreutils/semodule/semodule.814
-rw-r--r--policycoreutils/semodule/semodule.c146
-rw-r--r--policycoreutils/sepolicy/selinux_client.py19
-rw-r--r--policycoreutils/sepolicy/selinux_server.py29
-rwxr-xr-xpolicycoreutils/sepolicy/sepolicy.py220
-rw-r--r--policycoreutils/sepolicy/sepolicy/__init__.py487
-rw-r--r--policycoreutils/sepolicy/sepolicy/booleans.py19
-rwxr-xr-xpolicycoreutils/sepolicy/sepolicy/communicate.py21
-rw-r--r--policycoreutils/sepolicy/sepolicy/generate.py2168
-rw-r--r--policycoreutils/sepolicy/sepolicy/gui.py527
-rw-r--r--policycoreutils/sepolicy/sepolicy/interface.py49
-rwxr-xr-xpolicycoreutils/sepolicy/sepolicy/manpage.py1174
-rwxr-xr-xpolicycoreutils/sepolicy/sepolicy/network.py33
-rw-r--r--policycoreutils/sepolicy/sepolicy/sedbus.py30
-rwxr-xr-xpolicycoreutils/sepolicy/sepolicy/transition.py35
-rw-r--r--policycoreutils/sepolicy/setup.py8
-rw-r--r--policycoreutils/sepolicy/test_sepolicy.py39
-rw-r--r--secilc/Android.mk1
-rw-r--r--secilc/ChangeLog6
-rw-r--r--secilc/docs/cil_access_vector_rules.xml172
-rw-r--r--secilc/docs/cil_class_and_permission_statements.xml95
-rw-r--r--secilc/docs/cil_constraint_statements.xml8
-rw-r--r--secilc/docs/cil_container_statements.xml23
-rw-r--r--secilc/docs/cil_user_statements.xml110
-rw-r--r--secilc/test/bounds.cil241
-rw-r--r--secilc/test/neverallow.cil79
-rw-r--r--secilc/test/policy.cil31
-rw-r--r--sepolgen/ChangeLog5
-rw-r--r--sepolgen/src/sepolgen/access.py45
-rw-r--r--sepolgen/src/sepolgen/audit.py13
-rw-r--r--sepolgen/src/sepolgen/classperms.py10
-rw-r--r--sepolgen/src/sepolgen/defaults.py4
-rw-r--r--sepolgen/src/sepolgen/interfaces.py14
-rw-r--r--sepolgen/src/sepolgen/lex.py164
-rw-r--r--sepolgen/src/sepolgen/matching.py39
-rw-r--r--sepolgen/src/sepolgen/module.py17
-rw-r--r--sepolgen/src/sepolgen/objectmodel.py2
-rw-r--r--sepolgen/src/sepolgen/output.py12
-rw-r--r--sepolgen/src/sepolgen/policygen.py21
-rw-r--r--sepolgen/src/sepolgen/refparser.py26
-rw-r--r--sepolgen/src/sepolgen/refpolicy.py39
-rw-r--r--sepolgen/src/sepolgen/util.py95
-rw-r--r--sepolgen/src/sepolgen/yacc.py199
-rw-r--r--sepolgen/tests/test_access.py74
-rw-r--r--sepolgen/tests/test_audit.py109
-rw-r--r--sepolgen/tests/test_interfaces.py29
-rw-r--r--sepolgen/tests/test_matching.py12
-rw-r--r--sepolgen/tests/test_objectmodel.py19
-rw-r--r--sepolgen/tests/test_refparser.py6
-rw-r--r--sepolgen/tests/test_refpolicy.py59
160 files changed, 14012 insertions, 7911 deletions
diff --git a/checkpolicy/Android.mk b/checkpolicy/Android.mk
index 09ca2ac9..bcaa36f1 100644
--- a/checkpolicy/Android.mk
+++ b/checkpolicy/Android.mk
@@ -11,7 +11,6 @@ common_src_files := \
common_cflags := \
-Wall -Wshadow -O2 \
-pipe -fno-strict-aliasing \
- -Wno-return-type
ifeq ($(HOST_OS),darwin)
common_cflags += -DDARWIN
diff --git a/checkpolicy/ChangeLog b/checkpolicy/ChangeLog
index daa1bbd9..1062cb0d 100644
--- a/checkpolicy/ChangeLog
+++ b/checkpolicy/ChangeLog
@@ -1,3 +1,8 @@
+ * Add neverallow support for ioctl extended permissions, from Jeff Vander Stoep.
+ * fix double free on name-based type transitions, from Stephen Smalley.
+ * switch operations to extended perms, from Jeff Vander Stoep.
+ * policy_define.c: fix compiler warnings, from Nick Kralevich.
+ * Remove uses of -Wno-return-type, from Dan Albert.
* Fix -Wreturn-type issues, from Dan Albert.
* dispol: display operations as ranges, from Jeff Vander Stoep.
* dispol: Extend to display operations, from Stephen Smalley.
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 093bded0..ee20fea2 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -1521,7 +1521,8 @@ int define_compute_type_helper(int which, avrule_t ** rule)
ebitmap_node_t *node;
avrule_t *avrule;
class_perm_node_t *perm;
- int i, add = 1;
+ uint32_t i;
+ int add = 1;
avrule = malloc(sizeof(avrule_t));
if (!avrule) {
@@ -1728,32 +1729,27 @@ avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
return sl;
}
-#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
-#define operation_perm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
-#define operation_perm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
-
-typedef struct av_operations_range {
+typedef struct av_ioctl_range {
uint16_t low;
uint16_t high;
-} av_operations_range_t;
+} av_ioctl_range_t;
-struct av_operations_range_list {
+struct av_ioctl_range_list {
uint8_t omit;
- av_operations_range_t range;
- struct av_operations_range_list *next;
+ av_ioctl_range_t range;
+ struct av_ioctl_range_list *next;
};
-int avrule_sort_operations(
- struct av_operations_range_list **rangehead)
+int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead)
{
- struct av_operations_range_list *r, *r2, *sorted, *sortedhead = NULL;
+ struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL;
/* order list by range.low */
for (r = *rangehead; r != NULL; r = r->next) {
- sorted = malloc(sizeof(struct av_operations_range_list));
+ sorted = malloc(sizeof(struct av_ioctl_range_list));
if (sorted == NULL)
goto error;
- memcpy(sorted, r, sizeof(struct av_operations_range_list));
+ memcpy(sorted, r, sizeof(struct av_ioctl_range_list));
sorted->next = NULL;
if (sortedhead == NULL) {
sortedhead = sorted;
@@ -1792,9 +1788,9 @@ error:
return -1;
}
-int avrule_merge_operations(struct av_operations_range_list **rangehead)
+int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead)
{
- struct av_operations_range_list *r, *tmp;
+ struct av_ioctl_range_list *r, *tmp;
r = *rangehead;
while (r != NULL && r->next != NULL) {
/* merge */
@@ -1812,14 +1808,14 @@ int avrule_merge_operations(struct av_operations_range_list **rangehead)
return 0;
}
-int avrule_read_operations(struct av_operations_range_list **rangehead)
+int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
{
char *id;
- struct av_operations_range_list *rnew, *r = NULL;
+ struct av_ioctl_range_list *rnew, *r = NULL;
*rangehead = NULL;
uint8_t omit = 0;
- /* read in all the operations */
+ /* read in all the ioctl commands */
while ((id = queue_remove(id_queue))) {
if (strcmp(id,"~") == 0) {
/* these are values to be omitted */
@@ -1837,7 +1833,7 @@ int avrule_read_operations(struct av_operations_range_list **rangehead)
free(id);
} else {
/* read in new low value */
- rnew = malloc(sizeof(struct av_operations_range_list));
+ rnew = malloc(sizeof(struct av_ioctl_range_list));
if (rnew == NULL)
goto error;
rnew->next = NULL;
@@ -1862,11 +1858,11 @@ error:
}
/* flip to included ranges */
-int avrule_omit_operations(struct av_operations_range_list **rangehead)
+int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead)
{
- struct av_operations_range_list *rnew, *r, *newhead, *r2;
+ struct av_ioctl_range_list *rnew, *r, *newhead, *r2;
- rnew = calloc(1, sizeof(struct av_operations_range_list));
+ rnew = calloc(1, sizeof(struct av_ioctl_range_list));
if (!rnew)
goto error;
@@ -1884,7 +1880,7 @@ int avrule_omit_operations(struct av_operations_range_list **rangehead)
while (r) {
r2->range.high = r->range.low - 1;
- rnew = calloc(1, sizeof(struct av_operations_range_list));
+ rnew = calloc(1, sizeof(struct av_ioctl_range_list));
if (!rnew)
goto error;
r2->next = rnew;
@@ -1910,27 +1906,27 @@ error:
return -1;
}
-int avrule_operation_ranges(struct av_operations_range_list **rangelist)
+int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist)
{
- struct av_operations_range_list *rangehead;
+ struct av_ioctl_range_list *rangehead;
uint8_t omit;
/* read in ranges to include and omit */
- if (avrule_read_operations(&rangehead))
+ if (avrule_read_ioctls(&rangehead))
return -1;
omit = rangehead->omit;
if (rangehead == NULL) {
- yyerror("error processing ioctl operations");
+ yyerror("error processing ioctl commands");
return -1;
}
- /* sort and merge the input operations */
- if (avrule_sort_operations(&rangehead))
+ /* sort and merge the input ioctls */
+ if (avrule_sort_ioctls(&rangehead))
return -1;
- if (avrule_merge_operations(&rangehead))
+ if (avrule_merge_ioctls(&rangehead))
return -1;
/* flip ranges if these are ommited*/
if (omit) {
- if (avrule_omit_operations(&rangehead))
+ if (avrule_omit_ioctls(&rangehead))
return -1;
}
@@ -1938,10 +1934,12 @@ int avrule_operation_ranges(struct av_operations_range_list **rangelist)
return 0;
}
-int define_te_avtab_operation_helper(int which, avrule_t ** rule)
+int define_te_avtab_xperms_helper(int which, avrule_t ** rule)
{
char *id;
class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
+ class_datum_t *cladatum;
+ perm_datum_t *perdatum = NULL;
ebitmap_t tclasses;
ebitmap_node_t *node;
avrule_t *avrule;
@@ -1959,7 +1957,7 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule)
avrule->line = policydb_lineno;
avrule->source_line = source_lineno;
avrule->source_filename = strdup(source_file);
- avrule->ops = NULL;
+ avrule->xperms = NULL;
if (!avrule->source_filename) {
yyerror("out of memory");
return -1;
@@ -1968,7 +1966,7 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule)
while ((id = queue_remove(id_queue))) {
if (set_types
(&avrule->stypes, id, &add,
- which == AVRULE_NEVERALLOW ? 1 : 0)) {
+ which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
ret = -1;
goto out;
}
@@ -1982,7 +1980,7 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule)
}
if (set_types
(&avrule->ttypes, id, &add,
- which == AVRULE_NEVERALLOW ? 1 : 0)) {
+ which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
ret = -1;
goto out;
}
@@ -1994,6 +1992,7 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule)
goto out;
perms = NULL;
+ id = queue_head(id_queue);
ebitmap_for_each_bit(&tclasses, node, i) {
if (!ebitmap_node_get_bit(node, i))
continue;
@@ -2011,6 +2010,29 @@ int define_te_avtab_operation_helper(int which, avrule_t ** rule)
if (tail)
tail->next = cur_perms;
tail = cur_perms;
+
+ cladatum = policydbp->class_val_to_struct[i];
+ perdatum = hashtab_search(cladatum->permissions.table, id);
+ if (!perdatum) {
+ if (cladatum->comdatum) {
+ perdatum = hashtab_search(cladatum->comdatum->
+ permissions.table,
+ id);
+ }
+ }
+ if (!perdatum) {
+ yyerror2("permission %s is not defined"
+ " for class %s", id,
+ policydbp->p_class_val_to_name[i]);
+ continue;
+ } else if (!is_perm_in_scope (id, policydbp->p_class_val_to_name[i])) {
+ yyerror2("permission %s of class %s is"
+ " not within scope", id,
+ policydbp->p_class_val_to_name[i]);
+ continue;
+ } else {
+ cur_perms->data |= 1U << (perdatum->s.value - 1);
+ }
}
ebitmap_destroy(&tclasses);
@@ -2023,95 +2045,102 @@ out:
}
/* index of the u32 containing the permission */
-#define OP_IDX(x) (x >> 5)
+#define XPERM_IDX(x) (x >> 5)
/* set bits 0 through x-1 within the u32 */
-#define OP_SETBITS(x) ((1 << (x & 0x1f)) - 1)
+#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
/* low value for this u32 */
-#define OP_LOW(x) (x << 5)
+#define XPERM_LOW(x) (x << 5)
/* high value for this u32 */
-#define OP_HIGH(x) (((x + 1) << 5) - 1)
-void avrule_operation_setrangebits(uint16_t low, uint16_t high, av_operations_t *ops)
+#define XPERM_HIGH(x) (((x + 1) << 5) - 1)
+void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
+ av_extended_perms_t *xperms)
{
unsigned int i;
uint16_t h = high + 1;
- /* for each u32 that this low-high range touches, set type permissions */
- for (i = OP_IDX(low); i <= OP_IDX(high); i++) {
+ /* for each u32 that this low-high range touches, set driver permissions */
+ for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
/* set all bits in u32 */
- if ((low <= OP_LOW(i)) && (high >= OP_HIGH(i)))
- ops->perms[i] |= ~0U;
+ if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+ xperms->perms[i] |= ~0U;
/* set low bits */
- else if ((low <= OP_LOW(i)) && (high < OP_HIGH(i)))
- ops->perms[i] |= OP_SETBITS(h);
+ else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
+ xperms->perms[i] |= XPERM_SETBITS(h);
/* set high bits */
- else if ((low > OP_LOW(i)) && (high >= OP_HIGH(i)))
- ops->perms[i] |= ~0U - OP_SETBITS(low);
+ else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+ xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
/* set middle bits */
- else if ((low > OP_LOW(i)) && (high <= OP_HIGH(i)))
- ops->perms[i] |= OP_SETBITS(h) - OP_SETBITS(low);
+ else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
+ xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
}
}
-int avrule_operation_used(av_operations_t *ops)
+int avrule_xperms_used(av_extended_perms_t *xperms)
{
unsigned int i;
- for (i = 0; i < sizeof(ops->perms)/sizeof(ops->perms[0]); i++) {
- if (ops->perms[i])
+ for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) {
+ if (xperms->perms[i])
return 1;
}
return 0;
}
-#define OP_TYPE(x) (x >> 8)
-#define OP_NUM(x) (x & 0xff)
-#define OP_CMD(type, num) ((type << 8) + num)
-int avrule_operation_partialtype(struct av_operations_range_list *rangelist,
- av_operations_t *complete_type,
- av_operations_t **operations)
+/*
+ * using definitions found in kernel document ioctl-number.txt
+ * The kernel components of an ioctl command are:
+ * dir, size, driver, and fucntion. Only the driver and function fields
+ * are considered here
+ */
+#define IOC_DRIV(x) (x >> 8)
+#define IOC_FUNC(x) (x & 0xff)
+#define IOC_CMD(driver, func) ((driver << 8) + func)
+int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist,
+ av_extended_perms_t *complete_driver,
+ av_extended_perms_t **extended_perms)
{
- struct av_operations_range_list *r;
- av_operations_t *ops;
+ struct av_ioctl_range_list *r;
+ av_extended_perms_t *xperms;
uint8_t low, high;
- ops = calloc(1, sizeof(av_operations_t));
- if (!ops) {
+ xperms = calloc(1, sizeof(av_extended_perms_t));
+ if (!xperms) {
yyerror("out of memory");
return - 1;
}
r = rangelist;
while(r) {
- low = OP_TYPE(r->range.low);
- high = OP_TYPE(r->range.high);
- if (complete_type) {
- if (!operation_perm_test(low, complete_type->perms))
- operation_perm_set(low, ops->perms);
- if (!operation_perm_test(high, complete_type->perms))
- operation_perm_set(high, ops->perms);
+ low = IOC_DRIV(r->range.low);
+ high = IOC_DRIV(r->range.high);
+ if (complete_driver) {
+ if (!xperm_test(low, complete_driver->perms))
+ xperm_set(low, xperms->perms);
+ if (!xperm_test(high, complete_driver->perms))
+ xperm_set(high, xperms->perms);
} else {
- operation_perm_set(low, ops->perms);
- operation_perm_set(high, ops->perms);
+ xperm_set(low, xperms->perms);
+ xperm_set(high, xperms->perms);
}
r = r->next;
}
- if (avrule_operation_used(ops)) {
- *operations = ops;
+ if (avrule_xperms_used(xperms)) {
+ *extended_perms = xperms;
} else {
- free(ops);
- *operations = NULL;
+ free(xperms);
+ *extended_perms = NULL;
}
return 0;
}
-int avrule_operation_completetype(struct av_operations_range_list *rangelist,
- av_operations_t **operations)
+int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist,
+ av_extended_perms_t **extended_perms)
{
- struct av_operations_range_list *r;
- av_operations_t *ops;
+ struct av_ioctl_range_list *r;
+ av_extended_perms_t *xperms;
uint16_t low, high;
- ops = calloc(1, sizeof(av_operations_t));
- if (!ops) {
+ xperms = calloc(1, sizeof(av_extended_perms_t));
+ if (!xperms) {
yyerror("out of memory");
return - 1;
}
@@ -2119,83 +2148,86 @@ int avrule_operation_completetype(struct av_operations_range_list *rangelist,
r = rangelist;
while(r) {
/*
- * Any type that has numbers 0x00 - 0xff is a complete type,
+ * Any driver code that has sequence 0x00 - 0xff is a complete code,
*
- * if command number = 0xff, then round high up to next type,
- * else 0x00 - 0xfe keep current type
+ * if command number = 0xff, then round high up to next code,
+ * else 0x00 - 0xfe keep current code
* of this range. temporarily u32 for the + 1
* to account for possible rollover before right shift
*/
- high = OP_TYPE((uint32_t) (r->range.high + 1));
- /* if 0x00 keep current type else 0x01 - 0xff round up to next type */
- low = OP_TYPE(r->range.low);
- if (OP_NUM(r->range.low))
+ high = IOC_DRIV((uint32_t) (r->range.high + 1));
+ /* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/
+ low = IOC_DRIV(r->range.low);
+ if (IOC_FUNC(r->range.low))
low++;
if (high > low)
- avrule_operation_setrangebits(low, high - 1, ops);
+ avrule_xperm_setrangebits(low, high - 1, xperms);
r = r->next;
}
- if (avrule_operation_used(ops)) {
- *operations = ops;
+ if (avrule_xperms_used(xperms)) {
+ xperms->driver = 0x00;
+ xperms->specified = AVRULE_XPERMS_IOCTLDRIVER;
+ *extended_perms = xperms;
} else {
- free(ops);
- *operations = NULL;
+ free(xperms);
+ *extended_perms = NULL;
}
return 0;
}
-int avrule_operation_num(struct av_operations_range_list *rangelist,
- av_operations_t **operations, unsigned int type)
+int avrule_ioctl_func(struct av_ioctl_range_list *rangelist,
+ av_extended_perms_t **extended_perms, unsigned int driver)
{
- struct av_operations_range_list *r;
- av_operations_t *ops;
+ struct av_ioctl_range_list *r;
+ av_extended_perms_t *xperms;
uint16_t low, high;
- *operations = NULL;
- ops = calloc(1, sizeof(av_operations_t));
- if (!ops) {
+ *extended_perms = NULL;
+ xperms = calloc(1, sizeof(av_extended_perms_t));
+ if (!xperms) {
yyerror("out of memory");
return - 1;
}
r = rangelist;
- /* for the passed in types, find the ranges that apply */
+ /* for the passed in driver code, find the ranges that apply */
while (r) {
low = r->range.low;
high = r->range.high;
- if ((type != OP_TYPE(low)) && (type != OP_TYPE(high))) {
+ if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) {
r = r->next;
continue;
}
- if (type == OP_TYPE(low)) {
- if (high > OP_CMD(type, 0xff))
- high = OP_CMD(type, 0xff);
+ if (driver == IOC_DRIV(low)) {
+ if (high > IOC_CMD(driver, 0xff))
+ high = IOC_CMD(driver, 0xff);
} else {
- if (low < OP_CMD(type, 0))
- low = OP_CMD(type, 0);
+ if (low < IOC_CMD(driver, 0))
+ low = IOC_CMD(driver, 0);
}
- low = OP_NUM(low);
- high = OP_NUM(high);
- avrule_operation_setrangebits(low, high, ops);
- ops->type = type;
+ low = IOC_FUNC(low);
+ high = IOC_FUNC(high);
+ avrule_xperm_setrangebits(low, high, xperms);
+ xperms->driver = driver;
+ xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
r = r->next;
}
- if (avrule_operation_used(ops)) {
- *operations = ops;
+ if (avrule_xperms_used(xperms)) {
+ *extended_perms = xperms;
} else {
- free(ops);
- *operations = NULL;
+ free(xperms);
+ *extended_perms = NULL;
}
return 0;
}
-void avrule_operation_freeranges(struct av_operations_range_list *rangelist)
+void avrule_ioctl_freeranges(struct av_ioctl_range_list *rangelist)
{
- struct av_operations_range_list *r, *tmp;
+ struct av_ioctl_range_list *r, *tmp;
r = rangelist;
while (r) {
tmp = r;
@@ -2204,12 +2236,12 @@ void avrule_operation_freeranges(struct av_operations_range_list *rangelist)
}
}
-unsigned int operation_for_each_bit(unsigned int *bit, av_operations_t *ops)
+unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
{
unsigned int i;
- for (i = *bit; i < sizeof(ops->perms)*8; i++) {
- if (operation_perm_test(i,ops->perms)) {
- operation_perm_clear(i, ops->perms);
+ for (i = *bit; i < sizeof(xperms->perms)*8; i++) {
+ if (xperm_test(i,xperms->perms)) {
+ xperm_clear(i, xperms->perms);
*bit = i;
return 1;
}
@@ -2236,6 +2268,10 @@ int avrule_cpy(avrule_t *dest, avrule_t *src)
}
dest->line = src->line;
dest->source_filename = strdup(source_file);
+ if (!dest->source_filename) {
+ yyerror("out of memory");
+ return -1;
+ }
dest->source_line = src->source_line;
/* increment through the class perms and copy over */
@@ -2261,35 +2297,22 @@ int avrule_cpy(avrule_t *dest, avrule_t *src)
return 0;
}
-int define_te_avtab_operation(int which)
+int define_te_avtab_ioctl(avrule_t *avrule_template)
{
- char *id;
- avrule_t *avrule_template;
avrule_t *avrule;
- struct av_operations_range_list *rangelist;
- av_operations_t *complete_type, *partial_type, *ops;
+ struct av_ioctl_range_list *rangelist;
+ av_extended_perms_t *complete_driver, *partial_driver, *xperms;
unsigned int i;
- if (pass == 1) {
- for (i = 0; i < 4; i++) {
- while ((id = queue_remove(id_queue)))
- free(id);
- }
- return 0;
- }
-
- /* populate avrule template with source/target/tclass */
- if (define_te_avtab_operation_helper(which, &avrule_template))
- return -1;
- /* organize operation ranges */
- if (avrule_operation_ranges(&rangelist))
+ /* organize ioctl ranges */
+ if (avrule_ioctl_ranges(&rangelist))
return -1;
- /* create rule for ioctl operation types that are entirely enabled */
- if (avrule_operation_completetype(rangelist, &complete_type))
+ /* create rule for ioctl driver types that are entirely enabled */
+ if (avrule_ioctl_completedriver(rangelist, &complete_driver))
return -1;
- if (complete_type) {
+ if (complete_driver) {
avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
if (!avrule) {
yyerror("out of memory");
@@ -2297,31 +2320,28 @@ int define_te_avtab_operation(int which)
}
if (avrule_cpy(avrule, avrule_template))
return -1;
- avrule->ops = complete_type;
- if (which == AVRULE_OPNUM_ALLOWED)
- avrule->specified = AVRULE_OPTYPE_ALLOWED;
- else if (which == AVRULE_OPNUM_AUDITALLOW)
- avrule->specified = AVRULE_OPTYPE_AUDITALLOW;
- else if (which == AVRULE_OPNUM_DONTAUDIT)
- avrule->specified = AVRULE_OPTYPE_DONTAUDIT;
-
+ avrule->xperms = complete_driver;
append_avrule(avrule);
}
- /* flag ioctl types that are partially enabled */
- if (avrule_operation_partialtype(rangelist, complete_type, &partial_type))
+ /* flag ioctl driver codes that are partially enabled */
+ if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver))
return -1;
- if (!partial_type || !avrule_operation_used(partial_type))
+ if (!partial_driver || !avrule_xperms_used(partial_driver))
goto done;
- /* create rule for each partially enabled type */
+ /*
+ * create rule for each partially used driver codes
+ * "partially used" meaning that the code number e.g. socket 0x89
+ * has some permission bits set and others not set.
+ */
i = 0;
- while (operation_for_each_bit(&i, partial_type)) {
- if (avrule_operation_num(rangelist, &ops, i))
+ while (xperms_for_each_bit(&i, partial_driver)) {
+ if (avrule_ioctl_func(rangelist, &xperms, i))
return -1;
- if (ops) {
+ if (xperms) {
avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
if (!avrule) {
yyerror("out of memory");
@@ -2329,18 +2349,48 @@ int define_te_avtab_operation(int which)
}
if (avrule_cpy(avrule, avrule_template))
return -1;
- avrule->ops = ops;
+ avrule->xperms = xperms;
append_avrule(avrule);
}
}
done:
- if (partial_type)
- free(partial_type);
+ if (partial_driver)
+ free(partial_driver);
return 0;
}
+int define_te_avtab_extended_perms(int which)
+{
+ char *id;
+ unsigned int i;
+ avrule_t *avrule_template;
+
+ if (pass == 1) {
+ for (i = 0; i < 4; i++) {
+ while ((id = queue_remove(id_queue)))
+ free(id);
+ }
+ return 0;
+ }
+
+ /* populate avrule template with source/target/tclass */
+ if (define_te_avtab_xperms_helper(which, &avrule_template))
+ return -1;
+
+ id = queue_remove(id_queue);
+ if (strcmp(id,"ioctl") == 0) {
+ if (define_te_avtab_ioctl(avrule_template))
+ return -1;
+ free(id);
+ } else {
+ yyerror("only ioctl extended permissions are supported");
+ return -1;
+ }
+ return 0;
+}
+
int define_te_avtab_helper(int which, avrule_t ** rule)
{
char *id;
@@ -2365,7 +2415,7 @@ int define_te_avtab_helper(int which, avrule_t ** rule)
avrule->line = policydb_lineno;
avrule->source_line = source_lineno;
avrule->source_filename = strdup(source_file);
- avrule->ops = NULL;
+ avrule->xperms = NULL;
if (!avrule->source_filename) {
yyerror("out of memory");
return -1;
@@ -2745,7 +2795,7 @@ static int dominate_role_recheck(hashtab_key_t key __attribute__ ((unused)),
role_datum_t *rdp = (role_datum_t *) arg;
role_datum_t *rdatum = (role_datum_t *) datum;
ebitmap_node_t *node;
- int i;
+ uint32_t i;
/* Don't bother to process against self role */
if (rdatum->s.value == rdp->s.value)
@@ -3291,8 +3341,14 @@ int define_filename_trans(void)
append_filename_trans(ftr);
ftr->name = strdup(name);
- ftr->stypes = stypes;
- ftr->ttypes = ttypes;
+ if (type_set_cpy(&ftr->stypes, &stypes)) {
+ yyerror("out of memory");
+ goto bad;
+ }
+ if (type_set_cpy(&ftr->ttypes, &ttypes)) {
+ yyerror("out of memory");
+ goto bad;
+ }
ftr->tclass = c + 1;
ftr->otype = otype;
}
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 43c7c088..964baae0 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -58,7 +58,7 @@ int define_roleattribute(void);
int define_filename_trans(void);
int define_sens(void);
int define_te_avtab(int which);
-int define_te_avtab_operation(int which);
+int define_te_avtab_extended_perms(int which);
int define_typealias(void);
int define_typeattribute(void);
int define_typebounds(void);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 059b7b87..3b6a2f86 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -126,6 +126,10 @@ typedef int (* require_func_t)(int pass);
%token AUDITALLOW
%token AUDITDENY
%token DONTAUDIT
+%token ALLOWXPERM
+%token AUDITALLOWXPERM
+%token DONTAUDITXPERM
+%token NEVERALLOWXPERM
%token SOURCE
%token TARGET
%token SAMEUSER
@@ -457,9 +461,10 @@ te_avtab_def : allow_def
| auditdeny_def
| dontaudit_def
| neverallow_def
- | operation_allow_def
- | operation_auditallow_def
- | operation_dontaudit_def
+ | xperm_allow_def
+ | xperm_auditallow_def
+ | xperm_dontaudit_def
+ | xperm_neverallow_def
;
allow_def : ALLOW names names ':' names names ';'
{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
@@ -476,14 +481,17 @@ dontaudit_def : DONTAUDIT names names ':' names names ';'
neverallow_def : NEVERALLOW names names ':' names names ';'
{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
;
-operation_allow_def : ALLOW names names ':' names operations ';'
- {if (define_te_avtab_operation(AVRULE_OPNUM_ALLOWED)) return -1; }
+xperm_allow_def : ALLOWXPERM names names ':' names identifier xperms ';'
+ {if (define_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED)) return -1; }
;
-operation_auditallow_def: AUDITALLOW names names ':' names operations ';'
- {if (define_te_avtab_operation(AVRULE_OPNUM_AUDITALLOW)) return -1; }
+xperm_auditallow_def : AUDITALLOWXPERM names names ':' names identifier xperms ';'
+ {if (define_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW)) return -1; }
;
-operation_dontaudit_def : DONTAUDIT names names ':' names operations ';'
- {if (define_te_avtab_operation(AVRULE_OPNUM_DONTAUDIT)) return -1; }
+xperm_dontaudit_def : DONTAUDITXPERM names names ':' names identifier xperms ';'
+ {if (define_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT)) return -1; }
+ ;
+xperm_neverallow_def : NEVERALLOWXPERM names names ':' names identifier xperms ';'
+ {if (define_te_avtab_extended_perms(AVRULE_XPERMS_NEVERALLOW)) return -1; }
;
attribute_role_def : ATTRIBUTE_ROLE identifier ';'
{if (define_attrib_role()) return -1; }
@@ -749,26 +757,26 @@ genfs_context_def : GENFSCON filesystem path '-' identifier security_context_def
ipv4_addr_def : IPV4_ADDR
{ if (insert_id(yytext,0)) return -1; }
;
-operations : operation
+xperms : xperm
{ if (insert_separator(0)) return -1; }
- | nested_operation_set
+ | nested_xperm_set
{ if (insert_separator(0)) return -1; }
- | tilde operation
+ | tilde xperm
{ if (insert_id("~", 0)) return -1; }
- | tilde nested_operation_set
+ | tilde nested_xperm_set
{ if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
;
-nested_operation_set : '{' nested_operation_list '}'
+nested_xperm_set : '{' nested_xperm_list '}'
;
-nested_operation_list : nested_operation_element
- | nested_operation_list nested_operation_element
+nested_xperm_list : nested_xperm_element
+ | nested_xperm_list nested_xperm_element
;
-nested_operation_element: operation '-' { if (insert_id("-", 0)) return -1; } operation
- | operation
- | nested_operation_set
+nested_xperm_element: xperm '-' { if (insert_id("-", 0)) return -1; } xperm
+ | xperm
+ | nested_xperm_set
;
-operation : number
+xperm : number
{ if (insert_id(yytext,0)) return -1; }
;
security_context_def : identifier ':' identifier ':' identifier opt_mls_range_def
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 108edbc3..22da3381 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -142,6 +142,14 @@ AUDITDENY |
auditdeny { return(AUDITDENY); }
DONTAUDIT |
dontaudit { return(DONTAUDIT); }
+ALLOWXPERM |
+allowxperm { return(ALLOWXPERM); }
+AUDITALLOWXPERM |
+auditallowxperm { return(AUDITALLOWXPERM); }
+DONTAUDITXPERM |
+dontauditxperm { return(DONTAUDITXPERM); }
+NEVERALLOWXPERM |
+neverallowxperm { return(NEVERALLOWXPERM); }
SOURCE |
source { return(SOURCE); }
TARGET |
diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
index 157361a4..86f56882 100644
--- a/checkpolicy/test/dispol.c
+++ b/checkpolicy/test/dispol.c
@@ -54,56 +54,6 @@ int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p,
return 0;
}
-#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
-#define next_bit_in_range(i, p) \
- ((i + 1 < sizeof(p)*8) && operation_perm_test((i + 1), p))
-
-int render_operations(avtab_operations_t *ops, avtab_key_t * key, FILE * fp)
-{
- uint16_t value;
- uint16_t low_bit;
- uint16_t low_value;
- unsigned int bit;
- unsigned int in_range = 0;
-
- fprintf(fp, "{ ");
- for (bit = 0; bit < sizeof(ops->perms)*8; bit++) {
- if (!operation_perm_test(bit, ops->perms))
- continue;
-
- if (in_range && next_bit_in_range(bit, ops->perms)) {
- /* continue until high value found */
- continue;
- } else if (next_bit_in_range(bit, ops->perms)) {
- /* low value */
- low_bit = bit;
- in_range = 1;
- continue;
- }
-
- if (key->specified & AVTAB_OPNUM) {
- value = ops->type<<8 | bit;
- low_value = ops->type<<8 | low_bit;
- if (in_range)
- fprintf(fp, "0x%hx-0x%hx ", low_value, value);
- else
- fprintf(fp, "0x%hx ", value);
- } else if (key->specified & AVTAB_OPTYPE) {
- value = bit << 8;
- low_value = low_bit << 8;
- if (in_range)
- fprintf(fp, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
- else
- fprintf(fp, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
-
- }
- if (in_range)
- in_range = 0;
- }
- fprintf(fp, "}");
- return 0;
-}
-
int render_type(uint32_t type, policydb_t * p, FILE * fp)
{
fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
@@ -197,16 +147,15 @@ int render_av_rule(avtab_key_t * key, avtab_datum_t * datum, uint32_t what,
render_type(datum->data, p, fp);
fprintf(fp, ";\n");
}
- } else if (key->specified & AVTAB_OP) {
- if (key->specified & (AVTAB_OPNUM_ALLOWED|AVTAB_OPTYPE_ALLOWED))
- fprintf(fp, "allow ");
- else if (key->specified & (AVTAB_OPNUM_AUDITALLOW|AVTAB_OPTYPE_AUDITALLOW))
- fprintf(fp, "auditallow ");
- else if (key->specified & (AVTAB_OPNUM_DONTAUDIT|AVTAB_OPTYPE_DONTAUDIT))
- fprintf(fp, "dontaudit ");
+ } else if (key->specified & AVTAB_XPERMS) {
+ if (key->specified & AVTAB_XPERMS_ALLOWED)
+ fprintf(fp, "allowxperm ");
+ else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
+ fprintf(fp, "auditallowxperm ");
+ else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
+ fprintf(fp, "dontauditxperm ");
render_key(key, p, fp);
- render_operations(datum->ops, key, fp);
- fprintf(fp, ";\n");
+ fprintf(fp, "%s;\n", sepol_extended_perms_to_string(datum->xperms));
} else {
fprintf(fp, " ERROR: no valid rule type specified\n");
return -1;
diff --git a/libselinux/ChangeLog b/libselinux/ChangeLog
index 6a010b73..3501428b 100644
--- a/libselinux/ChangeLog
+++ b/libselinux/ChangeLog
@@ -1,3 +1,30 @@
+ * label_file: fix memory leaks and uninitialized jump, from William Roberts.
+ * Replace selabel_digest hash function, from Richard Haines.
+ * Fix selabel_open(3) services if no digest requested, from Richard Haines.
+ * Add selabel_digest function, from Richard Haines.
+ * Fix parallel build with swig python, from Jason Zaman.
+ * Flush the class/perm string mapping cache on policy reload, from Stephen Smalley.
+ * Fix restorecon when path has no context, from Nir Soffer.
+ * Free memory when processing media and x specfiles, from Richard Haines.
+ * Fix mmap memory release for file labeling, from Richard Haines.
+ * Add explicit dependency for pywrap on selinux.py, from Wenzong Fan.
+ * Add policy context validation to sefcontext_compile, from Richard Haines.
+ * Do not treat an empty file_contexts(.local) as an error, from Stephen Smalley.
+ * Fail hard on invalid property_contexts entries, from Stephen Smalley.
+ * Fail hard on invalid file_contexts entries, from Stephen Smalley.
+ * Support context validation on file_contexts.bin, from Stephen Smalley.
+ * Test for file_contexts.bin format by magic number, from Stephen Smalley.
+ * Add selabel_cmp interface and label_file backend, from Stephen Smalley.
+ * Support specifying file_contexts.bin file path, from Stephen Smalley.
+ * Support file_contexts.bin without file_contexts, from Stephen Smalley.
+ * Simplify procattr cache, from Stephen Smalley.
+ * Use /proc/thread-self when available, from Stephen Smalley.
+ * Add const to selinux_opt for label backends, from Richard Haines.
+ * Fix binary file labels for regexes with metachars, from Richard Haines.
+ * Fix file labels for regexes with metachars, from Jeff Vander Stoep.
+ * Fix if file_contexts not '\n' terminated, from Richard Haines.
+ * Enhance file context support, from Richard Haines.
+ * Fix property processing and cleanup formatting, from Richard Haines.
* Add read_spec_entries function to replace sscanf, from Richard Haines.
* Support consistent mode size for bin files, from Richard Haines.
* Expunge remaining references to flask.h and av_permissions.h, from Stephen Smalley.
diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h
index 7a94a925..f0b1e10d 100644
--- a/libselinux/include/selinux/label.h
+++ b/libselinux/include/selinux/label.h
@@ -49,8 +49,10 @@ struct selabel_handle;
#define SELABEL_OPT_PATH 3
/* select a subset of the search space as an optimization (file backend) */
#define SELABEL_OPT_SUBSET 4
+/* require a hash calculation on spec files */
+#define SELABEL_OPT_DIGEST 5
/* total number of options */
-#define SELABEL_NOPT 5
+#define SELABEL_NOPT 6
/*
* Label operations
@@ -69,7 +71,8 @@ struct selabel_handle;
* @errno set on failure.
*/
struct selabel_handle *selabel_open(unsigned int backend,
- struct selinux_opt *opts, unsigned nopts);
+ const struct selinux_opt *opts,
+ unsigned nopts);
/**
* selabel_close - Close a labeling handle.
@@ -106,6 +109,43 @@ int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
const char *key, const char **aliases, int type);
/**
+ * selabel_digest - Retrieve the SHA1 digest and the list of specfiles used to
+ * generate the digest. The SELABEL_OPT_DIGEST option must
+ * be set in selabel_open() to initiate the digest generation.
+ * @handle: specifies backend instance to query
+ * @digest: returns a pointer to the SHA1 digest.
+ * @digest_len: returns length of digest in bytes.
+ * @specfiles: a list of specfiles used in the SHA1 digest generation.
+ * The list is NULL terminated and will hold @num_specfiles entries.
+ * @num_specfiles: number of specfiles in the list.
+ *
+ * Return %0 on success, -%1 with @errno set on failure.
+ */
+int selabel_digest(struct selabel_handle *rec,
+ unsigned char **digest, size_t *digest_len,
+ char ***specfiles, size_t *num_specfiles);
+
+enum selabel_cmp_result {
+ SELABEL_SUBSET,
+ SELABEL_EQUAL,
+ SELABEL_SUPERSET,
+ SELABEL_INCOMPARABLE
+};
+
+/**
+ * selabel_cmp - Compare two label configurations.
+ * @h1: handle for the first label configuration
+ * @h2: handle for the first label configuration
+ *
+ * Compare two label configurations.
+ * Return %SELABEL_SUBSET if @h1 is a subset of @h2, %SELABEL_EQUAL
+ * if @h1 is identical to @h2, %SELABEL_SUPERSET if @h1 is a superset
+ * of @h2, and %SELABEL_INCOMPARABLE if @h1 and @h2 are incomparable.
+ */
+enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
+ struct selabel_handle *h2);
+
+/**
* selabel_stats - log labeling operation statistics.
* @handle: specifies backend instance to query
*
diff --git a/libselinux/man/man3/selabel_digest.3 b/libselinux/man/man3/selabel_digest.3
new file mode 100644
index 00000000..56a008f0
--- /dev/null
+++ b/libselinux/man/man3/selabel_digest.3
@@ -0,0 +1,61 @@
+.TH "selabel_digest" "3" "16 Sept 2015" "" "SELinux API documentation"
+.SH "NAME"
+selabel_digest \- Return digest of specfiles and list of files used
+.
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.br
+.B #include <selinux/label.h>
+.sp
+.BI "int selabel_digest(struct selabel_handle *" hnd ,
+.in +\w'int selabel_digest('u
+.BI "unsigned char **" digest ,
+.BI "size_t *" digest_len ,
+.br
+.BI "char ***" specfiles,
+.BI "size_t *" num_specfiles ");"
+.in
+.
+.SH "DESCRIPTION"
+.BR selabel_digest ()
+performs an operation on the handle
+.IR hnd ,
+returning the results of the SHA1 digest pointed to by
+.IR digest ,
+whose length will be
+.IR digest_len .
+The list of specfiles used in the SHA1 digest calculation is returned in
+.I specfiles
+with the number of entries in
+.IR num_specfiles .
+.sp
+To enable
+.BR selabel_digest ()
+to return this information the
+.B SELABEL_OPT_DIGEST
+option must be enable in
+.BR selabel_open (3).
+.sp
+The result of
+.BR selabel_digest ()
+must not be used after
+.BR selabel_close (3).
+.
+.SH "RETURN VALUE"
+On success, zero is returned. On error, \-1 is returned and
+.I errno
+is set appropriately.
+.
+.SH "ERRORS"
+.TP
+.B EINVAL
+No digest available (returned if
+.B SELABEL_OPT_DIGEST
+option not enabled).
+.TP
+.B ENOMEM
+An attempt to allocate memory failed.
+.
+.SH "SEE ALSO"
+.BR selabel_open (3),
+.BR selinux (8)
diff --git a/libselinux/man/man3/selabel_open.3 b/libselinux/man/man3/selabel_open.3
index 00f28287..971ebc1a 100644
--- a/libselinux/man/man3/selabel_open.3
+++ b/libselinux/man/man3/selabel_open.3
@@ -12,7 +12,7 @@ selabel_open, selabel_close \- userspace SELinux labeling interface
.sp
.BI "struct selabel_handle *selabel_open(int " backend ,
.in +\w'struct selabel_handle *selabel_open('u
-.BI "struct selinux_opt *" options ,
+.BI "const struct selinux_opt *" options ,
.br
.BI "unsigned " nopt ");"
.in
@@ -67,6 +67,11 @@ A non-null value for this option enables context validation. By default,
is used; a custom validation function can be provided via
.BR selinux_set_callback (3).
Note that an invalid context may not be treated as an error unless it is actually encountered during a lookup operation.
+.TP
+.B SELABEL_OPT_DIGEST
+A non-null value for this option enables the generation of an SHA1 digest of
+the spec files loaded as described in
+.BR selabel_digest (3)
.
.SH "BACKENDS"
.TP
diff --git a/libselinux/man/man8/sefcontext_compile.8 b/libselinux/man/man8/sefcontext_compile.8
index 810d22ac..b77ff3a1 100644
--- a/libselinux/man/man8/sefcontext_compile.8
+++ b/libselinux/man/man8/sefcontext_compile.8
@@ -1,15 +1,67 @@
-.TH "sefcontext_compile" "8" "27 Jun 2013" "dwalsh@redhat.com" "SELinux Command Line documentation"
+.TH "sefcontext_compile" "8" "12 Aug 2015" "dwalsh@redhat.com" "SELinux Command Line documentation"
.SH "NAME"
sefcontext_compile \- compile file context regular expression files
.
.SH "SYNOPSIS"
-.B sefcontext_compile inputfile
+.B sefcontext_compile
+.RB [ \-o
+.IR outputfile ]
+.RB [ \-p
+.IR policyfile ]
+.I inputfile
.
.SH "DESCRIPTION"
-sefcontext_compile is used libsemanage to compile file context regular expressions into prce format. sefcontext_compile writes the compiled prce file with the .bin suffix appended "inputfile".bin. This compiled file is used by libselinux file labeling functions.
+.B sefcontext_compile
+is used to compile file context regular expressions into
+.BR prce (3)
+format.
+.sp
+The compiled file is used by libselinux file labeling functions.
+.sp
+By default
+.B sefcontext_compile
+writes the compiled prce file with the
+.B .bin
+suffix appended (e.g. \fIinputfile\fB.bin\fR).
+.SH OPTIONS
+.TP
+.B \-o
+Specify an
+.I outputfile
+that must be a fully qualified file name as the
+.B .bin
+suffix is not automatically added.
+.TP
+.B \-p
+Specify a binary
+.I policyfile
+that will be used to validate the context entries in the
+.I inputfile
+.br
+If an invalid context is found the pcre formatted file will not be written and
+an error will be returned.
-.SH "EXAMPLE"
+.SH "RETURN VALUE"
+On error -1 is returned. On success 0 is returned.
+
+.SH "EXAMPLES"
+.B Example 1:
+.br
sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts
+.sp
+Results in the following file being generated:
+.RS
+/etc/selinux/targeted/contexts/files/file_contexts.bin
+.RE
+.sp
+.B Example 2:
+.br
+sefcontext_compile -o new_fc.bin /etc/selinux/targeted/contexts/files/file_contexts
+.sp
+Results in the following file being generated in the cwd:
+.RS
+new_fc.bin
+.RE
.
.SH AUTHOR
Dan Walsh, <dwalsh@redhat.com>
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index ac25c1fa..feab5612 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -29,11 +29,12 @@ LIBPC=libselinux.pc
SWIGIF= selinuxswig_python.i selinuxswig_python_exception.i
SWIGRUBYIF= selinuxswig_ruby.i
SWIGCOUT= selinuxswig_wrap.c
+SWIGPYOUT= selinux.py
SWIGRUBYCOUT= selinuxswig_ruby_wrap.c
SWIGLOBJ:= $(patsubst %.c,$(PYPREFIX)%.lo,$(SWIGCOUT))
SWIGRUBYLOBJ:= $(patsubst %.c,%.lo,$(SWIGRUBYCOUT))
SWIGSO=$(PYPREFIX)_selinux.so
-SWIGFILES=$(SWIGSO) selinux.py
+SWIGFILES=$(SWIGSO) $(SWIGPYOUT)
SWIGRUBYSO=$(RUBYPREFIX)_selinux.so
LIBSO=$(TARGET).$(LIBVERSION)
AUDIT2WHYLOBJ=$(PYPREFIX)audit2why.lo
@@ -90,7 +91,7 @@ SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./
all: $(LIBA) $(LIBSO) $(LIBPC)
-pywrap: all $(SWIGSO) $(AUDIT2WHYSO)
+pywrap: all $(SWIGFILES) $(AUDIT2WHYSO)
rubywrap: all $(SWIGRUBYSO)
@@ -135,6 +136,8 @@ $(AUDIT2WHYSO): $(AUDIT2WHYLOBJ)
$(SWIGCOUT): $(SWIGIF)
$(SWIG) $<
+$(SWIGPYOUT): $(SWIGCOUT)
+
$(SWIGRUBYCOUT): $(SWIGRUBYIF)
$(SWIGRUBY) $<
@@ -154,7 +157,7 @@ install-pywrap: pywrap
test -d $(PYLIBDIR)/site-packages/selinux || install -m 755 -d $(PYLIBDIR)/site-packages/selinux
install -m 755 $(SWIGSO) $(PYLIBDIR)/site-packages/selinux/_selinux.so
install -m 755 $(AUDIT2WHYSO) $(PYLIBDIR)/site-packages/selinux/audit2why.so
- install -m 644 selinux.py $(PYLIBDIR)/site-packages/selinux/__init__.py
+ install -m 644 $(SWIGPYOUT) $(PYLIBDIR)/site-packages/selinux/__init__.py
install-rubywrap: rubywrap
test -d $(RUBYINSTALL) || install -m 755 -d $(RUBYINSTALL)
diff --git a/libselinux/src/checkAccess.c b/libselinux/src/checkAccess.c
index 29be16ec..8de57477 100644
--- a/libselinux/src/checkAccess.c
+++ b/libselinux/src/checkAccess.c
@@ -10,11 +10,26 @@
static pthread_once_t once = PTHREAD_ONCE_INIT;
static int selinux_enabled;
+static int avc_reset_callback(uint32_t event __attribute__((unused)),
+ security_id_t ssid __attribute__((unused)),
+ security_id_t tsid __attribute__((unused)),
+ security_class_t tclass __attribute__((unused)),
+ access_vector_t perms __attribute__((unused)),
+ access_vector_t *out_retained __attribute__((unused)))
+{
+ flush_class_cache();
+ return 0;
+}
+
static void avc_init_once(void)
{
selinux_enabled = is_selinux_enabled();
- if (selinux_enabled == 1)
- avc_open(NULL, 0);
+ if (selinux_enabled == 1) {
+ if (avc_open(NULL, 0))
+ return;
+ avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET,
+ 0, 0, 0, 0);
+ }
}
int selinux_check_access(const char *scon, const char *tcon, const char *class, const char *perm, void *aux) {
@@ -33,9 +48,11 @@ int selinux_check_access(const char *scon, const char *tcon, const char *class,
if (rc < 0)
return rc;
- rc = avc_context_to_sid(tcon, &tcon_id);
- if (rc < 0)
- return rc;
+ rc = avc_context_to_sid(tcon, &tcon_id);
+ if (rc < 0)
+ return rc;
+
+ (void) avc_netlink_check_nb();
sclass = string_to_security_class(class);
if (sclass == 0) {
diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index 759a3fa6..963bfcbf 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <selinux/selinux.h>
#include "callbacks.h"
#include "label_internal.h"
@@ -17,7 +18,8 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
typedef int (*selabel_initfunc)(struct selabel_handle *rec,
- struct selinux_opt *opts, unsigned nopts);
+ const struct selinux_opt *opts,
+ unsigned nopts);
static selabel_initfunc initfuncs[] = {
&selabel_file_init,
@@ -64,15 +66,21 @@ static char *selabel_sub(struct selabel_sub *ptr, const char *src)
return NULL;
}
-struct selabel_sub *selabel_subs_init(const char *path, struct selabel_sub *list)
+struct selabel_sub *selabel_subs_init(const char *path,
+ struct selabel_sub *list,
+ struct selabel_digest *digest)
{
char buf[1024];
FILE *cfg = fopen(path, "r");
- struct selabel_sub *sub;
+ struct selabel_sub *sub = NULL;
+ struct stat sb;
if (!cfg)
return list;
+ if (fstat(fileno(cfg), &sb) < 0)
+ return list;
+
while (fgets_unlocked(buf, sizeof(buf) - 1, cfg)) {
char *ptr = NULL;
char *src = buf;
@@ -114,6 +122,10 @@ struct selabel_sub *selabel_subs_init(const char *path, struct selabel_sub *list
sub->next = list;
list = sub;
}
+
+ if (digest_add_specfile(digest, cfg, NULL, sb.st_size, path) < 0)
+ goto err;
+
out:
fclose(cfg);
return list;
@@ -124,11 +136,63 @@ err:
goto out;
}
+static inline struct selabel_digest *selabel_is_digest_set
+ (const struct selinux_opt *opts,
+ unsigned n,
+ struct selabel_digest *entry)
+{
+ struct selabel_digest *digest = NULL;
+
+ while (n--) {
+ if (opts[n].type == SELABEL_OPT_DIGEST &&
+ opts[n].value == (char *)1) {
+ digest = calloc(1, sizeof(*digest));
+ if (!digest)
+ goto err;
+
+ digest->digest = calloc(1, DIGEST_SPECFILE_SIZE + 1);
+ if (!digest->digest)
+ goto err;
+
+ digest->specfile_list = calloc(DIGEST_FILES_MAX,
+ sizeof(char *));
+ if (!digest->specfile_list)
+ goto err;
+
+ entry = digest;
+ return entry;
+ }
+ }
+ return NULL;
+
+err:
+ free(digest->digest);
+ free(digest->specfile_list);
+ free(digest);
+ return NULL;
+}
+
+static void selabel_digest_fini(struct selabel_digest *ptr)
+{
+ int i;
+
+ free(ptr->digest);
+ free(ptr->hashbuf);
+
+ if (ptr->specfile_list) {
+ for (i = 0; ptr->specfile_list[i]; i++)
+ free(ptr->specfile_list[i]);
+ free(ptr->specfile_list);
+ }
+ free(ptr);
+}
+
/*
* Validation functions
*/
-static inline int selabel_is_validate_set(struct selinux_opt *opts, unsigned n)
+static inline int selabel_is_validate_set(const struct selinux_opt *opts,
+ unsigned n)
{
while (n--)
if (opts[n].type == SELABEL_OPT_VALIDATE)
@@ -251,7 +315,8 @@ selabel_lookup_bm_common(struct selabel_handle *rec, int translating,
*/
struct selabel_handle *selabel_open(unsigned int backend,
- struct selinux_opt *opts, unsigned nopts)
+ const struct selinux_opt *opts,
+ unsigned nopts)
{
struct selabel_handle *rec = NULL;
@@ -270,8 +335,10 @@ struct selabel_handle *selabel_open(unsigned int backend,
rec->subs = NULL;
rec->dist_subs = NULL;
+ rec->digest = selabel_is_digest_set(opts, nopts, rec->digest);
if ((*initfuncs[backend])(rec, opts, nopts)) {
+ free(rec->spec_file);
free(rec);
rec = NULL;
}
@@ -366,10 +433,37 @@ int selabel_lookup_best_match_raw(struct selabel_handle *rec, char **con,
return *con ? 0 : -1;
}
+enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
+ struct selabel_handle *h2)
+{
+ if (!h1->func_cmp || h1->func_cmp != h2->func_cmp)
+ return SELABEL_INCOMPARABLE;
+
+ return h1->func_cmp(h1, h2);
+}
+
+int selabel_digest(struct selabel_handle *rec,
+ unsigned char **digest, size_t *digest_len,
+ char ***specfiles, size_t *num_specfiles)
+{
+ if (!rec->digest) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *digest = rec->digest->digest;
+ *digest_len = DIGEST_SPECFILE_SIZE;
+ *specfiles = rec->digest->specfile_list;
+ *num_specfiles = rec->digest->specfile_cnt;
+ return 0;
+}
+
void selabel_close(struct selabel_handle *rec)
{
selabel_subs_fini(rec->subs);
selabel_subs_fini(rec->dist_subs);
+ if (rec->digest)
+ selabel_digest_fini(rec->digest);
rec->func_close(rec);
free(rec->spec_file);
free(rec);
diff --git a/libselinux/src/label_android_property.c b/libselinux/src/label_android_property.c
index dadb1602..712eecba 100644
--- a/libselinux/src/label_android_property.c
+++ b/libselinux/src/label_android_property.c
@@ -1,5 +1,5 @@
/*
- * Property Service contexts backend for labeling Android
+ * Property Service contexts backend for labeling Android
* property keys
*/
@@ -16,7 +16,7 @@
/* A property security context specification. */
typedef struct spec {
struct selabel_lookup_rec lr; /* holds contexts for lookup result */
- char *property_key; /* property key string */
+ char *property_key; /* property key string */
} spec_t;
/* Our stored configuration */
@@ -56,21 +56,23 @@ static int nodups_specs(struct saved_data *data, const char *path)
for (ii = 0; ii < data->nspec; ii++) {
curr_spec = &spec_arr[ii];
for (jj = ii + 1; jj < data->nspec; jj++) {
- if (!strcmp(spec_arr[jj].property_key, curr_spec->property_key)) {
+ if (!strcmp(spec_arr[jj].property_key,
+ curr_spec->property_key)) {
rc = -1;
errno = EINVAL;
- if (strcmp(spec_arr[jj].lr.ctx_raw, curr_spec->lr.ctx_raw)) {
- selinux_log(SELINUX_ERROR,
- "%s: Multiple different specifications for %s (%s and %s).\n",
- path,
- curr_spec->property_key,
- spec_arr[jj].lr.ctx_raw,
- curr_spec->lr.ctx_raw);
+ if (strcmp(spec_arr[jj].lr.ctx_raw,
+ curr_spec->lr.ctx_raw)) {
+ selinux_log
+ (SELINUX_ERROR,
+ "%s: Multiple different specifications for %s (%s and %s).\n",
+ path, curr_spec->property_key,
+ spec_arr[jj].lr.ctx_raw,
+ curr_spec->lr.ctx_raw);
} else {
- selinux_log(SELINUX_ERROR,
- "%s: Multiple same specifications for %s.\n",
- path,
- curr_spec->property_key);
+ selinux_log
+ (SELINUX_ERROR,
+ "%s: Multiple same specifications for %s.\n",
+ path, curr_spec->property_key);
}
}
}
@@ -92,36 +94,29 @@ static int process_line(struct selabel_handle *rec,
if (items <= 0)
return items;
if (items != 2) {
- selinux_log(SELINUX_WARNING,
- "%s: line %u is missing fields, skipping\n", path,
+ selinux_log(SELINUX_ERROR,
+ "%s: line %u is missing fields\n", path,
lineno);
- return 0;
+ free(prop);
+ errno = EINVAL;
+ return -1;
}
- if (pass == 1) {
+ if (pass == 0) {
+ free(prop);
+ free(context);
+ } else if (pass == 1) {
/* On the second pass, process and store the specification in spec. */
- spec_arr[nspec].property_key = strdup(prop);
- if (!spec_arr[nspec].property_key) {
- selinux_log(SELINUX_WARNING,
- "%s: out of memory at line %u on prop %s\n",
- path, lineno, prop);
- return -1;
-
- }
-
- spec_arr[nspec].lr.ctx_raw = strdup(context);
- if (!spec_arr[nspec].lr.ctx_raw) {
- selinux_log(SELINUX_WARNING,
- "%s: out of memory at line %u on context %s\n",
- path, lineno, context);
- return -1;
- }
+ spec_arr[nspec].property_key = prop;
+ spec_arr[nspec].lr.ctx_raw = context;
if (rec->validating) {
if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) {
- selinux_log(SELINUX_WARNING,
+ selinux_log(SELINUX_ERROR,
"%s: line %u has invalid context %s\n",
path, lineno, spec_arr[nspec].lr.ctx_raw);
+ errno = EINVAL;
+ return -1;
}
}
}
@@ -130,7 +125,7 @@ static int process_line(struct selabel_handle *rec,
return 0;
}
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
unsigned n)
{
struct saved_data *data = (struct saved_data *)rec->data;
@@ -149,7 +144,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
break;
}
- if (!path)
+ if (!path)
return -1;
/* Open the specification file. */
@@ -164,17 +159,18 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
/*
* Two passes of the specification file. First is to get the size.
- * After the first pass, the spec array is malloced to the appropriate
- * size. Second pass is to populate the spec array and check for
+ * After the first pass, the spec array is malloced to the appropriate
+ * size. Second pass is to populate the spec array and check for
* dups.
*/
maxnspec = UINT_MAX / sizeof(spec_t);
for (pass = 0; pass < 2; pass++) {
data->nspec = 0;
- while (fgets(line_buf, sizeof line_buf - 1, fp)
+ while (fgets(line_buf, sizeof(line_buf) - 1, fp)
&& data->nspec < maxnspec) {
- if (process_line(rec, path, line_buf, pass, ++lineno) != 0)
+ if (process_line(rec, path, line_buf, pass, ++lineno)
+ != 0)
goto finish;
}
@@ -186,7 +182,6 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
}
if (pass == 0) {
-
if (data->nspec == 0) {
status = 0;
goto finish;
@@ -204,7 +199,12 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
qsort(data->spec_arr, data->nspec, sizeof(struct spec), cmp);
- status = 0;
+ status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+ if (status)
+ goto finish;
+
+ digest_gen_hash(rec->digest);
+
finish:
fclose(fp);
return status;
@@ -234,7 +234,7 @@ static void closef(struct selabel_handle *rec)
static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
const char *key,
- int __attribute__ ((unused)) type)
+ int __attribute__((unused)) type)
{
struct saved_data *data = (struct saved_data *)rec->data;
spec_t *spec_arr = data->spec_arr;
@@ -267,12 +267,13 @@ finish:
return ret;
}
-static void stats(struct selabel_handle __attribute__ ((unused)) * rec)
+static void stats(struct selabel_handle __attribute__((unused)) *rec)
{
selinux_log(SELINUX_WARNING, "'stats' functionality not implemented.\n");
}
-int selabel_property_init(struct selabel_handle *rec, struct selinux_opt *opts,
+int selabel_property_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
unsigned nopts)
{
struct saved_data *data;
diff --git a/libselinux/src/label_db.c b/libselinux/src/label_db.c
index 1b48735e..1155bcc8 100644
--- a/libselinux/src/label_db.c
+++ b/libselinux/src/label_db.c
@@ -234,7 +234,8 @@ db_stats(struct selabel_handle *rec)
* selabel_open() handler
*/
static catalog_t *
-db_init(struct selinux_opt *opts, unsigned nopts, struct selabel_handle *rec)
+db_init(const struct selinux_opt *opts, unsigned nopts,
+ struct selabel_handle *rec)
{
catalog_t *catalog;
FILE *filp;
@@ -243,6 +244,7 @@ db_init(struct selinux_opt *opts, unsigned nopts, struct selabel_handle *rec)
size_t line_len = 0;
unsigned int line_num = 0;
unsigned int i;
+ struct stat sb;
/*
* Initialize catalog data structure
@@ -279,6 +281,12 @@ db_init(struct selinux_opt *opts, unsigned nopts, struct selabel_handle *rec)
free(catalog);
return NULL;
}
+ if (fstat(fileno(filp), &sb) < 0)
+ return NULL;
+ if (!S_ISREG(sb.st_mode)) {
+ errno = EINVAL;
+ return NULL;
+ }
rec->spec_file = strdup(path);
/*
@@ -311,6 +319,11 @@ db_init(struct selinux_opt *opts, unsigned nopts, struct selabel_handle *rec)
}
free(line_buf);
+ if (digest_add_specfile(rec->digest, filp, NULL, sb.st_size, path) < 0)
+ goto out_error;
+
+ digest_gen_hash(rec->digest);
+
fclose(filp);
return catalog;
@@ -332,7 +345,7 @@ out_error:
* Initialize selabel_handle and load the entries of specfile
*/
int selabel_db_init(struct selabel_handle *rec,
- struct selinux_opt *opts, unsigned nopts)
+ const struct selinux_opt *opts, unsigned nopts)
{
rec->func_close = &db_close;
rec->func_lookup = &db_lookup;
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 60aae669..071d9020 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -5,6 +5,7 @@
* Author : Stephen Smalley <sds@tycho.nsa.gov>
*/
+#include <assert.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
@@ -15,13 +16,11 @@
#include <limits.h>
#include <stdint.h>
#include <pcre.h>
-
-#include <linux/limits.h>
-
+#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
+
#include "callbacks.h"
#include "label_internal.h"
#include "label_file.h"
@@ -72,12 +71,14 @@ static int nodups_specs(struct saved_data *data, const char *path)
for (ii = 0; ii < data->nspec; ii++) {
curr_spec = &spec_arr[ii];
for (jj = ii + 1; jj < data->nspec; jj++) {
- if ((!strcmp(spec_arr[jj].regex_str, curr_spec->regex_str))
+ if ((!strcmp(spec_arr[jj].regex_str,
+ curr_spec->regex_str))
&& (!spec_arr[jj].mode || !curr_spec->mode
|| spec_arr[jj].mode == curr_spec->mode)) {
rc = -1;
errno = EINVAL;
- if (strcmp(spec_arr[jj].lr.ctx_raw, curr_spec->lr.ctx_raw)) {
+ if (strcmp(spec_arr[jj].lr.ctx_raw,
+ curr_spec->lr.ctx_raw)) {
COMPAT_LOG
(SELINUX_ERROR,
"%s: Multiple different specifications for %s (%s and %s).\n",
@@ -96,136 +97,9 @@ static int nodups_specs(struct saved_data *data, const char *path)
return rc;
}
-static int compile_regex(struct saved_data *data, struct spec *spec, const char **errbuf)
-{
- const char *tmperrbuf;
- char *reg_buf, *anchored_regex, *cp;
- struct stem *stem_arr = data->stem_arr;
- size_t len;
- int erroff;
-
- if (spec->regcomp)
- return 0; /* already done */
-
- /* Skip the fixed stem. */
- reg_buf = spec->regex_str;
- if (spec->stem_id >= 0)
- reg_buf += stem_arr[spec->stem_id].len;
-
- /* Anchor the regular expression. */
- len = strlen(reg_buf);
- cp = anchored_regex = malloc(len + 3);
- if (!anchored_regex)
- return -1;
-
- /* Create ^...$ regexp. */
- *cp++ = '^';
- cp = mempcpy(cp, reg_buf, len);
- *cp++ = '$';
- *cp = '\0';
-
- /* Compile the regular expression. */
- spec->regex = pcre_compile(anchored_regex, PCRE_DOTALL, &tmperrbuf, &erroff, NULL);
- free(anchored_regex);
- if (!spec->regex) {
- if (errbuf)
- *errbuf=tmperrbuf;
- return -1;
- }
-
- spec->sd = pcre_study(spec->regex, 0, &tmperrbuf);
- if (!spec->sd && tmperrbuf) {
- if (errbuf)
- *errbuf=tmperrbuf;
- return -1;
- }
-
- /* Done. */
- spec->regcomp = 1;
-
- return 0;
-}
-
-static int process_line(struct selabel_handle *rec,
- const char *path, const char *prefix,
- char *line_buf, unsigned lineno)
-{
- int items, len, rc;
- char *regex = NULL, *type = NULL, *context = NULL;
- struct saved_data *data = (struct saved_data *)rec->data;
- struct spec *spec_arr;
- unsigned int nspec = data->nspec;
- const char *errbuf = NULL;
-
- items = read_spec_entries(line_buf, 3, &regex, &type, &context);
- if (items <= 0)
- return items;
-
- if (items < 2) {
- COMPAT_LOG(SELINUX_WARNING,
- "%s: line %u is missing fields, skipping\n", path,
- lineno);
- if (items == 1)
- free(regex);
- return 0;
- } else if (items == 2) {
- /* The type field is optional. */
- free(context);
- context = type;
- type = 0;
- }
-
- len = get_stem_from_spec(regex);
- if (len && prefix && strncmp(prefix, regex, len)) {
- /* Stem of regex does not match requested prefix, discard. */
- free(regex);
- free(type);
- free(context);
- return 0;
- }
-
- rc = grow_specs(data);
- if (rc)
- return rc;
-
- spec_arr = data->spec_arr;
-
- /* process and store the specification in spec. */
- spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
- spec_arr[nspec].regex_str = regex;
- if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) {
- COMPAT_LOG(SELINUX_WARNING, "%s: line %u has invalid regex %s: %s\n",
- path, lineno, regex, (errbuf ? errbuf : "out of memory"));
- }
-
- /* Convert the type string to a mode format */
- spec_arr[nspec].type_str = type;
- spec_arr[nspec].mode = 0;
- if (type) {
- mode_t mode = string_to_mode(type);
- if (mode == (mode_t)-1) {
- COMPAT_LOG(SELINUX_WARNING, "%s: line %u has invalid file type %s\n",
- path, lineno, type);
- mode = 0;
- }
- spec_arr[nspec].mode = mode;
- }
-
- spec_arr[nspec].lr.ctx_raw = context;
-
- /* Determine if specification has
- * any meta characters in the RE */
- spec_hasMetaChars(&spec_arr[nspec]);
-
- if (strcmp(context, "<<none>>") && rec->validating)
- compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
-
- data->nspec = ++nspec;
-
- return 0;
-}
-
-static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *sb)
+static int load_mmap(struct selabel_handle *rec, const char *path,
+ struct stat *sb, bool isbinary,
+ struct selabel_digest *digest)
{
struct saved_data *data = (struct saved_data *)rec->data;
char mmap_path[PATH_MAX + 1];
@@ -239,9 +113,16 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
uint32_t i, magic, version;
uint32_t entry_len, stem_map_len, regex_array_len;
- rc = snprintf(mmap_path, sizeof(mmap_path), "%s.bin", path);
- if (rc >= (int)sizeof(mmap_path))
- return -1;
+ if (isbinary) {
+ len = strlen(path);
+ if (len >= sizeof(mmap_path))
+ return -1;
+ strcpy(mmap_path, path);
+ } else {
+ rc = snprintf(mmap_path, sizeof(mmap_path), "%s.bin", path);
+ if (rc >= (int)sizeof(mmap_path))
+ return -1;
+ }
mmapfd = open(mmap_path, O_RDONLY | O_CLOEXEC);
if (mmapfd < 0)
@@ -259,12 +140,6 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
return -1;
}
- if (mmap_stat.st_mtime == sb->st_mtime &&
- mmap_stat.st_mtim.tv_nsec < sb->st_mtim.tv_nsec) {
- close(mmapfd);
- return -1;
- }
-
/* ok, read it in... */
len = mmap_stat.st_size;
len += (sysconf(_SC_PAGE_SIZE) - 1);
@@ -285,8 +160,8 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
}
/* save where we mmap'd the file to cleanup on close() */
- mmap_area->addr = addr;
- mmap_area->len = len;
+ mmap_area->addr = mmap_area->next_addr = addr;
+ mmap_area->len = mmap_area->next_len = len;
mmap_area->next = data->mmap_areas;
data->mmap_areas = mmap_area;
@@ -357,7 +232,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
/* Check for stem_len wrap around. */
if (stem_len < UINT32_MAX) {
- buf = (char *)mmap_area->addr;
+ buf = (char *)mmap_area->next_addr;
/* Check if over-run before null check. */
rc = next_entry(NULL, mmap_area, (stem_len + 1));
if (rc < 0)
@@ -395,7 +270,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
for (i = 0; i < regex_array_len; i++) {
struct spec *spec;
int32_t stem_id, meta_chars;
- uint32_t mode = 0;
+ uint32_t mode = 0, prefix_len = 0;
rc = grow_specs(data);
if (rc < 0)
@@ -428,6 +303,14 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
}
spec->lr.ctx_raw = str_buf;
+ if (strcmp(spec->lr.ctx_raw, "<<none>>") && rec->validating) {
+ if (selabel_validate(rec, &spec->lr) < 0) {
+ selinux_log(SELINUX_ERROR,
+ "%s: context %s is invalid\n", mmap_path, spec->lr.ctx_raw);
+ goto err;
+ }
+ }
+
/* Process regex string */
rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
if (rc < 0 || !entry_len) {
@@ -435,7 +318,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
goto err;
}
- spec->regex_str = (char *)mmap_area->addr;
+ spec->regex_str = (char *)mmap_area->next_addr;
rc = next_entry(NULL, mmap_area, entry_len);
if (rc < 0)
goto err;
@@ -460,7 +343,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
if (rc < 0)
goto err;
- if (stem_id < 0 || stem_id >= stem_map_len)
+ if (stem_id < 0 || stem_id >= (int32_t)stem_map_len)
spec->stem_id = -1;
else
spec->stem_id = stem_map[stem_id];
@@ -471,6 +354,15 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
goto err;
spec->hasMetaChars = meta_chars;
+ /* and prefix length for use by selabel_lookup_best_match */
+ if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) {
+ rc = next_entry(&prefix_len, mmap_area,
+ sizeof(uint32_t));
+ if (rc < 0)
+ goto err;
+
+ spec->prefix_len = prefix_len;
+ }
/* Process regex and study_data entries */
rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
@@ -478,7 +370,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
rc = -1;
goto err;
}
- spec->regex = (pcre *)mmap_area->addr;
+ spec->regex = (pcre *)mmap_area->next_addr;
rc = next_entry(NULL, mmap_area, entry_len);
if (rc < 0)
goto err;
@@ -496,7 +388,7 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
rc = -1;
goto err;
}
- spec->lsd.study_data = (void *)mmap_area->addr;
+ spec->lsd.study_data = (void *)mmap_area->next_addr;
spec->lsd.flags |= PCRE_EXTRA_STUDY_DATA;
rc = next_entry(NULL, mmap_area, entry_len);
if (rc < 0)
@@ -512,27 +404,36 @@ static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *
data->nspec++;
}
- /* win */
- rc = 0;
+
+ rc = digest_add_specfile(digest, NULL, addr, mmap_stat.st_size,
+ mmap_path);
+ if (rc)
+ goto err;
+
err:
free(stem_map);
return rc;
}
-static int process_file(const char *path, const char *suffix, struct selabel_handle *rec, const char *prefix)
+static int process_file(const char *path, const char *suffix,
+ struct selabel_handle *rec,
+ const char *prefix, struct selabel_digest *digest)
{
FILE *fp;
struct stat sb;
unsigned int lineno;
- size_t line_len;
+ size_t line_len = 0;
char *line_buf = NULL;
int rc;
char stack_path[PATH_MAX + 1];
+ bool isbinary = false;
+ uint32_t magic;
/* append the path suffix if we have one */
if (suffix) {
- rc = snprintf(stack_path, sizeof(stack_path), "%s.%s", path, suffix);
+ rc = snprintf(stack_path, sizeof(stack_path),
+ "%s.%s", path, suffix);
if (rc >= (int)sizeof(stack_path)) {
errno = ENAMETOOLONG;
return -1;
@@ -541,38 +442,74 @@ static int process_file(const char *path, const char *suffix, struct selabel_han
}
/* Open the specification file. */
- if ((fp = fopen(path, "r")) == NULL)
- return -1;
- __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ fp = fopen(path, "r");
+ if (fp) {
+ __fsetlocking(fp, FSETLOCKING_BYCALLER);
- if (fstat(fileno(fp), &sb) < 0)
- return -1;
- if (!S_ISREG(sb.st_mode)) {
- errno = EINVAL;
- return -1;
+ if (fstat(fileno(fp), &sb) < 0)
+ return -1;
+ if (!S_ISREG(sb.st_mode)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ magic = 0;
+ if (fread(&magic, sizeof magic, 1, fp) != 1) {
+ if (ferror(fp)) {
+ errno = EINVAL;
+ fclose(fp);
+ return -1;
+ }
+ clearerr(fp);
+ }
+
+ if (magic == SELINUX_MAGIC_COMPILED_FCONTEXT) {
+ /* file_contexts.bin format */
+ fclose(fp);
+ fp = NULL;
+ isbinary = true;
+ } else {
+ rewind(fp);
+ }
+ } else {
+ /*
+ * Text file does not exist, so clear the timestamp
+ * so that we will always pass the timestamp comparison
+ * with the bin file in load_mmap().
+ */
+ sb.st_mtime = 0;
}
- rc = load_mmap(rec, path, &sb);
+ rc = load_mmap(rec, path, &sb, isbinary, digest);
if (rc == 0)
goto out;
+ if (!fp)
+ return -1; /* no text or bin file */
+
/*
- * The do detailed validation of the input and fill the spec array
+ * Then do detailed validation of the input and fill the spec array
*/
lineno = 0;
+ rc = 0;
while (getline(&line_buf, &line_len, fp) > 0) {
rc = process_line(rec, path, prefix, line_buf, ++lineno);
if (rc)
- return rc;
+ goto out;
}
+
+ rc = digest_add_specfile(digest, fp, NULL, sb.st_size, path);
+
out:
free(line_buf);
- fclose(fp);
-
- return 0;
+ if (fp)
+ fclose(fp);
+ return rc;
}
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static void closef(struct selabel_handle *rec);
+
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
unsigned n)
{
struct saved_data *data = (struct saved_data *)rec->data;
@@ -597,22 +534,27 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
/* Process local and distribution substitution files */
if (!path) {
- rec->dist_subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->dist_subs);
- rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs);
+ rec->dist_subs =
+ selabel_subs_init(selinux_file_context_subs_dist_path(),
+ rec->dist_subs, rec->digest);
+ rec->subs = selabel_subs_init(selinux_file_context_subs_path(),
+ rec->subs, rec->digest);
path = selinux_file_context_path();
} else {
snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path);
- rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs);
+ rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs,
+ rec->digest);
snprintf(subs_file, sizeof(subs_file), "%s.subs", path);
- rec->subs = selabel_subs_init(subs_file, rec->subs);
+ rec->subs = selabel_subs_init(subs_file, rec->subs,
+ rec->digest);
}
rec->spec_file = strdup(path);
- /*
+ /*
* The do detailed validation of the input and fill the spec array
*/
- status = process_file(path, NULL, rec, prefix);
+ status = process_file(path, NULL, rec, prefix, rec->digest);
if (status)
goto finish;
@@ -623,21 +565,25 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
}
if (!baseonly) {
- status = process_file(path, "homedirs", rec, prefix);
+ status = process_file(path, "homedirs", rec, prefix,
+ rec->digest);
if (status && errno != ENOENT)
goto finish;
- status = process_file(path, "local", rec, prefix);
+ status = process_file(path, "local", rec, prefix,
+ rec->digest);
if (status && errno != ENOENT)
goto finish;
}
+ digest_gen_hash(rec->digest);
+
status = sort_specs(data);
- status = 0;
finish:
if (status)
- free(data->spec_arr);
+ closef(rec);
+
return status;
}
@@ -731,7 +677,7 @@ static struct spec *lookup_common(struct selabel_handle *rec,
if (partial)
pcre_options |= PCRE_PARTIAL_SOFT;
- /*
+ /*
* Check for matching specifications in reverse order, so that
* the last matching specification is used.
*/
@@ -857,6 +803,96 @@ out:
return lr;
}
+static enum selabel_cmp_result incomp(struct spec *spec1, struct spec *spec2, const char *reason, int i, int j)
+{
+ selinux_log(SELINUX_INFO,
+ "selabel_cmp: mismatched %s on entry %d: (%s, %x, %s) vs entry %d: (%s, %x, %s)\n",
+ reason,
+ i, spec1->regex_str, spec1->mode, spec1->lr.ctx_raw,
+ j, spec2->regex_str, spec2->mode, spec2->lr.ctx_raw);
+ return SELABEL_INCOMPARABLE;
+}
+
+static enum selabel_cmp_result cmp(struct selabel_handle *h1,
+ struct selabel_handle *h2)
+{
+ struct saved_data *data1 = (struct saved_data *)h1->data;
+ struct saved_data *data2 = (struct saved_data *)h2->data;
+ unsigned int i, nspec1 = data1->nspec, j, nspec2 = data2->nspec;
+ struct spec *spec_arr1 = data1->spec_arr, *spec_arr2 = data2->spec_arr;
+ struct stem *stem_arr1 = data1->stem_arr, *stem_arr2 = data2->stem_arr;
+ bool skipped1 = false, skipped2 = false;
+
+ i = 0;
+ j = 0;
+ while (i < nspec1 && j < nspec2) {
+ struct spec *spec1 = &spec_arr1[i];
+ struct spec *spec2 = &spec_arr2[j];
+
+ /*
+ * Because sort_specs() moves exact pathnames to the
+ * end, we might need to skip over additional regex
+ * entries that only exist in one of the configurations.
+ */
+ if (!spec1->hasMetaChars && spec2->hasMetaChars) {
+ j++;
+ skipped2 = true;
+ continue;
+ }
+
+ if (spec1->hasMetaChars && !spec2->hasMetaChars) {
+ i++;
+ skipped1 = true;
+ continue;
+ }
+
+ if (spec1->regcomp && spec2->regcomp) {
+ size_t len1, len2;
+ int rc;
+
+ rc = pcre_fullinfo(spec1->regex, NULL, PCRE_INFO_SIZE, &len1);
+ assert(rc == 0);
+ rc = pcre_fullinfo(spec2->regex, NULL, PCRE_INFO_SIZE, &len2);
+ assert(rc == 0);
+ if (len1 != len2 ||
+ memcmp(spec1->regex, spec2->regex, len1))
+ return incomp(spec1, spec2, "regex", i, j);
+ } else {
+ if (strcmp(spec1->regex_str, spec2->regex_str))
+ return incomp(spec1, spec2, "regex_str", i, j);
+ }
+
+ if (spec1->mode != spec2->mode)
+ return incomp(spec1, spec2, "mode", i, j);
+
+ if (spec1->stem_id == -1 && spec2->stem_id != -1)
+ return incomp(spec1, spec2, "stem_id", i, j);
+ if (spec2->stem_id == -1 && spec1->stem_id != -1)
+ return incomp(spec1, spec2, "stem_id", i, j);
+ if (spec1->stem_id != -1 && spec2->stem_id != -1) {
+ struct stem *stem1 = &stem_arr1[spec1->stem_id];
+ struct stem *stem2 = &stem_arr2[spec2->stem_id];
+ if (stem1->len != stem2->len ||
+ strncmp(stem1->buf, stem2->buf, stem1->len))
+ return incomp(spec1, spec2, "stem", i, j);
+ }
+
+ if (strcmp(spec1->lr.ctx_raw, spec2->lr.ctx_raw))
+ return incomp(spec1, spec2, "ctx_raw", i, j);
+
+ i++;
+ j++;
+ }
+
+ if ((skipped1 || i < nspec1) && !skipped2)
+ return SELABEL_SUPERSET;
+ if ((skipped2 || j < nspec2) && !skipped1)
+ return SELABEL_SUBSET;
+ if (skipped1 && skipped2)
+ return SELABEL_INCOMPARABLE;
+ return SELABEL_EQUAL;
+}
+
static void stats(struct selabel_handle *rec)
{
@@ -882,8 +918,9 @@ static void stats(struct selabel_handle *rec)
}
}
-int selabel_file_init(struct selabel_handle *rec, struct selinux_opt *opts,
- unsigned nopts)
+int selabel_file_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
+ unsigned nopts)
{
struct saved_data *data;
@@ -898,6 +935,7 @@ int selabel_file_init(struct selabel_handle *rec, struct selinux_opt *opts,
rec->func_lookup = &lookup;
rec->func_partial_match = &partial_match;
rec->func_lookup_best_match = &lookup_best_match;
+ rec->func_cmp = &cmp;
return init(rec, opts, nopts);
}
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index a8d1e51d..beb1fc26 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -3,6 +3,7 @@
#include <sys/stat.h>
+#include "callbacks.h"
#include "label_internal.h"
#define SELINUX_MAGIC_COMPILED_FCONTEXT 0xf97cff8a
@@ -11,10 +12,11 @@
#define SELINUX_COMPILED_FCONTEXT_NOPCRE_VERS 1
#define SELINUX_COMPILED_FCONTEXT_PCRE_VERS 2
#define SELINUX_COMPILED_FCONTEXT_MODE 3
+#define SELINUX_COMPILED_FCONTEXT_PREFIX_LEN 4
-#define SELINUX_COMPILED_FCONTEXT_MAX_VERS SELINUX_COMPILED_FCONTEXT_MODE
+#define SELINUX_COMPILED_FCONTEXT_MAX_VERS SELINUX_COMPILED_FCONTEXT_PREFIX_LEN
-/* Prior to verison 8.20, libpcre did not have pcre_free_study() */
+/* Prior to version 8.20, libpcre did not have pcre_free_study() */
#if (PCRE_MAJOR < 8 || (PCRE_MAJOR == 8 && PCRE_MINOR < 20))
#define pcre_free_study pcre_free
#endif
@@ -47,8 +49,10 @@ struct stem {
/* Where we map the file in during selabel_open() */
struct mmap_area {
- void *addr; /* Start of area - gets incremented by next_entry() */
- size_t len; /* Length - gets decremented by next_entry() */
+ void *addr; /* Start addr + len used to release memory at close */
+ size_t len;
+ void *next_addr; /* Incremented by next_entry() */
+ size_t next_len; /* Decremented by next_entry() */
struct mmap_area *next;
};
@@ -147,6 +151,7 @@ static inline void spec_hasMetaChars(struct spec *spec)
end = c + len;
spec->hasMetaChars = 0;
+ spec->prefix_len = len;
/* Look at each character in the RE specification string for a
* meta character. Return when any meta character reached. */
@@ -163,6 +168,7 @@ static inline void spec_hasMetaChars(struct spec *spec)
case '(':
case '{':
spec->hasMetaChars = 1;
+ spec->prefix_len = c - spec->regex_str;
return;
case '\\': /* skip the next character */
c++;
@@ -173,7 +179,6 @@ static inline void spec_hasMetaChars(struct spec *spec)
}
c++;
}
- return;
}
/* Move exact pathname specifications to the end. */
@@ -200,9 +205,9 @@ static inline int sort_specs(struct saved_data *data)
}
/*
- * now the exact pathnames are at the end, but they are in the reverse order.
- * since 'front' is now the first of the 'exact' we can run that part of the
- * array switching the front and back element.
+ * now the exact pathnames are at the end, but they are in the reverse
+ * order. Since 'front' is now the first of the 'exact' we can run
+ * that part of the array switching the front and back element.
*/
back = data->nspec - 1;
while (front < back) {
@@ -242,7 +247,8 @@ static inline int get_stem_from_spec(const char *const buf)
/*
* return the stemid given a string and a length
*/
-static inline int find_stem(struct saved_data *data, const char *buf, int stem_len)
+static inline int find_stem(struct saved_data *data, const char *buf,
+ int stem_len)
{
int i;
@@ -272,6 +278,7 @@ static inline int store_stem(struct saved_data *data, char *buf, int stem_len)
}
data->stem_arr[num].len = stem_len;
data->stem_arr[num].buf = buf;
+ data->stem_arr[num].from_mmap = 0;
data->num_stems++;
return num;
@@ -306,14 +313,161 @@ static inline int find_stem_from_spec(struct saved_data *data, const char *buf)
* current buffer). */
static inline int next_entry(void *buf, struct mmap_area *fp, size_t bytes)
{
- if (bytes > fp->len)
+ if (bytes > fp->next_len)
return -1;
if (buf)
- memcpy(buf, fp->addr, bytes);
+ memcpy(buf, fp->next_addr, bytes);
+
+ fp->next_addr = (char *)fp->next_addr + bytes;
+ fp->next_len -= bytes;
+ return 0;
+}
+
+static inline int compile_regex(struct saved_data *data, struct spec *spec,
+ const char **errbuf)
+{
+ const char *tmperrbuf;
+ char *reg_buf, *anchored_regex, *cp;
+ struct stem *stem_arr = data->stem_arr;
+ size_t len;
+ int erroff;
+
+ if (spec->regcomp)
+ return 0; /* already done */
+
+ /* Skip the fixed stem. */
+ reg_buf = spec->regex_str;
+ if (spec->stem_id >= 0)
+ reg_buf += stem_arr[spec->stem_id].len;
+
+ /* Anchor the regular expression. */
+ len = strlen(reg_buf);
+ cp = anchored_regex = malloc(len + 3);
+ if (!anchored_regex)
+ return -1;
+
+ /* Create ^...$ regexp. */
+ *cp++ = '^';
+ memcpy(cp, reg_buf, len);
+ cp += len;
+ *cp++ = '$';
+ *cp = '\0';
+
+ /* Compile the regular expression. */
+ spec->regex = pcre_compile(anchored_regex, PCRE_DOTALL, &tmperrbuf,
+ &erroff, NULL);
+ free(anchored_regex);
+ if (!spec->regex) {
+ if (errbuf)
+ *errbuf = tmperrbuf;
+ return -1;
+ }
+
+ spec->sd = pcre_study(spec->regex, 0, &tmperrbuf);
+ if (!spec->sd && tmperrbuf) {
+ if (errbuf)
+ *errbuf = tmperrbuf;
+ return -1;
+ }
+
+ /* Done. */
+ spec->regcomp = 1;
+
+ return 0;
+}
+
+/* This service is used by label_file.c process_file() and
+ * utils/sefcontext_compile.c */
+static inline int process_line(struct selabel_handle *rec,
+ const char *path, const char *prefix,
+ char *line_buf, unsigned lineno)
+{
+ int items, len, rc;
+ char *regex = NULL, *type = NULL, *context = NULL;
+ struct saved_data *data = (struct saved_data *)rec->data;
+ struct spec *spec_arr;
+ unsigned int nspec = data->nspec;
+ const char *errbuf = NULL;
+
+ items = read_spec_entries(line_buf, 3, &regex, &type, &context);
+ if (items <= 0)
+ return items;
+
+ if (items < 2) {
+ COMPAT_LOG(SELINUX_ERROR,
+ "%s: line %u is missing fields\n", path,
+ lineno);
+ if (items == 1)
+ free(regex);
+ errno = EINVAL;
+ return -1;
+ } else if (items == 2) {
+ /* The type field is optional. */
+ context = type;
+ type = 0;
+ }
+
+ len = get_stem_from_spec(regex);
+ if (len && prefix && strncmp(prefix, regex, len)) {
+ /* Stem of regex does not match requested prefix, discard. */
+ free(regex);
+ free(type);
+ free(context);
+ return 0;
+ }
+
+ rc = grow_specs(data);
+ if (rc)
+ return rc;
+
+ spec_arr = data->spec_arr;
+
+ /* process and store the specification in spec. */
+ spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
+ spec_arr[nspec].regex_str = regex;
+
+ spec_arr[nspec].type_str = type;
+ spec_arr[nspec].mode = 0;
+
+ spec_arr[nspec].lr.ctx_raw = context;
+
+ /*
+ * bump data->nspecs to cause closef() to cover it in its free
+ * but do not bump nspec since it's used below.
+ */
+ data->nspec++;
+
+ if (rec->validating &&
+ compile_regex(data, &spec_arr[nspec], &errbuf)) {
+ COMPAT_LOG(SELINUX_ERROR,
+ "%s: line %u has invalid regex %s: %s\n",
+ path, lineno, regex,
+ (errbuf ? errbuf : "out of memory"));
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (type) {
+ mode_t mode = string_to_mode(type);
+
+ if (mode == (mode_t)-1) {
+ COMPAT_LOG(SELINUX_ERROR,
+ "%s: line %u has invalid file type %s\n",
+ path, lineno, type);
+ errno = EINVAL;
+ return -1;
+ }
+ spec_arr[nspec].mode = mode;
+ }
+
+ /* Determine if specification has
+ * any meta characters in the RE */
+ spec_hasMetaChars(&spec_arr[nspec]);
+
+ if (strcmp(context, "<<none>>") && rec->validating)
+ compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
- fp->addr = (char *)fp->addr + bytes;
- fp->len -= bytes;
return 0;
}
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index 0e582b62..cefa80b1 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -10,23 +10,30 @@
#include <stdlib.h>
#include <stdarg.h>
+#include <stdio.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "dso.h"
+#include "sha1.h"
/*
* Installed backends
*/
-int selabel_file_init(struct selabel_handle *rec, struct selinux_opt *opts,
- unsigned nopts) hidden;
-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_file_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
+ unsigned nopts) hidden;
+int selabel_media_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
+ unsigned nopts) hidden;
+int selabel_x_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
+ unsigned nopts) hidden;
int selabel_db_init(struct selabel_handle *rec,
- struct selinux_opt *opts, unsigned nopts) hidden;
+ const struct selinux_opt *opts,
+ unsigned nopts) hidden;
int selabel_property_init(struct selabel_handle *rec,
- struct selinux_opt *opts, unsigned nopts) hidden;
+ const struct selinux_opt *opts,
+ unsigned nopts) hidden;
/*
* Labeling internal structures
@@ -38,8 +45,31 @@ struct selabel_sub {
struct selabel_sub *next;
};
+/*
+ * Calculate an SHA1 hash of all the files used to build the specs.
+ * The hash value is held in rec->digest if SELABEL_OPT_DIGEST set. To
+ * calculate the hash the hashbuf will hold a concatenation of all the files
+ * used. This is released once the value has been calculated.
+ */
+#define DIGEST_SPECFILE_SIZE SHA1_HASH_SIZE
+#define DIGEST_FILES_MAX 8
+struct selabel_digest {
+ unsigned char *digest; /* SHA1 digest of specfiles */
+ unsigned char *hashbuf; /* buffer to hold specfiles */
+ size_t hashbuf_size; /* buffer size */
+ size_t specfile_cnt; /* how many specfiles processed */
+ char **specfile_list; /* and their names */
+};
+
+extern int digest_add_specfile(struct selabel_digest *digest, FILE *fp,
+ char *from_addr,
+ size_t buf_len,
+ const char *path);
+extern void digest_gen_hash(struct selabel_digest *digest);
+
extern struct selabel_sub *selabel_subs_init(const char *path,
- struct selabel_sub *list);
+ struct selabel_sub *list,
+ struct selabel_digest *digest);
struct selabel_lookup_rec {
char * ctx_raw;
@@ -63,6 +93,8 @@ struct selabel_handle {
const char *key,
const char **aliases,
int type);
+ enum selabel_cmp_result (*func_cmp)(struct selabel_handle *h1,
+ struct selabel_handle *h2);
/* supports backend-specific state information */
void *data;
@@ -76,6 +108,8 @@ struct selabel_handle {
/* substitution support */
struct selabel_sub *dist_subs;
struct selabel_sub *subs;
+ /* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */
+ struct selabel_digest *digest;
};
/*
@@ -90,7 +124,7 @@ selabel_validate(struct selabel_handle *rec,
*/
extern int myprintf_compat;
extern void __attribute__ ((format(printf, 1, 2)))
-(*myprintf) (const char *fmt,...);
+(*myprintf) (const char *fmt, ...);
#define COMPAT_LOG(type, fmt...) if (myprintf_compat) \
myprintf(fmt); \
diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c
index a09486b3..622741b2 100644
--- a/libselinux/src/label_media.c
+++ b/libselinux/src/label_media.c
@@ -67,7 +67,7 @@ static int process_line(const char *path, char *line_buf, int pass,
return 0;
}
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
unsigned n)
{
FILE *fp;
@@ -136,7 +136,12 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
}
free(line_buf);
- status = 0;
+ status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+ if (status)
+ goto finish;
+
+ digest_gen_hash(rec->digest);
+
finish:
fclose(fp);
return status;
@@ -161,7 +166,7 @@ static void close(struct selabel_handle *rec)
if (spec_arr)
free(spec_arr);
- memset(data, 0, sizeof(*data));
+ free(data);
}
static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
@@ -201,8 +206,9 @@ static void stats(struct selabel_handle *rec)
data->nspec, total);
}
-int selabel_media_init(struct selabel_handle *rec, struct selinux_opt *opts,
- unsigned nopts)
+int selabel_media_init(struct selabel_handle *rec,
+ const struct selinux_opt *opts,
+ unsigned nopts)
{
struct saved_data *data;
diff --git a/libselinux/src/label_support.c b/libselinux/src/label_support.c
index 7464f430..324dc51c 100644
--- a/libselinux/src/label_support.c
+++ b/libselinux/src/label_support.c
@@ -8,6 +8,8 @@
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
+#include <stdio.h>
+#include <errno.h>
#include "label_internal.h"
/*
@@ -15,11 +17,8 @@
* replace sscanf to read entries from spec files. The file and
* property services now use these.
*/
-
-/* Read an entry from a spec file (e.g. file_contexts) */
-static inline int read_spec_entry(char **entry, char **ptr)
+static inline int read_spec_entry(char **entry, char **ptr, int *len)
{
- int entry_len = 0;
*entry = NULL;
char *tmp_buf = NULL;
@@ -27,15 +26,18 @@ static inline int read_spec_entry(char **entry, char **ptr)
(*ptr)++;
tmp_buf = *ptr;
+ *len = 0;
while (!isspace(**ptr) && **ptr != '\0') {
(*ptr)++;
- entry_len++;
+ (*len)++;
}
- *entry = strndup(tmp_buf, entry_len);
- if (!*entry)
- return -1;
+ if (*len) {
+ *entry = strndup(tmp_buf, *len);
+ if (!*entry)
+ return -1;
+ }
return 0;
}
@@ -48,15 +50,20 @@ static inline int read_spec_entry(char **entry, char **ptr)
*
* This function calls read_spec_entry() to do the actual string processing.
*/
-int read_spec_entries(char *line_buf, int num_args, ...)
+int hidden read_spec_entries(char *line_buf, int num_args, ...)
{
char **spec_entry, *buf_p;
- int len, rc, items;
+ int len, rc, items, entry_len = 0;
va_list ap;
len = strlen(line_buf);
if (line_buf[len - 1] == '\n')
line_buf[len - 1] = '\0';
+ else
+ /* Handle case if line not \n terminated by bumping
+ * the len for the check below (as the line is NUL
+ * terminated by getline(3)) */
+ len++;
buf_p = line_buf;
while (isspace(*buf_p))
@@ -69,7 +76,8 @@ int read_spec_entries(char *line_buf, int num_args, ...)
/* Process the spec file entries */
va_start(ap, num_args);
- for (items = 0; items < num_args; items++) {
+ items = 0;
+ while (items < num_args) {
spec_entry = va_arg(ap, char **);
if (len - 1 == buf_p - line_buf) {
@@ -77,12 +85,93 @@ int read_spec_entries(char *line_buf, int num_args, ...)
return items;
}
- rc = read_spec_entry(spec_entry, &buf_p);
+ rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
if (rc < 0) {
va_end(ap);
return rc;
}
+ if (entry_len)
+ items++;
}
va_end(ap);
return items;
}
+
+/* Once all the specfiles are in the hash_buf, generate the hash. */
+void hidden digest_gen_hash(struct selabel_digest *digest)
+{
+ Sha1Context context;
+
+ /* If SELABEL_OPT_DIGEST not set then just return */
+ if (!digest)
+ return;
+
+ Sha1Initialise(&context);
+ Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
+ Sha1Finalise(&context, (SHA1_HASH *)digest->digest);
+ free(digest->hashbuf);
+ digest->hashbuf = NULL;
+ return;
+}
+
+/**
+ * digest_add_specfile - Add a specfile to the hashbuf and if gen_hash true
+ * then generate the hash.
+ * @digest: pointer to the selabel_digest struct
+ * @fp: file pointer for fread(3) or NULL if not.
+ * @from_addr: pointer at start of buffer for memcpy or NULL if not (used for
+ * mmap(3) files).
+ * @buf_len: length of buffer to copy.
+ * @path: pointer to the specfile.
+ *
+ * Return %0 on success, -%1 with @errno set on failure.
+ */
+int hidden digest_add_specfile(struct selabel_digest *digest, FILE *fp,
+ char *from_addr, size_t buf_len,
+ const char *path)
+{
+ unsigned char *tmp_buf;
+
+ /* If SELABEL_OPT_DIGEST not set then just return */
+ if (!digest)
+ return 0;
+
+ if (digest->hashbuf_size + buf_len < digest->hashbuf_size) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ digest->hashbuf_size += buf_len;
+
+ tmp_buf = realloc(digest->hashbuf, digest->hashbuf_size);
+ if (!tmp_buf)
+ return -1;
+
+ digest->hashbuf = tmp_buf;
+
+ if (fp) {
+ rewind(fp);
+ if (fread(digest->hashbuf + (digest->hashbuf_size - buf_len),
+ 1, buf_len, fp) != buf_len)
+ return -1;
+
+ rewind(fp);
+ } else if (from_addr) {
+ tmp_buf = memcpy(digest->hashbuf +
+ (digest->hashbuf_size - buf_len),
+ from_addr, buf_len);
+ if (!tmp_buf)
+ return -1;
+ }
+ /* Now add path to list */
+ digest->specfile_list[digest->specfile_cnt] = strdup(path);
+ if (!digest->specfile_list[digest->specfile_cnt])
+ return -1;
+
+ digest->specfile_cnt++;
+ if (digest->specfile_cnt > DIGEST_FILES_MAX) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c
index 8435b766..700def17 100644
--- a/libselinux/src/label_x.c
+++ b/libselinux/src/label_x.c
@@ -94,7 +94,7 @@ static int process_line(const char *path, char *line_buf, int pass,
return 0;
}
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
unsigned n)
{
FILE *fp;
@@ -163,7 +163,12 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts,
}
free(line_buf);
- status = 0;
+ status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+ if (status)
+ goto finish;
+
+ digest_gen_hash(rec->digest);
+
finish:
fclose(fp);
return status;
@@ -188,7 +193,7 @@ static void close(struct selabel_handle *rec)
if (spec_arr)
free(spec_arr);
- memset(data, 0, sizeof(*data));
+ free(data);
}
static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
@@ -227,7 +232,7 @@ static void stats(struct selabel_handle *rec)
data->nspec, total);
}
-int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
+int selabel_x_init(struct selabel_handle *rec, const struct selinux_opt *opts,
unsigned nopts)
{
struct saved_data *data;
diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c
index f9903505..527a0a5c 100644
--- a/libselinux/src/procattr.c
+++ b/libselinux/src/procattr.c
@@ -11,8 +11,6 @@
#define UNSET (char *) -1
-static __thread pid_t cpid;
-static __thread pid_t tid;
static __thread char *prev_current = UNSET;
static __thread char * prev_exec = UNSET;
static __thread char * prev_fscreate = UNSET;
@@ -24,15 +22,6 @@ static pthread_key_t destructor_key;
static int destructor_key_initialized = 0;
static __thread char destructor_initialized;
-extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
-extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
-
-static int __selinux_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
-{
- return __register_atfork (prepare, parent, child,
- &__dso_handle == NULL ? NULL : __dso_handle);
-}
-
static pid_t gettid(void)
{
return syscall(__NR_gettid);
@@ -52,14 +41,6 @@ static void procattr_thread_destructor(void __attribute__((unused)) *unused)
free(prev_sockcreate);
}
-static void free_procattr(void)
-{
- procattr_thread_destructor(NULL);
- tid = 0;
- cpid = getpid();
- prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = UNSET;
-}
-
void __attribute__((destructor)) procattr_destructor(void);
void hidden __attribute__((destructor)) procattr_destructor(void)
@@ -79,7 +60,6 @@ static inline void init_thread_destructor(void)
static void init_procattr(void)
{
if (__selinux_key_create(&destructor_key, procattr_thread_destructor) == 0) {
- __selinux_atfork(NULL, NULL, free_procattr);
destructor_key_initialized = 1;
}
}
@@ -88,21 +68,26 @@ static int openattr(pid_t pid, const char *attr, int flags)
{
int fd, rc;
char *path;
-
- if (cpid != getpid())
- free_procattr();
+ pid_t tid;
if (pid > 0)
rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
else {
- if (!tid)
- tid = gettid();
+ rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
+ if (rc < 0)
+ return -1;
+ fd = open(path, flags | O_CLOEXEC);
+ if (fd >= 0 || errno != ENOENT)
+ goto out;
+ free(path);
+ tid = gettid();
rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
}
if (rc < 0)
return -1;
fd = open(path, flags | O_CLOEXEC);
+out:
free(path);
return fd;
}
@@ -120,9 +105,6 @@ static int getprocattrcon_raw(char ** context,
__selinux_once(once, init_procattr);
init_thread_destructor();
- if (cpid != getpid())
- free_procattr();
-
switch (attr[0]) {
case 'c':
prev_context = prev_current;
@@ -220,9 +202,6 @@ static int setprocattrcon_raw(const char * context,
__selinux_once(once, init_procattr);
init_thread_destructor();
- if (cpid != getpid())
- free_procattr();
-
switch (attr[0]) {
case 'c':
prev_context = &prev_current;
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 844e408b..46566f62 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -102,6 +102,8 @@ hidden_proto(security_get_initial_context);
hidden_proto(security_get_initial_context_raw);
hidden_proto(selinux_reset_config);
+hidden void flush_class_cache(void);
+
extern int load_setlocaldefs hidden;
extern int require_seusers hidden;
extern int selinux_page_size hidden;
diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i
index c9a2341a..8cea18d2 100644
--- a/libselinux/src/selinuxswig_python.i
+++ b/libselinux/src/selinuxswig_python.i
@@ -8,7 +8,7 @@
%pythoncode %{
-import shutil, os, stat
+import shutil, os, errno, stat
DISABLED = -1
PERMISSIVE = 0
@@ -26,7 +26,12 @@ def restorecon(path, recursive=False):
status, context = matchpathcon(path, mode)
if status == 0:
- status, oldcontext = lgetfilecon(path)
+ try:
+ status, oldcontext = lgetfilecon(path)
+ except OSError as e:
+ if e.errno != errno.ENODATA:
+ raise
+ oldcontext = None
if context != oldcontext:
lsetfilecon(path, context)
diff --git a/libselinux/src/sha1.c b/libselinux/src/sha1.c
new file mode 100644
index 00000000..5f02af86
--- /dev/null
+++ b/libselinux/src/sha1.c
@@ -0,0 +1,214 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// LibSha1
+//
+// Implementation of SHA1 hash function.
+// Original author: Steve Reid <sreid@sea-to-sky.net>
+// Contributions by: James H. Brown <jbrown@burgoyne.com>, Saul Kravitz <Saul.Kravitz@celera.com>,
+// and Ralph Giles <giles@ghostscript.com>
+// Modified by WaterJuice retaining Public Domain license.
+//
+// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+// Modified to stop symbols being exported for libselinux shared library - October 2015
+// Richard Haines <richard_c_haines@btinternet.com>
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// IMPORTS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "sha1.h"
+#include "dso.h"
+#include <memory.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TYPES
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef union
+{
+ uint8_t c [64];
+ uint32_t l [16];
+} CHAR64LONG16;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// INTERNAL FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+// blk0() and blk() perform the initial expand.
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+ |(rol(block->l[i],8)&0x00FF00FF))
+
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+// (R0+R1), R2, R3, R4 are the different operations used in SHA1
+#define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk0(i)+ 0x5A827999 + rol(v,5); w=rol(w,30);
+#define R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk(i) + 0x5A827999 + rol(v,5); w=rol(w,30);
+#define R2(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0x6ED9EBA1 + rol(v,5); w=rol(w,30);
+#define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk(i) + 0x8F1BBCDC + rol(v,5); w=rol(w,30);
+#define R4(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0xCA62C1D6 + rol(v,5); w=rol(w,30);
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TransformFunction
+//
+// Hash a single 512-bit block. This is the core of the algorithm
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static
+void
+ TransformFunction
+ (
+ uint32_t state[5],
+ const uint8_t buffer[64]
+ )
+{
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+ uint32_t e;
+ uint8_t workspace[64];
+ CHAR64LONG16* block = (CHAR64LONG16*) workspace;
+
+ memcpy( block, buffer, 64 );
+
+ // Copy context->state[] to working vars
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+
+ // 4 rounds of 20 operations each. Loop unrolled.
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+ // Add the working vars back into context.state[]
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Initialise
+//
+// Initialises an SHA1 Context. Use this to initialise/reset a context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+ Sha1Initialise
+ (
+ Sha1Context* Context
+ )
+{
+ // SHA1 initialization constants
+ Context->State[0] = 0x67452301;
+ Context->State[1] = 0xEFCDAB89;
+ Context->State[2] = 0x98BADCFE;
+ Context->State[3] = 0x10325476;
+ Context->State[4] = 0xC3D2E1F0;
+ Context->Count[0] = 0;
+ Context->Count[1] = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Update
+//
+// Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on
+// calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+ Sha1Update
+ (
+ Sha1Context* Context,
+ void* Buffer,
+ uint32_t BufferSize
+ )
+{
+ uint32_t i;
+ uint32_t j;
+
+ j = (Context->Count[0] >> 3) & 63;
+ if( (Context->Count[0] += BufferSize << 3) < (BufferSize << 3) )
+ {
+ Context->Count[1]++;
+ }
+
+ Context->Count[1] += (BufferSize >> 29);
+ if( (j + BufferSize) > 63 )
+ {
+ i = 64 - j;
+ memcpy( &Context->Buffer[j], Buffer, i );
+ TransformFunction(Context->State, Context->Buffer);
+ for( ; i + 63 < BufferSize; i += 64 )
+ {
+ TransformFunction(Context->State, (uint8_t*)Buffer + i);
+ }
+ j = 0;
+ }
+ else
+ {
+ i = 0;
+ }
+
+ memcpy( &Context->Buffer[j], &((uint8_t*)Buffer)[i], BufferSize - i );
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Finalise
+//
+// Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After
+// calling this, Sha1Initialised must be used to reuse the context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+ Sha1Finalise
+ (
+ Sha1Context* Context,
+ SHA1_HASH* Digest
+ )
+{
+ uint32_t i;
+ uint8_t finalcount[8];
+
+ for( i=0; i<8; i++ )
+ {
+ finalcount[i] = (unsigned char)((Context->Count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); // Endian independent
+ }
+ Sha1Update( Context, (uint8_t*)"\x80", 1 );
+ while( (Context->Count[0] & 504) != 448 )
+ {
+ Sha1Update( Context, (uint8_t*)"\0", 1 );
+ }
+
+ Sha1Update( Context, finalcount, 8 ); // Should cause a Sha1TransformFunction()
+ for( i=0; i<SHA1_HASH_SIZE; i++ )
+ {
+ Digest->bytes[i] = (uint8_t)((Context->State[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+}
diff --git a/libselinux/src/sha1.h b/libselinux/src/sha1.h
new file mode 100644
index 00000000..eac3c195
--- /dev/null
+++ b/libselinux/src/sha1.h
@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// LibSha1
+//
+// Implementation of SHA1 hash function.
+// Original author: Steve Reid <sreid@sea-to-sky.net>
+// Contributions by: James H. Brown <jbrown@burgoyne.com>, Saul Kravitz <Saul.Kravitz@celera.com>,
+// and Ralph Giles <giles@ghostscript.com>
+// Modified by WaterJuice retaining Public Domain license.
+//
+// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _sha1_h_
+#define _sha1_h_
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// IMPORTS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdint.h>
+#include <stdio.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TYPES
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Sha1Context - This must be initialised using Sha1Initialised. Do not modify the contents of this structure directly.
+typedef struct
+{
+ uint32_t State[5];
+ uint32_t Count[2];
+ uint8_t Buffer[64];
+} Sha1Context;
+
+#define SHA1_HASH_SIZE ( 160 / 8 )
+
+typedef struct
+{
+ uint8_t bytes [SHA1_HASH_SIZE];
+} SHA1_HASH;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Initialise
+//
+// Initialises an SHA1 Context. Use this to initialise/reset a context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha1Initialise
+ (
+ Sha1Context* Context
+ );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Update
+//
+// Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on
+// calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha1Update
+ (
+ Sha1Context* Context,
+ void* Buffer,
+ uint32_t BufferSize
+ );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha1Finalise
+//
+// Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After
+// calling this, Sha1Initialised must be used to reuse the context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha1Finalise
+ (
+ Sha1Context* Context,
+ SHA1_HASH* Digest
+ );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif //_sha1_h_
diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c
index 9ae82483..2dbec2bf 100644
--- a/libselinux/src/stringrep.c
+++ b/libselinux/src/stringrep.c
@@ -158,6 +158,28 @@ err1:
return NULL;
}
+hidden void flush_class_cache(void)
+{
+ struct discover_class_node *cur = discover_class_cache, *prev = NULL;
+ size_t i;
+
+ while (cur != NULL) {
+ free(cur->name);
+
+ for (i = 0; i < MAXVECTORS; i++)
+ free(cur->perms[i]);
+
+ free(cur->perms);
+
+ prev = cur;
+ cur = cur->next;
+
+ free(prev);
+ }
+
+ discover_class_cache = NULL;
+}
+
security_class_t string_to_security_class(const char *s)
{
struct discover_class_node *node;
diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
index 54995385..cac85c75 100644
--- a/libselinux/utils/Makefile
+++ b/libselinux/utils/Makefile
@@ -28,7 +28,7 @@ LDLIBS += -L../src -lselinux -L$(LIBDIR)
TARGETS=$(patsubst %.c,%,$(wildcard *.c))
-sefcontext_compile: LDLIBS += -lpcre
+sefcontext_compile: LDLIBS += -lpcre ../src/libselinux.a -lsepol
ifeq ($(DISABLE_AVC),y)
UNUSED_TARGETS+=compute_av compute_create compute_member compute_relabel
diff --git a/libselinux/utils/sefcontext_compile.c b/libselinux/utils/sefcontext_compile.c
index 03bc0a7e..d2578b6b 100644
--- a/libselinux/utils/sefcontext_compile.c
+++ b/libselinux/utils/sefcontext_compile.c
@@ -7,117 +7,62 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-
-#include <linux/limits.h>
+#include <getopt.h>
+#include <limits.h>
+#include <selinux/selinux.h>
+#include <sepol/sepol.h>
#include "../src/label_file.h"
-static int process_file(struct saved_data *data, const char *filename)
+const char *policy_file;
+static int ctx_err;
+
+static int validate_context(char **ctxp)
+{
+ char *ctx = *ctxp;
+
+ if (policy_file && sepol_check_context(ctx) < 0) {
+ ctx_err = -1;
+ return ctx_err;
+ }
+
+ return 0;
+}
+
+static int process_file(struct selabel_handle *rec, const char *filename)
{
- struct spec *spec;
unsigned int line_num;
+ int rc;
char *line_buf = NULL;
- size_t line_len;
- ssize_t len;
+ size_t line_len = 0;
FILE *context_file;
+ const char *prefix = NULL;
context_file = fopen(filename, "r");
if (!context_file) {
- fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
+ fprintf(stderr, "Error opening %s: %s\n",
+ filename, strerror(errno));
return -1;
}
line_num = 0;
- while ((len = getline(&line_buf, &line_len, context_file)) != -1) {
- char *context = NULL;
- char *mode = NULL;
- char *regex = NULL;
- char *cp, *anchored_regex;
- pcre *re;
- pcre_extra *sd;
- const char *err;
- int items, erroff, rc;
- size_t regex_len;
- int32_t stem_id;
-
- line_num++;
-
- items = read_spec_entries(line_buf, 3, &regex, &mode, &context);
- if (items < 0)
- return -1;
-
- if (items == 0)
- continue;
- else if (items == 1) {
- fprintf(stderr,
- "line: %u has invalid entry - skipping: %s\n",
- line_num, line_buf);
- continue;
- } else if (items == 2) {
- context = mode;
- mode = NULL;
- }
-
- rc = grow_specs(data);
- if (rc) {
- fprintf(stderr, "grow_specs failed: %s\n", strerror(errno));
- return rc;
- }
-
- spec = &data->spec_arr[data->nspec];
-
- spec->lr.ctx_raw = context;
- spec->mode = string_to_mode(mode);
- if (spec->mode == (mode_t)-1) {
- fprintf(stderr, "%s: line %u has invalid file type %s\n",
- regex, line_num + 1, mode);
- spec->mode = 0;
- }
- free(mode);
- spec->regex_str = regex;
-
- stem_id = find_stem_from_spec(data, regex);
- spec->stem_id = stem_id;
- /* skip past the fixed stem part */
- if (stem_id != -1)
- regex += data->stem_arr[stem_id].len;
-
- regex_len = strlen(regex);
- cp = anchored_regex = malloc(regex_len + 3);
- if (!cp) {
- fprintf(stderr, "Malloc Failed: %s\n", strerror(errno));
- return -1;
- }
- *cp++ = '^';
- memcpy(cp, regex, regex_len);
- cp += regex_len;
- *cp++ = '$';
- *cp = '\0';
-
- spec_hasMetaChars(spec);
-
- re = pcre_compile(anchored_regex, PCRE_DOTALL, &err, &erroff, NULL);
- if (!re) {
- fprintf(stderr, "PCRE compilation failed for %s at offset %d: %s\n", anchored_regex, erroff, err);
- return -1;
- }
- spec->regex = re;
-
- sd = pcre_study(re, 0, &err);
- if (!sd) {
- fprintf(stderr, "PCRE study failed for %s: %s\n", anchored_regex, err);
- return -1;
+ rc = 0;
+ while (getline(&line_buf, &line_len, context_file) > 0) {
+ rc = process_line(rec, filename, prefix, line_buf, ++line_num);
+ if (rc || ctx_err) {
+ /* With -p option need to check and fail if ctx err as
+ * process_line() context validation on Linux does not
+ * return an error, but does print the error line to
+ * stderr. Android will set both to error and print
+ * the error line. */
+ rc = -1;
+ goto out;
}
- free(anchored_regex);
- spec->sd = sd;
-
- data->nspec++;
}
-
+out:
free(line_buf);
fclose(context_file);
-
- return 0;
+ return rc;
}
/*
@@ -129,18 +74,19 @@ static int process_file(struct saved_data *data, const char *filename)
* char - pcre version string EXCLUDING nul
* u32 - number of stems
* ** Stems
- * u32 - length of stem EXCLUDING nul
- * char - stem char array INCLUDING nul
+ * u32 - length of stem EXCLUDING nul
+ * char - stem char array INCLUDING nul
* u32 - number of regexs
* ** Regexes
- * u32 - length of upcoming context INCLUDING nul
- * char - char array of the raw context
+ * u32 - length of upcoming context INCLUDING nul
+ * char - char array of the raw context
* u32 - length of the upcoming regex_str
* char - char array of the original regex string including the stem.
* u32 - mode bits for >= SELINUX_COMPILED_FCONTEXT_MODE
* mode_t for <= SELINUX_COMPILED_FCONTEXT_PCRE_VERS
* s32 - stemid associated with the regex
* u32 - spec has meta characters
+ * u32 - The specs prefix_len if >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN
* u32 - data length of the pcre regex
* char - a bufer holding the raw pcre regex info
* u32 - data length of the pcre regex study daya
@@ -214,6 +160,7 @@ static int write_binary_file(struct saved_data *data, int fd)
char *context = specs[i].lr.ctx_raw;
char *regex_str = specs[i].regex_str;
mode_t mode = specs[i].mode;
+ size_t prefix_len = specs[i].prefix_len;
int32_t stem_id = specs[i].stem_id;
pcre *re = specs[i].regex;
pcre_extra *sd = get_pcre_extra(&specs[i]);
@@ -259,6 +206,12 @@ static int write_binary_file(struct saved_data *data, int fd)
if (len != 1)
goto err;
+ /* For SELINUX_COMPILED_FCONTEXT_PREFIX_LEN */
+ to_write = prefix_len;
+ len = fwrite(&to_write, sizeof(to_write), 1, bin_file);
+ if (len != 1)
+ goto err;
+
/* determine the size of the pcre data in bytes */
rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
if (rc < 0)
@@ -301,7 +254,7 @@ err:
goto out;
}
-static int free_specs(struct saved_data *data)
+static void free_specs(struct saved_data *data)
{
struct spec *specs = data->spec_arr;
unsigned int num_entries = data->nspec;
@@ -311,59 +264,144 @@ static int free_specs(struct saved_data *data)
free(specs[i].lr.ctx_raw);
free(specs[i].lr.ctx_trans);
free(specs[i].regex_str);
+ free(specs[i].type_str);
pcre_free(specs[i].regex);
pcre_free_study(specs[i].sd);
}
free(specs);
num_entries = data->num_stems;
- for (i = 0; i < num_entries; i++) {
+ for (i = 0; i < num_entries; i++)
free(data->stem_arr[i].buf);
- }
free(data->stem_arr);
memset(data, 0, sizeof(*data));
- return 0;
+}
+
+static void usage(const char *progname)
+{
+ fprintf(stderr,
+ "usage: %s [-o out_file] [-p policy_file] fc_file\n"
+ "Where:\n\t"
+ "-o Optional file name of the PCRE formatted binary\n\t"
+ " file to be output. If not specified the default\n\t"
+ " will be fc_file with the .bin suffix appended.\n\t"
+ "-p Optional binary policy file that will be used to\n\t"
+ " validate contexts defined in the fc_file.\n\t"
+ "fc_file The text based file contexts file to be processed.\n",
+ progname);
+ exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
- struct saved_data data;
- const char *path;
+ const char *path = NULL;
+ const char *out_file = NULL;
char stack_path[PATH_MAX + 1];
- int rc;
- char *tmp= NULL;
- int fd;
+ char *tmp = NULL;
+ int fd, rc, opt;
+ FILE *policy_fp = NULL;
struct stat buf;
+ struct selabel_handle *rec = NULL;
+ struct saved_data *data = NULL;
+
+ if (argc < 2)
+ usage(argv[0]);
+
+ while ((opt = getopt(argc, argv, "o:p:")) > 0) {
+ switch (opt) {
+ case 'o':
+ out_file = optarg;
+ break;
+ case 'p':
+ policy_file = optarg;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ if (optind >= argc)
+ usage(argv[0]);
- if (argc != 2) {
- fprintf(stderr, "usage: %s input_file\n", argv[0]);
+ path = argv[optind];
+ if (stat(path, &buf) < 0) {
+ fprintf(stderr, "Can not stat: %s: %m\n", path);
exit(EXIT_FAILURE);
}
- memset(&data, 0, sizeof(data));
+ /* Open binary policy if supplied. */
+ if (policy_file) {
+ policy_fp = fopen(policy_file, "r");
- path = argv[1];
+ if (!policy_fp) {
+ fprintf(stderr, "Failed to open policy: %s\n",
+ policy_file);
+ exit(EXIT_FAILURE);
+ }
- if (stat(path, &buf) < 0) {
- fprintf(stderr, "Can not stat: %s: %m\n", path);
+ if (sepol_set_policydb_from_file(policy_fp) < 0) {
+ fprintf(stderr, "Failed to load policy: %s\n",
+ policy_file);
+ fclose(policy_fp);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Generate dummy handle for process_line() function */
+ rec = (struct selabel_handle *)calloc(1, sizeof(*rec));
+ if (!rec) {
+ fprintf(stderr, "Failed to calloc handle\n");
+ if (policy_fp)
+ fclose(policy_fp);
+ exit(EXIT_FAILURE);
+ }
+ rec->backend = SELABEL_CTX_FILE;
+
+ /* Need to set validation on to get the bin file generated by the
+ * process_line function, however as the bin file being generated
+ * may not be related to the currently loaded policy (that it
+ * would be validated against), then set callback to ignore any
+ * validation - unless the -p option is used in which case if an
+ * error is detected, the process will be aborted. */
+ rec->validating = 1;
+ selinux_set_callback(SELINUX_CB_VALIDATE,
+ (union selinux_callback)&validate_context);
+
+ data = (struct saved_data *)calloc(1, sizeof(*data));
+ if (!data) {
+ fprintf(stderr, "Failed to calloc saved_data\n");
+ free(rec);
+ if (policy_fp)
+ fclose(policy_fp);
exit(EXIT_FAILURE);
}
- rc = process_file(&data, path);
+ rec->data = data;
+
+ rc = process_file(rec, path);
if (rc < 0)
- return rc;
+ goto err;
- rc = sort_specs(&data);
+ rc = sort_specs(data);
if (rc)
- return rc;
+ goto err;
+
+ if (out_file)
+ rc = snprintf(stack_path, sizeof(stack_path), "%s", out_file);
+ else
+ rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path);
- rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path);
if (rc < 0 || rc >= (int)sizeof(stack_path))
- return rc;
+ goto err;
- if (asprintf(&tmp, "%sXXXXXX", stack_path) < 0)
- return -1;
+ tmp = malloc(strlen(stack_path) + 7);
+ if (!tmp)
+ goto err;
+
+ rc = sprintf(tmp, "%sXXXXXX", stack_path);
+ if (rc < 0)
+ goto err;
fd = mkstemp(tmp);
if (fd < 0)
@@ -372,23 +410,30 @@ int main(int argc, char *argv[])
rc = fchmod(fd, buf.st_mode);
if (rc < 0) {
perror("fchmod failed to set permission on compiled regexs");
- goto err;
+ goto err_unlink;
}
- rc = write_binary_file(&data, fd);
-
+ rc = write_binary_file(data, fd);
if (rc < 0)
- goto err;
+ goto err_unlink;
- rename(tmp, stack_path);
- rc = free_specs(&data);
+ rc = rename(tmp, stack_path);
if (rc < 0)
- goto err;
+ goto err_unlink;
rc = 0;
out:
+ if (policy_fp)
+ fclose(policy_fp);
+
+ free_specs(data);
+ free(rec);
+ free(data);
free(tmp);
return rc;
+
+err_unlink:
+ unlink(tmp);
err:
rc = -1;
goto out;
diff --git a/libselinux/utils/selabel_digest.c b/libselinux/utils/selabel_digest.c
new file mode 100644
index 00000000..1e9fb34c
--- /dev/null
+++ b/libselinux/utils/selabel_digest.c
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+static size_t digest_len;
+
+static void usage(const char *progname)
+{
+ fprintf(stderr,
+ "usage: %s -b backend [-d] [-v] [-B] [-i] [-f file]\n\n"
+ "Where:\n\t"
+ "-b The backend - \"file\", \"media\", \"x\", \"db\" or "
+ "\"prop\"\n\t"
+ "-v Run \"cat <specfile_list> | openssl dgst -sha1 -hex\"\n\t"
+ " on the list of specfiles to compare the SHA1 digests.\n\t"
+ "-B Use base specfiles only (valid for \"-b file\" only).\n\t"
+ "-i Do not request a digest.\n\t"
+ "-f Optional file containing the specs (defaults to\n\t"
+ " those used by loaded policy).\n\n",
+ progname);
+ exit(1);
+}
+
+static int run_check_digest(char *cmd, char *selabel_digest)
+{
+ FILE *fp;
+ char files_digest[128];
+ char *files_ptr;
+ int rc = 0;
+
+ fp = popen(cmd, "r");
+ if (!fp) {
+ printf("Failed to run command line\n");
+ return -1;
+ }
+
+ /* Only expect one line "(stdin)= x.." so read and find first space */
+ while (fgets(files_digest, sizeof(files_digest) - 1, fp) != NULL)
+ ;
+
+ files_ptr = strstr(files_digest, " ");
+
+ rc = strncmp(selabel_digest, files_ptr + 1, digest_len * 2);
+ if (rc) {
+ printf("Failed validation:\n\tselabel_digest: %s\n\t"
+ "files_digest: %s\n",
+ selabel_digest, files_ptr + 1);
+ } else {
+ printf("Passed validation - digest: %s\n", selabel_digest);
+ }
+
+ pclose(fp);
+ return rc;
+}
+
+int main(int argc, char **argv)
+{
+ int backend = 0, rc, opt, i, validate = 0;
+ char *baseonly = NULL, *file = NULL, *digest = (char *)1;
+ char **specfiles = NULL;
+ unsigned char *sha1_digest = NULL;
+ size_t num_specfiles;
+
+ char cmd_buf[4096];
+ char *cmd_ptr;
+ char *sha1_buf;
+
+ struct selabel_handle *hnd;
+ struct selinux_opt selabel_option[] = {
+ { SELABEL_OPT_PATH, file },
+ { SELABEL_OPT_BASEONLY, baseonly },
+ { SELABEL_OPT_DIGEST, digest }
+ };
+
+ if (argc < 3)
+ usage(argv[0]);
+
+ while ((opt = getopt(argc, argv, "ib:Bvf:")) > 0) {
+ switch (opt) {
+ case 'b':
+ if (!strcasecmp(optarg, "file")) {
+ backend = SELABEL_CTX_FILE;
+ } else if (!strcmp(optarg, "media")) {
+ backend = SELABEL_CTX_MEDIA;
+ } else if (!strcmp(optarg, "x")) {
+ backend = SELABEL_CTX_X;
+ } else if (!strcmp(optarg, "db")) {
+ backend = SELABEL_CTX_DB;
+ } else if (!strcmp(optarg, "prop")) {
+ backend = SELABEL_CTX_ANDROID_PROP;
+ } else {
+ fprintf(stderr, "Unknown backend: %s\n",
+ optarg);
+ usage(argv[0]);
+ }
+ break;
+ case 'B':
+ baseonly = (char *)1;
+ break;
+ case 'v':
+ validate = 1;
+ break;
+ case 'i':
+ digest = NULL;
+ break;
+ case 'f':
+ file = optarg;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+
+ memset(cmd_buf, 0, sizeof(cmd_buf));
+
+ selabel_option[0].value = file;
+ selabel_option[1].value = baseonly;
+ selabel_option[2].value = digest;
+
+ hnd = selabel_open(backend, selabel_option, 3);
+ if (!hnd) {
+ switch (errno) {
+ case EOVERFLOW:
+ fprintf(stderr, "ERROR Number of specfiles or specfile"
+ " buffer caused an overflow.\n");
+ break;
+ default:
+ fprintf(stderr, "ERROR: selabel_open: %s\n",
+ strerror(errno));
+ }
+ return -1;
+ }
+
+ rc = selabel_digest(hnd, &sha1_digest, &digest_len, &specfiles,
+ &num_specfiles);
+
+ if (rc) {
+ switch (errno) {
+ case EINVAL:
+ fprintf(stderr, "No digest available.\n");
+ break;
+ default:
+ fprintf(stderr, "selabel_digest ERROR: %s\n",
+ strerror(errno));
+ }
+ goto err;
+ }
+
+ sha1_buf = malloc(digest_len * 2 + 1);
+ if (!sha1_buf) {
+ fprintf(stderr, "Could not malloc buffer ERROR: %s\n",
+ strerror(errno));
+ rc = -1;
+ goto err;
+ }
+
+ printf("SHA1 digest: ");
+ for (i = 0; i < digest_len; i++)
+ sprintf(&(sha1_buf[i * 2]), "%02x", sha1_digest[i]);
+
+ printf("%s\n", sha1_buf);
+ printf("calculated using the following specfile(s):\n");
+
+ if (specfiles) {
+ cmd_ptr = &cmd_buf[0];
+ sprintf(cmd_ptr, "/usr/bin/cat ");
+ cmd_ptr = &cmd_buf[0] + strlen(cmd_buf);
+
+ for (i = 0; i < num_specfiles; i++) {
+ sprintf(cmd_ptr, "%s ", specfiles[i]);
+ cmd_ptr += strlen(specfiles[i]) + 1;
+ printf("%s\n", specfiles[i]);
+ }
+ sprintf(cmd_ptr, "| /usr/bin/openssl dgst -sha1 -hex");
+
+ if (validate)
+ rc = run_check_digest(cmd_buf, sha1_buf);
+ }
+
+ free(sha1_buf);
+err:
+ selabel_close(hnd);
+ return rc;
+}
diff --git a/libsemanage/ChangeLog b/libsemanage/ChangeLog
index 217c3e7d..b55a028c 100644
--- a/libsemanage/ChangeLog
+++ b/libsemanage/ChangeLog
@@ -1,3 +1,12 @@
+ * semanage_migrate_store: Load libsepol.so.1 instead of libsepol.so, from Laurent Bigonville.
+ * Store homedir_template and users_extra in policy store, from Steve Lawrence
+ * Fix null pointer dereference in semanage_module_key_destroy, from Yuli Khodorkovskiy.
+ * Add semanage_module_extract() to extract a module as CIL or HLL, from Yuli Khodorkovskiy.
+ * semanage_migrate_store: add -r <root> option for migrating inside chroots, from Petr Lautrbach.
+ * Add file_contexts and seusers to the store, from Yuli Khodorkovskiy.
+ * Add policy binary and file_contexts.local to the store, from Yuli Khodorkovskiy.
+ * Allow to install compressed modules without a compression extension,
+ from Petr Lautrbach.
* Do not copy contexts in semanage_migrate_store, from Jason Zaman.
* Fix logic in bunzip for uncompressed pp files, from Thomas Hurd.
* Fix fname[] initialization in test_utilities.c, from Petr Lautrbach.
diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
index 4267bd29..4b93e54e 100644
--- a/libsemanage/include/semanage/modules.h
+++ b/libsemanage/include/semanage/modules.h
@@ -24,6 +24,7 @@
#include <stddef.h>
#include <stdint.h>
#include <semanage/handle.h>
+#include <sys/types.h>
typedef struct semanage_module_key semanage_module_key_t;
@@ -41,6 +42,22 @@ int semanage_module_remove(semanage_handle_t *, char *module_name);
modules, only name at this time */
typedef struct semanage_module_info semanage_module_info_t;
+/* Look up a module using @modkey. The module's raw data is returned as a
+ * @mapped_data blob and size of the mapped_data is returned as @data_len.
+ * @modinfo contains additional information which can be used by the caller such
+ * as the high level language extension of @mapped_data.
+ *
+ * On success, the caller is responsible for unmapping @mapped_data with munmap(),
+ * destroying @modinfo with semanage_module_info_destroy(), and freeing @modinfo.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int semanage_module_extract(semanage_handle_t *sh,
+ semanage_module_key_t *modkey,
+ int extract_cil,
+ void **mapped_data,
+ size_t *data_len,
+ semanage_module_info_t **modinfo);
int semanage_module_list(semanage_handle_t *,
semanage_module_info_t **, int *num_modules);
void semanage_module_info_datum_destroy(semanage_module_info_t *);
diff --git a/libsemanage/src/booleans_policydb.c b/libsemanage/src/booleans_policydb.c
index 74af2a33..6869d6cd 100644
--- a/libsemanage/src/booleans_policydb.c
+++ b/libsemanage/src/booleans_policydb.c
@@ -55,10 +55,8 @@ int bool_policydb_dbase_init(semanage_handle_t * handle,
{
if (dbase_policydb_init(handle,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_KERNEL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
&SEMANAGE_BOOL_RTABLE,
&SEMANAGE_BOOL_POLICYDB_RTABLE,
&dconfig->dbase) < 0)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index e4f168e9..68dd0d18 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -66,6 +66,12 @@ static int semanage_direct_commit(semanage_handle_t * sh);
static int semanage_direct_install(semanage_handle_t * sh, char *data,
size_t data_len, const char *module_name, const char *lang_ext);
static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
+static int semanage_direct_extract(semanage_handle_t * sh,
+ semanage_module_key_t *modkey,
+ int extract_cil,
+ void **mapped_data,
+ size_t *data_len,
+ semanage_module_info_t **modinfo);
static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
static int semanage_direct_list(semanage_handle_t * sh,
semanage_module_info_t ** modinfo,
@@ -100,6 +106,7 @@ static struct semanage_policy_table direct_funcs = {
.begin_trans = semanage_direct_begintrans,
.commit = semanage_direct_commit,
.install = semanage_direct_install,
+ .extract = semanage_direct_extract,
.install_file = semanage_direct_install_file,
.remove = semanage_direct_remove,
.list = semanage_direct_list,
@@ -196,10 +203,8 @@ int semanage_direct_connect(semanage_handle_t * sh)
goto err;
if (fcontext_file_dbase_init(sh,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_FC_LOCAL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_FC_LOCAL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_LOCAL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
semanage_fcontext_dbase_local(sh)) < 0)
goto err;
@@ -250,18 +255,14 @@ int semanage_direct_connect(semanage_handle_t * sh)
goto err;
if (fcontext_file_dbase_init(sh,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_FC),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_FC),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
semanage_fcontext_dbase_policy(sh)) < 0)
goto err;
if (seuser_file_dbase_init(sh,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_SEUSERS),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_SEUSERS),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_SEUSERS),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
semanage_seuser_dbase_policy(sh)) < 0)
goto err;
@@ -502,15 +503,32 @@ exit:
* the file into '*data'.
* Returns the total number of bytes in memory .
* Returns -1 if file could not be opened or mapped. */
-static ssize_t map_file(semanage_handle_t *sh, int fd, char **data,
+static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
int *compressed)
{
ssize_t size = -1;
char *uncompress;
- if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) {
+ int fd = -1;
+ FILE *file = NULL;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ ERR(sh, "Unable to open %s\n", path);
+ return -1;
+ }
+
+ file = fdopen(fd, "r");
+ if (file == NULL) {
+ ERR(sh, "Unable to open %s\n", path);
+ close(fd);
+ return -1;
+ }
+
+ if ((size = bunzip(sh, file, &uncompress)) > 0) {
*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
if (*data == MAP_FAILED) {
free(uncompress);
+ fclose(file);
return -1;
} else {
memcpy(*data, uncompress, size);
@@ -529,6 +547,8 @@ static ssize_t map_file(semanage_handle_t *sh, int fd, char **data,
*compressed = 0;
}
+ fclose(file);
+
return size;
}
@@ -604,7 +624,7 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb
}
if (size > 0) {
- ofilename = semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS);
+ ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
if (ofilename == NULL) {
return -1;
}
@@ -892,9 +912,8 @@ cleanup:
return ret;
}
-static int semanage_compile_hll(semanage_handle_t *sh,
- semanage_module_info_t *modinfos,
- int num_modinfos)
+static int semanage_compile_module(semanage_handle_t *sh,
+ semanage_module_info_t *modinfo)
{
char cil_path[PATH_MAX];
char hll_path[PATH_MAX];
@@ -907,125 +926,132 @@ static int semanage_compile_hll(semanage_handle_t *sh,
ssize_t hll_data_len = 0;
ssize_t bzip_status;
int status = 0;
- int i, compressed;
- int in_fd = -1;
+ int compressed;
size_t cil_data_len;
size_t err_data_len;
- assert(sh);
- assert(modinfos);
+ if (!strcasecmp(modinfo->lang_ext, "cil")) {
+ goto cleanup;
+ }
- for (i = 0; i < num_modinfos; i++) {
- if (!strcasecmp(modinfos[i].lang_ext, "cil")) {
- continue;
- }
+ status = semanage_get_hll_compiler_path(sh, modinfo->lang_ext, &compiler_path);
+ if (status != 0) {
+ goto cleanup;
+ }
- status = semanage_module_get_path(
- sh,
- &modinfos[i],
- SEMANAGE_MODULE_PATH_CIL,
- cil_path,
- sizeof(cil_path));
- if (status != 0) {
- goto cleanup;
+ status = semanage_module_get_path(
+ sh,
+ modinfo,
+ SEMANAGE_MODULE_PATH_CIL,
+ cil_path,
+ sizeof(cil_path));
+ if (status != 0) {
+ goto cleanup;
+ }
+
+ status = semanage_module_get_path(
+ sh,
+ modinfo,
+ SEMANAGE_MODULE_PATH_HLL,
+ hll_path,
+ sizeof(hll_path));
+ if (status != 0) {
+ goto cleanup;
+ }
+
+ if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
+ ERR(sh, "Unable to read file %s\n", hll_path);
+ status = -1;
+ goto cleanup;
+ }
+
+ status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
+ if (err_data_len > 0) {
+ for (start = end = err_data; end < err_data + err_data_len; end++) {
+ if (*end == '\n') {
+ fprintf(stderr, "%s: ", modinfo->name);
+ fwrite(start, 1, end - start + 1, stderr);
+ start = end + 1;
+ }
}
- if (semanage_get_ignore_module_cache(sh) == 0 &&
- access(cil_path, F_OK) == 0) {
- continue;
+ if (end != start) {
+ fprintf(stderr, "%s: ", modinfo->name);
+ fwrite(start, 1, end - start, stderr);
+ fprintf(stderr, "\n");
}
+ }
+ if (status != 0) {
+ goto cleanup;
+ }
- status = semanage_get_hll_compiler_path(sh, modinfos[i].lang_ext, &compiler_path);
+ bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
+ if (bzip_status == -1) {
+ ERR(sh, "Failed to bzip %s\n", cil_path);
+ status = -1;
+ goto cleanup;
+ }
+
+ if (sh->conf->remove_hll == 1) {
+ status = unlink(hll_path);
if (status != 0) {
+ ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
goto cleanup;
}
- status = semanage_module_get_path(
- sh,
- &modinfos[i],
- SEMANAGE_MODULE_PATH_HLL,
- hll_path,
- sizeof(hll_path));
+ status = semanage_direct_write_langext(sh, "cil", modinfo);
if (status != 0) {
goto cleanup;
}
+ }
- if ((in_fd = open(hll_path, O_RDONLY)) == -1) {
- ERR(sh, "Unable to open %s\n", hll_path);
- status = -1;
- goto cleanup;
- }
+cleanup:
+ if (hll_data_len > 0) {
+ munmap(hll_data, hll_data_len);
+ }
+ free(cil_data);
+ free(err_data);
+ free(compiler_path);
- if ((hll_data_len = map_file(sh, in_fd, &hll_data, &compressed)) <= 0) {
- ERR(sh, "Unable to read file %s\n", hll_path);
- status = -1;
- goto cleanup;
- }
+ return status;
+}
- if (in_fd >= 0) close(in_fd);
- in_fd = -1;
+static int semanage_compile_hll_modules(semanage_handle_t *sh,
+ semanage_module_info_t *modinfos,
+ int num_modinfos)
+{
+ int status = 0;
+ int i;
+ char cil_path[PATH_MAX];
- status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
- if (err_data_len > 0) {
- for (start = end = err_data; end < err_data + err_data_len; end++) {
- if (*end == '\n') {
- fprintf(stderr, "%s: ", modinfos[i].name);
- fwrite(start, 1, end - start + 1, stderr);
- start = end + 1;
- }
- }
+ assert(sh);
+ assert(modinfos);
- if (end != start) {
- fprintf(stderr, "%s: ", modinfos[i].name);
- fwrite(start, 1, end - start, stderr);
- fprintf(stderr, "\n");
- }
- }
+ for (i = 0; i < num_modinfos; i++) {
+ status = semanage_module_get_path(
+ sh,
+ &modinfos[i],
+ SEMANAGE_MODULE_PATH_CIL,
+ cil_path,
+ sizeof(cil_path));
if (status != 0) {
goto cleanup;
}
- if (sh->conf->remove_hll == 1) {
- status = unlink(hll_path);
- if (status != 0) {
- ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
- goto cleanup;
- }
-
- status = semanage_direct_write_langext(sh, "cil", &modinfos[i]);
- if (status != 0) {
- goto cleanup;
- }
+ if (semanage_get_ignore_module_cache(sh) == 0 &&
+ access(cil_path, F_OK) == 0) {
+ continue;
}
- bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
- if (bzip_status == -1) {
- ERR(sh, "Failed to bzip %s\n", cil_path);
- status = -1;
+ status = semanage_compile_module(sh, &modinfos[i]);
+ if (status < 0) {
goto cleanup;
}
-
- if (hll_data_len > 0) munmap(hll_data, hll_data_len);
- hll_data_len = 0;
-
- free(cil_data);
- free(err_data);
- free(compiler_path);
- cil_data = NULL;
- err_data = NULL;
- compiler_path = NULL;
- cil_data_len = 0;
- err_data_len = 0;
}
status = 0;
cleanup:
- if (hll_data_len > 0) munmap(hll_data, hll_data_len);
- if (in_fd >= 0) close(in_fd);
- free(cil_data);
- free(err_data);
- free(compiler_path);
return status;
}
@@ -1041,7 +1067,8 @@ static int semanage_direct_commit(semanage_handle_t * sh)
size_t fc_buffer_len = 0;
const char *ofilename = NULL;
const char *path;
- int retval = -1, num_modinfos = 0, i;
+ int retval = -1, num_modinfos = 0, i, missing_policy_kern = 0,
+ missing_seusers = 0, missing_fc = 0, missing = 0;
sepol_policydb_t *out = NULL;
struct cil_db *cildb = NULL;
semanage_module_info_t *modinfos = NULL;
@@ -1143,8 +1170,36 @@ static int semanage_direct_commit(semanage_handle_t * sh)
modified |= dontaudit_modified;
modified |= preserve_tunables_modified;
+ /* This is for systems that have already migrated with an older version
+ * of semanage_migrate_store. The older version did not copy policy.kern so
+ * the policy binary must be rebuilt here.
+ */
+ if (!sh->do_rebuild && !modified) {
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL);
+
+ if (access(path, F_OK) != 0) {
+ missing_policy_kern = 1;
+ }
+
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
+
+ if (access(path, F_OK) != 0) {
+ missing_fc = 1;
+ }
+
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
+
+ if (access(path, F_OK) != 0) {
+ missing_seusers = 1;
+ }
+ }
+
+ missing |= missing_policy_kern;
+ missing |= missing_fc;
+ missing |= missing_seusers;
+
/* If there were policy changes, or explicitly requested, rebuild the policy */
- if (sh->do_rebuild || modified) {
+ if (sh->do_rebuild || modified || missing) {
/* =================== Module expansion =============== */
retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
@@ -1156,7 +1211,7 @@ static int semanage_direct_commit(semanage_handle_t * sh)
goto cleanup;
}
- retval = semanage_compile_hll(sh, modinfos, num_modinfos);
+ retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos);
if (retval < 0) {
ERR(sh, "Failed to compile hll files into cil files.\n");
goto cleanup;
@@ -1217,6 +1272,9 @@ static int semanage_direct_commit(semanage_handle_t * sh)
if (retval < 0)
goto cleanup;
+ /* remove FC_TMPL now that it is now longer needed */
+ unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
+
pfcontexts->dtable->drop_cache(pfcontexts->dbase);
/* SEUsers */
@@ -1302,6 +1360,43 @@ static int semanage_direct_commit(semanage_handle_t * sh)
if (retval < 0)
goto cleanup;
+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
+ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
+ sh->conf->file_mode);
+ if (retval < 0) {
+ goto cleanup;
+ }
+
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL);
+ if (access(path, F_OK) == 0) {
+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
+ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
+ sh->conf->file_mode);
+ if (retval < 0) {
+ goto cleanup;
+ }
+ }
+
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
+ if (access(path, F_OK) == 0) {
+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
+ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
+ sh->conf->file_mode);
+ if (retval < 0) {
+ goto cleanup;
+ }
+ }
+
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
+ if (access(path, F_OK) == 0) {
+ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
+ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
+ sh->conf->file_mode);
+ if (retval < 0) {
+ goto cleanup;
+ }
+ }
+
/* run genhomedircon if its enabled, this should be the last operation
* which requires the out policydb */
if (!sh->conf->disable_genhomedircon) {
@@ -1321,11 +1416,6 @@ static int semanage_direct_commit(semanage_handle_t * sh)
sepol_policydb_free(out);
out = NULL;
- /* remove files that are automatically generated and no longer needed */
- unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
- unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL));
- unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA));
-
if (sh->do_rebuild || modified || bools_modified || fcontexts_modified) {
retval = semanage_install_sandbox(sh);
}
@@ -1432,19 +1522,12 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
char *data = NULL;
ssize_t data_len = 0;
int compressed = 0;
- int in_fd = -1;
char *path = NULL;
char *filename;
- char *lang_ext;
+ char *lang_ext = NULL;
char *separator;
- if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
- ERR(sh, "Unable to open %s: %s\n", install_filename, strerror(errno));
- retval = -1;
- goto cleanup;
- }
-
- if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
+ if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
ERR(sh, "Unable to read file %s\n", install_filename);
retval = -1;
goto cleanup;
@@ -1467,30 +1550,114 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
goto cleanup;
}
*separator = '\0';
+ lang_ext = separator + 1;
}
separator = strrchr(filename, '.');
if (separator == NULL) {
- ERR(sh, "Module does not have a valid extension.");
- retval = -1;
- goto cleanup;
+ if (lang_ext == NULL) {
+ ERR(sh, "Module does not have a valid extension.");
+ retval = -1;
+ goto cleanup;
+ }
+ } else {
+ *separator = '\0';
+ lang_ext = separator + 1;
}
- *separator = '\0';
-
- lang_ext = separator + 1;
retval = semanage_direct_install(sh, data, data_len, filename, lang_ext);
cleanup:
- if (in_fd != -1) {
- close(in_fd);
- }
if (data_len > 0) munmap(data, data_len);
free(path);
return retval;
}
+static int semanage_direct_extract(semanage_handle_t * sh,
+ semanage_module_key_t *modkey,
+ int extract_cil,
+ void **mapped_data,
+ size_t *data_len,
+ semanage_module_info_t **modinfo)
+{
+ char module_path[PATH_MAX];
+ char input_file[PATH_MAX];
+ enum semanage_module_path_type file_type;
+ int rc = -1;
+ semanage_module_info_t *_modinfo = NULL;
+ ssize_t _data_len;
+ char *_data;
+ int compressed;
+
+ /* get path of module */
+ rc = semanage_module_get_path(
+ sh,
+ (const semanage_module_info_t *)modkey,
+ SEMANAGE_MODULE_PATH_NAME,
+ module_path,
+ sizeof(module_path));
+ if (rc != 0) {
+ goto cleanup;
+ }
+
+ if (access(module_path, F_OK) != 0) {
+ ERR(sh, "Module does not exist: %s", module_path);
+ rc = -1;
+ goto cleanup;
+ }
+
+ rc = semanage_module_get_module_info(sh,
+ modkey,
+ &_modinfo);
+ if (rc != 0) {
+ goto cleanup;
+ }
+
+ if (extract_cil || strcmp(_modinfo->lang_ext, "cil") == 0) {
+ file_type = SEMANAGE_MODULE_PATH_CIL;
+ } else {
+ file_type = SEMANAGE_MODULE_PATH_HLL;
+ }
+
+ /* get path of what to extract */
+ rc = semanage_module_get_path(
+ sh,
+ _modinfo,
+ file_type,
+ input_file,
+ sizeof(input_file));
+ if (rc != 0) {
+ goto cleanup;
+ }
+
+ if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && access(input_file, F_OK) != 0) {
+ rc = semanage_compile_module(sh, _modinfo);
+ if (rc < 0) {
+ goto cleanup;
+ }
+ }
+
+ _data_len = map_file(sh, input_file, &_data, &compressed);
+ if (_data_len <= 0) {
+ ERR(sh, "Error mapping file: %s", input_file);
+ rc = -1;
+ goto cleanup;
+ }
+
+ *modinfo = _modinfo;
+ *data_len = (size_t)_data_len;
+ *mapped_data = _data;
+
+cleanup:
+ if (rc != 0) {
+ semanage_module_info_destroy(sh, _modinfo);
+ free(_modinfo);
+ }
+
+ return rc;
+}
+
/* Removes a module from the sandbox. Returns 0 on success, -1 if out
* of memory, -2 if module not found or could not be removed. */
static int semanage_direct_remove(semanage_handle_t * sh, char *module_name)
diff --git a/libsemanage/src/interfaces_policydb.c b/libsemanage/src/interfaces_policydb.c
index 6a42eedf..552ce7d5 100644
--- a/libsemanage/src/interfaces_policydb.c
+++ b/libsemanage/src/interfaces_policydb.c
@@ -51,10 +51,8 @@ int iface_policydb_dbase_init(semanage_handle_t * handle,
{
if (dbase_policydb_init(handle,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_KERNEL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
&SEMANAGE_IFACE_RTABLE,
&SEMANAGE_IFACE_POLICYDB_RTABLE,
&dconfig->dbase) < 0)
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 70f57f9d..34b553d1 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -30,6 +30,7 @@ LIBSEMANAGE_1.0 {
LIBSEMANAGE_1.1 {
global:
semanage_module_install;
+ semanage_module_extract;
semanage_get_hll_compiler_path;
semanage_get_ignore_module_cache;
semanage_set_ignore_module_cache;
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index d29c3469..90c5e491 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -142,6 +142,23 @@ int semanage_module_install_file(semanage_handle_t * sh,
return sh->funcs->install_file(sh, module_name);
}
+int semanage_module_extract(semanage_handle_t * sh,
+ semanage_module_key_t *modkey,
+ int extract_cil,
+ void **mapped_data,
+ size_t *data_len,
+ semanage_module_info_t **modinfo) {
+ if (sh->funcs->extract == NULL) {
+ ERR(sh,
+ "No get function defined for this connection type.");
+ return -1;
+ } else if (!sh->is_connected) {
+ ERR(sh, "Not connected.");
+ return -1;
+ }
+ return sh->funcs->extract(sh, modkey, extract_cil, mapped_data, data_len, modinfo);
+}
+
/* Legacy function that remains to preserve ABI
* compatibility. Please use semanage_module_install instead.
*/
@@ -673,10 +690,12 @@ int semanage_module_key_destroy(semanage_handle_t *sh,
{
assert(sh);
- if (modkey) {
- free(modkey->name);
+ if (!modkey) {
+ return 0;
}
+ free(modkey->name);
+
return semanage_module_key_init(sh, modkey);
}
diff --git a/libsemanage/src/nodes_policydb.c b/libsemanage/src/nodes_policydb.c
index 56012fbf..7224f008 100644
--- a/libsemanage/src/nodes_policydb.c
+++ b/libsemanage/src/nodes_policydb.c
@@ -50,10 +50,8 @@ int node_policydb_dbase_init(semanage_handle_t * handle,
{
if (dbase_policydb_init(handle,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_KERNEL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
&SEMANAGE_NODE_RTABLE,
&SEMANAGE_NODE_POLICYDB_RTABLE,
&dconfig->dbase) < 0)
diff --git a/libsemanage/src/policy.h b/libsemanage/src/policy.h
index c5aec386..f1271560 100644
--- a/libsemanage/src/policy.h
+++ b/libsemanage/src/policy.h
@@ -52,6 +52,14 @@ struct semanage_policy_table {
/* Install a policy module */
int (*install_file) (struct semanage_handle *, const char *);
+ /* Extract a policy module */
+ int (*extract) (struct semanage_handle *,
+ semanage_module_key_t *,
+ int extract_cil,
+ void **,
+ size_t *,
+ semanage_module_info_t **);
+
/* Remove a policy module */
int (*remove) (struct semanage_handle *, char *);
diff --git a/libsemanage/src/ports_policydb.c b/libsemanage/src/ports_policydb.c
index b9600f05..37d7deb2 100644
--- a/libsemanage/src/ports_policydb.c
+++ b/libsemanage/src/ports_policydb.c
@@ -50,10 +50,8 @@ int port_policydb_dbase_init(semanage_handle_t * handle,
{
if (dbase_policydb_init(handle,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_KERNEL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
&SEMANAGE_PORT_RTABLE,
&SEMANAGE_PORT_POLICYDB_RTABLE,
&dconfig->dbase) < 0)
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 6051691b..fa0876fa 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -110,10 +110,14 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
"/disable_dontaudit",
"/preserve_tunables",
"/modules/disabled",
+ "/policy.kern",
+ "/file_contexts.local",
+ "/file_contexts",
+ "/seusers"
};
static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = {
- "/tmp",
+ "/final",
"",
};
@@ -664,7 +668,7 @@ static int semanage_filename_select(const struct dirent *d)
/* Copies a file from src to dst. If dst already exists then
* overwrite it. Returns 0 on success, -1 on error. */
-static int semanage_copy_file(const char *src, const char *dst, mode_t mode)
+int semanage_copy_file(const char *src, const char *dst, mode_t mode)
{
int in, out, retval = 0, amount_read, n, errsv = errno;
char tmp[PATH_MAX];
@@ -943,9 +947,7 @@ int semanage_make_final(semanage_handle_t *sh)
goto cleanup;
}
- /* Copy in exported databases.
- * i = 1 to avoid copying the top level directory.
- */
+ // Build final directory structure
int i;
for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) {
if (strlen(semanage_final_path(SEMANAGE_FINAL_TMP, i)) >= sizeof(fn)) {
@@ -959,12 +961,6 @@ int semanage_make_final(semanage_handle_t *sh)
status = -1;
goto cleanup;
}
-
- semanage_copy_file(
- semanage_final_path(SEMANAGE_FINAL_SELINUX, i),
- semanage_final_path(SEMANAGE_FINAL_TMP, i),
- sh->conf->file_mode);
- /* ignore errors, these files may not exist */
}
cleanup:
@@ -1431,11 +1427,11 @@ int semanage_split_fc(semanage_handle_t * sh)
goto cleanup;
}
- fc = open(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
+ fc = open(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fc < 0) {
ERR(sh, "Could not open %s for writing.",
- semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC));
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
goto cleanup;
}
hd = open(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL),
@@ -1460,8 +1456,7 @@ int semanage_split_fc(semanage_handle_t * sh)
} else {
if (write(fc, buf, strlen(buf)) < 0) {
ERR(sh, "Write to %s failed.",
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_FC));
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
goto cleanup;
}
}
@@ -2019,8 +2014,7 @@ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in)
FILE *infile = NULL;
if ((kernel_filename =
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL)) == NULL) {
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL)) == NULL) {
goto cleanup;
}
if ((infile = fopen(kernel_filename, "r")) == NULL) {
@@ -2061,7 +2055,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out)
FILE *outfile = NULL;
if ((kernel_filename =
- semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL)) == NULL) {
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL)) == NULL) {
goto cleanup;
}
if ((outfile = fopen(kernel_filename, "wb")) == NULL) {
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 62c7079b..acb6e3fd 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -55,6 +55,10 @@ enum semanage_sandbox_defs {
SEMANAGE_DISABLE_DONTAUDIT,
SEMANAGE_PRESERVE_TUNABLES,
SEMANAGE_MODULES_DISABLED,
+ SEMANAGE_STORE_KERNEL,
+ SEMANAGE_STORE_FC_LOCAL,
+ SEMANAGE_STORE_FC,
+ SEMANAGE_STORE_SEUSERS,
SEMANAGE_STORE_NUM_PATHS
};
@@ -148,4 +152,6 @@ int semanage_nc_sort(semanage_handle_t * sh,
size_t buf_len,
char **sorted_buf, size_t * sorted_buf_len);
+int semanage_copy_file(const char *src, const char *dst, mode_t mode);
+
#endif
diff --git a/libsemanage/src/semanageswig_python.i b/libsemanage/src/semanageswig_python.i
index 06b9408e..1346b2ea 100644
--- a/libsemanage/src/semanageswig_python.i
+++ b/libsemanage/src/semanageswig_python.i
@@ -23,6 +23,7 @@
%header %{
#include <stdlib.h>
#include <semanage/semanage.h>
+ #include <sys/mman.h>
#define STATUS_SUCCESS 0
#define STATUS_ERR -1
@@ -103,6 +104,10 @@
%apply int *OUTPUT { unsigned int * };
%apply int *OUTPUT { uint16_t * };
+%include <cstring.i>
+/* This is needed to properly mmaped binary data in SWIG */
+%cstring_output_allocate_size(void **mapped_data, size_t *data_len, munmap(*$1, *$2));
+
%typemap(in, numinputs=0) char **(char *temp=NULL) {
$1 = &temp;
}
diff --git a/libsemanage/src/users_base_policydb.c b/libsemanage/src/users_base_policydb.c
index 0a6ab9cd..b42279c8 100644
--- a/libsemanage/src/users_base_policydb.c
+++ b/libsemanage/src/users_base_policydb.c
@@ -50,10 +50,8 @@ int user_base_policydb_dbase_init(semanage_handle_t * handle,
{
if (dbase_policydb_init(handle,
- semanage_final_path(SEMANAGE_FINAL_SELINUX,
- SEMANAGE_KERNEL),
- semanage_final_path(SEMANAGE_FINAL_TMP,
- SEMANAGE_KERNEL),
+ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
&SEMANAGE_USER_BASE_RTABLE,
&SEMANAGE_USER_BASE_POLICYDB_RTABLE,
&dconfig->dbase) < 0)
diff --git a/libsemanage/utils/semanage_migrate_store b/libsemanage/utils/semanage_migrate_store
index 2f85e9c5..0ebd2852 100755
--- a/libsemanage/utils/semanage_migrate_store
+++ b/libsemanage/utils/semanage_migrate_store
@@ -10,7 +10,7 @@ from optparse import OptionParser
import ctypes
-sepol = ctypes.cdll.LoadLibrary('libsepol.so')
+sepol = ctypes.cdll.LoadLibrary('libsepol.so.1')
try:
import selinux
@@ -180,7 +180,7 @@ def rebuild_policy():
def oldroot_path():
- return "/etc/selinux"
+ return "%s/etc/selinux" % ROOT
def oldstore_path(store):
return "%s/%s/modules/active" % (oldroot_path(), store)
@@ -192,7 +192,7 @@ def disabledmodules_path(store):
return "%s/disabled" % newmodules_path(store)
def newroot_path():
- return PATH
+ return "%s%s" % (ROOT, PATH)
def newstore_path(store):
return "%s/%s/active" % (newroot_path(), store)
@@ -219,6 +219,8 @@ if __name__ == "__main__":
help="Disable rebuilding policy after migration (default: no)")
parser.add_option("-P", "--path", dest="path",
help="Set path for the policy store (default: /var/lib/selinux)")
+ parser.add_option("-r", "--root", dest="root",
+ help="Set an alternative root for the migration (default: /)")
(options, args) = parser.parse_args()
@@ -231,6 +233,10 @@ if __name__ == "__main__":
if PATH is None:
PATH = "/var/lib/selinux"
+ ROOT = options.root
+ if ROOT is None:
+ ROOT = ""
+
# List of paths that go in the active 'root'
TOPPATHS = [
"commit_num",
@@ -241,9 +247,13 @@ if __name__ == "__main__":
"file_contexts.local",
"seusers",
"users.local",
+ "users_extra",
"users_extra.local",
"disable_dontaudit",
- "preserve_tunables" ]
+ "preserve_tunables",
+ "policy.kern",
+ "file_contexts",
+ "homedir_template"]
create_dir(newroot_path(), 0o755)
diff --git a/libsepol/Android.mk b/libsepol/Android.mk
index 45eaafca..430d8599 100644
--- a/libsepol/Android.mk
+++ b/libsepol/Android.mk
@@ -46,6 +46,7 @@ cil_src_files := \
cil/src/cil_build_ast.c \
cil/src/cil.c \
cil/src/cil_copy_ast.c \
+ cil/src/cil_find.c \
cil/src/cil_fqn.c \
cil/src/cil_lexer.l \
cil/src/cil_list.c \
diff --git a/libsepol/ChangeLog b/libsepol/ChangeLog
index 26b99dc7..c5c97f25 100644
--- a/libsepol/ChangeLog
+++ b/libsepol/ChangeLog
@@ -1,8 +1,25 @@
+ * Add neverallow support for ioctl extended permissions, from Jeff Vander Stoep.
+ * Improve CIL block and macro call recursion detection, from Steve Lawrence
+ * Fix CIL uninitialized false positive in cil_binary, from Yuli Khodorkovskiy
+ * Provide error in CIL if classperms are empty, from Yuli Khodorkovskiy
+ * Add userattribute{set} functionality to CIL, from Yuli Khodorkovskiy
+ * fix CIL blockinherit copying segfault and add macro restrictions, from Steve Lawrence
+ * fix CIL NULL pointer dereference when copying classpermission/set, from Steve Lawrence
+ * Add CIL support for ioctl whitelists, from Steve Lawrence
+ * Fix memory leak when destroying avtab, from Steve Lawrence
+ * Replace sscanf in module_to_cil, from Yuli Khodorkovskiy.
+ * Improve CIL resolution error messages, from Steve Lawrence
+ * Fix policydb_read for policy versions < 24, from Stephen Smalley.
+ * Added CIL bounds checking and refactored CIL Neverallow checking, from James Carter
+ * Refactored libsepol Neverallow and bounds (hierarchy) checking, from James Carter
+ * Treat types like an attribute in the attr_type_map, from James Carter
+ * Add new ebitmap function named ebitmap_match_any(), from James Carter
+ * switch operations to extended perms, from Jeff Vander Stoep.
* Write auditadm_r and secadm_r roles to base module when writing CIL, from Steve Lawrence
* Fix module to CIL to only associate declared roleattributes with in-scope types, from Steve Lawrence
* Don't allow categories/sensitivities inside blocks in CIL, from Yuli Khodorkovskiy.
* Replace fmemopen() with internal function in libsepol, from James Carter.
- * Verify users prior to evaluating users in cil, from Yuli Khodorkovskiy.
+ * Verify users prior to evaluating users in cil, from Yuli Khodorkovskiy.
* Binary modules do not support ioctl rules, from Stephen Smalley.
* Add support for ioctl command whitelisting, from Jeff Vander Stoep.
* Don't use symbol versioning for static object files, from Yuli Khodorkovskiy.
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 5c53bf33..8716debb 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -70,11 +70,11 @@ asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1"
#endif
int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
- {64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+ {64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
+ {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
static void cil_init_keys(void)
@@ -122,6 +122,8 @@ static void cil_init_keys(void)
CIL_KEY_TYPE = cil_strpool_add("type");
CIL_KEY_ROLE = cil_strpool_add("role");
CIL_KEY_USER = cil_strpool_add("user");
+ CIL_KEY_USERATTRIBUTE = cil_strpool_add("userattribute");
+ CIL_KEY_USERATTRIBUTESET = cil_strpool_add("userattributeset");
CIL_KEY_SENSITIVITY = cil_strpool_add("sensitivity");
CIL_KEY_CATEGORY = cil_strpool_add("category");
CIL_KEY_CATSET = cil_strpool_add("categoryset");
@@ -223,6 +225,11 @@ static void cil_init_keys(void)
CIL_KEY_ROOT = cil_strpool_add("<root>");
CIL_KEY_NODE = cil_strpool_add("<node>");
CIL_KEY_PERM = cil_strpool_add("perm");
+ CIL_KEY_ALLOWX = cil_strpool_add("allowx");
+ CIL_KEY_AUDITALLOWX = cil_strpool_add("auditallowx");
+ CIL_KEY_DONTAUDITX = cil_strpool_add("dontauditx");
+ CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx");
+ CIL_KEY_IOCTL = cil_strpool_add("ioctl");
}
void cil_db_init(struct cil_db **db)
@@ -257,12 +264,15 @@ void cil_db_init(struct cil_db **db)
cil_type_init(&(*db)->selftype);
(*db)->selftype->datum.name = CIL_KEY_SELF;
(*db)->selftype->datum.fqn = CIL_KEY_SELF;
-
+ (*db)->num_types_and_attrs = 0;
+ (*db)->num_classes = 0;
(*db)->num_types = 0;
(*db)->num_roles = 0;
+ (*db)->num_users = 0;
(*db)->num_cats = 0;
(*db)->val_to_type = NULL;
(*db)->val_to_role = NULL;
+ (*db)->val_to_user = NULL;
(*db)->disable_dontaudit = CIL_FALSE;
(*db)->disable_neverallow = CIL_FALSE;
@@ -305,6 +315,7 @@ void cil_db_destroy(struct cil_db **db)
cil_strpool_destroy();
free((*db)->val_to_type);
free((*db)->val_to_role);
+ free((*db)->val_to_user);
free(*db);
*db = NULL;
@@ -340,7 +351,7 @@ int cil_add_file(cil_db_t *db, char *name, char *data, size_t size)
rc = cil_parser(name, buffer, size + 2, &db->parse);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to parse %s\n", name);
+ cil_log(CIL_INFO, "Failed to parse %s\n", name);
goto exit;
}
@@ -370,7 +381,7 @@ int cil_compile_nopdb(struct cil_db *db)
cil_log(CIL_INFO, "Building AST from Parse Tree\n");
rc = cil_build_ast(db, db->parse->root, db->ast->root);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to build ast\n");
+ cil_log(CIL_INFO, "Failed to build ast\n");
goto exit;
}
@@ -380,21 +391,21 @@ int cil_compile_nopdb(struct cil_db *db)
cil_log(CIL_INFO, "Resolving AST\n");
rc = cil_resolve_ast(db, db->ast->root);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to resolve ast\n");
+ cil_log(CIL_INFO, "Failed to resolve ast\n");
goto exit;
}
cil_log(CIL_INFO, "Qualifying Names\n");
rc = cil_fqn_qualify(db->ast->root);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to qualify names\n");
+ cil_log(CIL_INFO, "Failed to qualify names\n");
goto exit;
}
cil_log(CIL_INFO, "Compile post process\n");
rc = cil_post_process(db);
if (rc != SEPOL_OK ) {
- cil_log(CIL_ERR, "Post process failed\n");
+ cil_log(CIL_INFO, "Post process failed\n");
goto exit;
}
@@ -546,6 +557,12 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
case CIL_USER:
cil_destroy_user(*data);
break;
+ case CIL_USERATTRIBUTE:
+ cil_destroy_userattribute(*data);
+ break;
+ case CIL_USERATTRIBUTESET:
+ cil_destroy_userattributeset(*data);
+ break;
case CIL_USERPREFIX:
cil_destroy_userprefix(*data);
break;
@@ -652,6 +669,12 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
case CIL_AVRULE:
cil_destroy_avrule(*data);
break;
+ case CIL_AVRULEX:
+ cil_destroy_avrulex(*data);
+ break;
+ case CIL_PERMISSIONX:
+ cil_destroy_permissionx(*data);
+ break;
case CIL_ROLETRANSITION:
cil_destroy_roletransition(*data);
break;
@@ -782,6 +805,7 @@ int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_i
*sym_index = CIL_SYM_CLASSPERMSETS;
break;
case CIL_USER:
+ case CIL_USERATTRIBUTE:
*sym_index = CIL_SYM_USERS;
break;
case CIL_ROLE:
@@ -823,6 +847,9 @@ int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_i
case CIL_POLICYCAP:
*sym_index = CIL_SYM_POLICYCAPS;
break;
+ case CIL_PERMISSIONX:
+ *sym_index = CIL_SYM_PERMX;
+ break;
default:
*sym_index = CIL_SYM_UNKNOWN;
cil_log(CIL_INFO, "Failed to find flavor: %d\n", flavor);
@@ -909,6 +936,10 @@ const char * cil_node_to_string(struct cil_tree_node *node)
return CIL_KEY_CLASSPERMISSIONSET;
case CIL_USER:
return CIL_KEY_USER;
+ case CIL_USERATTRIBUTE:
+ return CIL_KEY_USERATTRIBUTE;
+ case CIL_USERATTRIBUTESET:
+ return CIL_KEY_USERATTRIBUTESET;
case CIL_USERPREFIX:
return CIL_KEY_USERPREFIX;
case CIL_USERROLE:
@@ -993,6 +1024,20 @@ const char * cil_node_to_string(struct cil_tree_node *node)
break;
}
break;
+ case CIL_AVRULEX:
+ switch (((struct cil_avrulex *)node->data)->rule_kind) {
+ case CIL_AVRULE_ALLOWED:
+ return CIL_KEY_ALLOWX;
+ case CIL_AVRULE_AUDITALLOW:
+ return CIL_KEY_AUDITALLOWX;
+ case CIL_AVRULE_DONTAUDIT:
+ return CIL_KEY_DONTAUDITX;
+ default:
+ break;
+ }
+ break;
+ case CIL_PERMISSIONX:
+ return CIL_KEY_PERMISSIONX;
case CIL_ROLETRANSITION:
return CIL_KEY_ROLETRANSITION;
case CIL_TYPE_RULE:
@@ -2078,6 +2123,31 @@ void cil_avrule_init(struct cil_avrule **avrule)
(*avrule)->classperms = NULL;
}
+void cil_permissionx_init(struct cil_permissionx **permx)
+{
+ *permx = cil_malloc(sizeof(**permx));
+
+ cil_symtab_datum_init(&(*permx)->datum);
+ (*permx)->kind = CIL_NONE;
+ (*permx)->obj_str = NULL;
+ (*permx)->obj = NULL;
+ (*permx)->expr_str = NULL;
+ (*permx)->perms = NULL;
+}
+
+void cil_avrulex_init(struct cil_avrulex **avrule)
+{
+ *avrule = cil_malloc(sizeof(**avrule));
+
+ (*avrule)->rule_kind = CIL_NONE;
+ (*avrule)->src_str = NULL;
+ (*avrule)->src = NULL;
+ (*avrule)->tgt_str = NULL;
+ (*avrule)->tgt = NULL;
+ (*avrule)->permx_str = NULL;
+ (*avrule)->permx = NULL;
+}
+
void cil_type_rule_init(struct cil_type_rule **type_rule)
{
*type_rule = cil_malloc(sizeof(**type_rule));
@@ -2325,6 +2395,26 @@ void cil_user_init(struct cil_user **user)
(*user)->roles = NULL;
(*user)->dftlevel = NULL;
(*user)->range = NULL;
+ (*user)->value = 0;
+}
+
+void cil_userattribute_init(struct cil_userattribute **attr)
+{
+ *attr = cil_malloc(sizeof(**attr));
+
+ cil_symtab_datum_init(&(*attr)->datum);
+
+ (*attr)->expr_list = NULL;
+ (*attr)->users = NULL;
+}
+
+void cil_userattributeset_init(struct cil_userattributeset **attrset)
+{
+ *attrset = cil_malloc(sizeof(**attrset));
+
+ (*attrset)->attr_str = NULL;
+ (*attrset)->str_expr = NULL;
+ (*attrset)->datum_expr = NULL;
}
void cil_userlevel_init(struct cil_userlevel **usrlvl)
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index 03f4924e..db09ec5e 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -37,6 +37,8 @@
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/constraint.h>
#include <sepol/policydb/flask.h>
+#include <sepol/policydb/expand.h>
+#include <sepol/policydb/hierarchy.h>
#include "cil_internal.h"
#include "cil_flavor.h"
@@ -45,13 +47,16 @@
#include "cil_tree.h"
#include "cil_binary.h"
#include "cil_symtab.h"
+#include "cil_find.h"
/* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended
* size of a hashtable. The next power of 2 of this is 2 ** 16.
*/
-#define FILENAME_TRANS_TABLE_SIZE 1 << 16
-#define RANGE_TRANS_TABLE_SIZE 1 << 13
-#define ROLE_TRANS_TABLE_SIZE 1 << 10
+#define FILENAME_TRANS_TABLE_SIZE (1 << 16)
+#define RANGE_TRANS_TABLE_SIZE (1 << 13)
+#define ROLE_TRANS_TABLE_SIZE (1 << 10)
+#define AVRULEX_TABLE_SIZE (1 << 10)
+#define PERMS_PER_CLASS 32
struct cil_args_binary {
const struct cil_db *db;
@@ -61,6 +66,8 @@ struct cil_args_binary {
hashtab_t filename_trans_table;
hashtab_t range_trans_table;
hashtab_t role_trans_table;
+ hashtab_t avrulex_ioctl_table;
+ void **type_value_to_cil;
};
struct cil_args_booleanif {
@@ -68,39 +75,9 @@ struct cil_args_booleanif {
policydb_t *pdb;
cond_node_t *cond_node;
enum cil_flavor cond_flavor;
- struct cil_list *neverallows;
hashtab_t filename_trans_table;
};
-struct cil_neverallow {
- struct cil_tree_node *node;
- struct cil_list *rules;
-};
-
-struct cil_neverallow_rule {
- struct cil_symtab_datum *src;
- struct cil_symtab_datum *tgt;
- uint32_t class;
- uint32_t perms;
-};
-
-void cil_neverallows_list_destroy(struct cil_list *neverallows)
-{
- struct cil_list_item *i;
- struct cil_list_item *j;
-
- cil_list_for_each(i, neverallows) {
- struct cil_neverallow *neverallow = i->data;
- cil_list_for_each(j, neverallow->rules) {
- struct cil_neverallow_rule *rule = j->data;
- free(rule);
- }
- cil_list_destroy(&neverallow->rules, CIL_FALSE);
- free(neverallow);
- }
- cil_list_destroy(&neverallows, CIL_FALSE);
-}
-
static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user)
{
*sepol_user = hashtab_search(pdb->p_users.table, datum->fqn);
@@ -167,6 +144,34 @@ static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum
return SEPOL_OK;
}
+static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new)
+{
+ struct cil_tree_node *node = datum->nodes->head->data;
+ struct cil_user *user = NULL;
+ struct cil_userattribute *attr = NULL;
+
+ if (node->flavor == CIL_USERATTRIBUTE) {
+ attr = (struct cil_userattribute *)datum;
+ if (ebitmap_cpy(new, attr->users)) {
+ cil_log(CIL_ERR, "Failed to copy user bits\n");
+ goto exit;
+ }
+ } else {
+ user = (struct cil_user *)datum;
+ ebitmap_init(new);
+ if (ebitmap_set_bit(new, user->value, 1)) {
+ cil_log(CIL_ERR, "Failed to set user bit\n");
+ ebitmap_destroy(new);
+ goto exit;
+ }
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return SEPOL_ERR;
+}
+
static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
{
struct cil_tree_node *node = datum->nodes->head->data;
@@ -330,7 +335,7 @@ exit:
return rc;
}
-int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
+int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
{
int rc = SEPOL_ERR;
struct cil_list_item *curr_class;
@@ -339,8 +344,8 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
struct cil_class *cil_class = curr_class->data;
uint32_t value = 0;
char *key = NULL;
- struct cil_tree_node *node = cil_class->datum.nodes->head->data;
- struct cil_tree_node *cil_perm = node->cl_head;
+ int class_index;
+ struct cil_tree_node *curr;
common_datum_t *sepol_common = NULL;
class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
memset(sepol_class, 0, sizeof(class_datum_t));
@@ -353,6 +358,8 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
goto exit;
}
sepol_class->s.value = value;
+ class_index = value;
+ class_value_to_cil[class_index] = cil_class;
rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
if (rc != SEPOL_OK) {
@@ -360,6 +367,7 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
}
if (cil_class->common != NULL) {
+ int i;
struct cil_class *cil_common = cil_class->common;
key = cil_class->common->datum.fqn;
@@ -373,14 +381,19 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
sepol_class->comdatum = sepol_common;
sepol_class->comkey = cil_strdup(key);
sepol_class->permissions.nprim += sepol_common->permissions.nprim;
+
+ for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) {
+ struct cil_perm *cil_perm = curr->data;
+ perm_value_to_cil[class_index][i] = cil_perm;
+ }
}
- while (cil_perm != NULL) {
- struct cil_perm *curr_perm = cil_perm->data;
+ for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) {
+ struct cil_perm *cil_perm = curr->data;
perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
memset(sepol_perm, 0, sizeof(perm_datum_t));
- key = cil_strdup(curr_perm->datum.fqn);
+ key = cil_strdup(cil_perm->datum.fqn);
rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
if (rc != SEPOL_OK) {
free(sepol_perm);
@@ -389,7 +402,7 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
}
sepol_perm->s.value = sepol_class->permissions.nprim + 1;
sepol_class->permissions.nprim++;
- cil_perm = cil_perm->next;
+ perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm;
}
}
@@ -490,7 +503,7 @@ exit:
return rc;
}
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[])
{
int rc = SEPOL_ERR;
uint32_t value = 0;
@@ -508,6 +521,8 @@ int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
sepol_type->s.value = value;
sepol_type->primary = 1;
+ type_value_to_cil[value] = cil_type;
+
return SEPOL_OK;
exit:
@@ -591,7 +606,7 @@ exit:
}
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr)
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[])
{
int rc = SEPOL_ERR;
uint32_t value = 0;
@@ -615,6 +630,8 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil
sepol_attr->s.value = value;
sepol_attr->primary = 1;
+ type_value_to_cil[value] = cil_attr;
+
return SEPOL_OK;
exit:
@@ -628,14 +645,21 @@ int __cil_typeattr_bitmap_init(policydb_t *pdb)
int rc = SEPOL_ERR;
pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
+ pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
uint32_t i = 0;
for (i = 0; i < pdb->p_types.nprim; i++) {
ebitmap_init(&pdb->type_attr_map[i]);
+ ebitmap_init(&pdb->attr_type_map[i]);
if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) {
rc = SEPOL_ERR;
goto exit;
}
+ if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) {
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
}
return SEPOL_OK;
@@ -675,6 +699,7 @@ int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct
if (rc != SEPOL_OK) goto exit;
ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1);
+ ebitmap_set_bit(&pdb->attr_type_map[value - 1], sepol_type->s.value - 1, 1);
}
rc = SEPOL_OK;
@@ -749,43 +774,41 @@ exit:
return SEPOL_ERR;
}
-int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole)
+int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user)
{
int rc = SEPOL_ERR;
user_datum_t *sepol_user = NULL;
role_datum_t *sepol_role = NULL;
- ebitmap_t role_bitmap;
- ebitmap_node_t *rnode;
+ ebitmap_node_t *rnode = NULL;
unsigned int i;
- rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user);
- if (rc != SEPOL_OK) goto exit;
-
- rc = __cil_expand_role(userrole->role, &role_bitmap);
- if (rc != SEPOL_OK) goto exit;
-
- ebitmap_for_each_bit(&role_bitmap, rnode, i) {
- if (!ebitmap_get_bit(&role_bitmap, i)) continue;
+ if (user->roles) {
+ rc = __cil_get_sepol_user_datum(pdb, DATUM(user), &sepol_user);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
- rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
- if (rc != SEPOL_OK) goto exit;
+ ebitmap_for_each_bit(user->roles, rnode, i) {
+ if (!ebitmap_get_bit(user->roles, i)) {
+ continue;
+ }
- if (sepol_role->s.value == 1) {
- // role is object_r, ignore it since it is implicitly associated
- // with all users
- continue;
- }
+ rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
- if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
- cil_log(CIL_INFO, "Failed to set role bit for user\n");
- goto exit;
+ if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
+ cil_log(CIL_INFO, "Failed to set role bit for user\n");
+ rc = SEPOL_ERR;
+ goto exit;
+ }
}
}
rc = SEPOL_OK;
exit:
- ebitmap_destroy(&role_bitmap);
return rc;
}
@@ -1324,89 +1347,7 @@ exit:
return rc;
}
-static void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
-{
- struct cil_neverallow *neverallow = neverallows->head->data;
- struct cil_list *neverallow_rules = neverallow->rules;
- struct cil_neverallow_rule *new = NULL;
-
- new = cil_malloc(sizeof(*new));
- new->src = src;
- new->tgt = tgt;
- new->class = class;
- new->perms = perms;
-
- cil_list_append(neverallow_rules, CIL_LIST_ITEM, new);
-}
-
-static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2)
-{
- if (t1->fqn == t2->fqn) {
- return CIL_TRUE;
- } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
- struct cil_typeattribute *a = (struct cil_typeattribute *)t1;
- struct cil_type *t = (struct cil_type *)t2;
- if (ebitmap_get_bit(a->types, t->value)) {
- return CIL_TRUE;
- }
- } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
- struct cil_typeattribute *a = (struct cil_typeattribute *)t2;
- struct cil_type *t = (struct cil_type *)t1;
- if (ebitmap_get_bit(a->types, t->value)) {
- return CIL_TRUE;
- }
- } else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
- struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2;
- struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1;
- /* abusing the ebitmap abstraction for speed */
- ebitmap_node_t *n1 = a1->types->node;
- ebitmap_node_t *n2 = a2->types->node;
- while (n1 && n2) {
- if (n1->startbit < n2->startbit) {
- n1 = n1->next;
- } else if (n2->startbit < n1->startbit) {
- n2 = n2->next;
- } else {
- if (n1->map & n2->map) {
- return CIL_TRUE;
- }
- n1 = n1->next;
- n2 = n2->next;
- }
- }
- }
- return CIL_FALSE;
-}
-
-static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
-{
- struct cil_list_item *curr = NULL;
- enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor;
- enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor;
- cil_list_for_each(curr, neverallows) {
- struct cil_neverallow *neverallow = curr->data;
- struct cil_tree_node *node = neverallow->node;
- struct cil_list_item *curr_item = NULL;
- cil_list_for_each(curr_item, neverallow->rules) {
- struct cil_neverallow_rule *curr_rule = curr_item->data;
- enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor;
- enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor;
- if ((curr_rule->perms & perms) && (class == curr_rule->class)) {
- int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src);
- if (src_match) {
- int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt);
- if (tgt_match) {
- cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path);
- return SEPOL_ERR;
- }
- }
- }
- }
- }
- return SEPOL_OK;
-}
-
-int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, cond_node_t *cond_node, enum cil_flavor cond_flavor)
{
int rc = SEPOL_ERR;
type_datum_t *sepol_src = NULL;
@@ -1425,28 +1366,19 @@ int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab
return SEPOL_OK;
}
- if (kind == CIL_AVRULE_NEVERALLOW) {
- __cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data);
- } else {
- if (kind == CIL_AVRULE_DONTAUDIT) {
- data = ~data;
- } else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) {
- rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data);
- if (rc != SEPOL_OK) {
- goto exit;
- }
- }
+ if (kind == CIL_AVRULE_DONTAUDIT) {
+ data = ~data;
+ }
- rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
- if (rc != SEPOL_OK) goto exit;
+ rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
+ if (rc != SEPOL_OK) goto exit;
- rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
- if (rc != SEPOL_OK) goto exit;
+ rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
+ if (rc != SEPOL_OK) goto exit;
- rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
- if (rc != SEPOL_OK) {
- goto exit;
- }
+ rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
+ if (rc != SEPOL_OK) {
+ goto exit;
}
return SEPOL_OK;
@@ -1456,7 +1388,7 @@ exit:
}
-int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, cond_node_t *cond_node, enum cil_flavor cond_flavor)
{
int rc = SEPOL_ERR;
struct cil_list_item *curr;
@@ -1465,7 +1397,7 @@ int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum
if (curr->flavor == CIL_CLASSPERMS) {
struct cil_classperms *cp = curr->data;
if (FLAVOR(cp->class) == CIL_CLASS) {
- rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -1473,7 +1405,7 @@ int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum
struct cil_list_item *i = NULL;
cil_list_for_each(i, cp->perms) {
struct cil_perm *cmp = i->data;
- rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -1482,7 +1414,7 @@ int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum
} else { /* SET */
struct cil_classperms_set *cp_set = curr->data;
struct cil_classpermission *cp = cp_set->set;
- rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -1495,7 +1427,7 @@ exit:
return rc;
}
-int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
{
int rc = SEPOL_ERR;
uint16_t kind = cil_avrule->rule_kind;
@@ -1509,12 +1441,6 @@ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_a
goto exit;
}
- if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) {
- // ignore neverallow rules
- rc = SEPOL_OK;
- goto exit;
- }
-
src = cil_avrule->src;
tgt = cil_avrule->tgt;
@@ -1530,7 +1456,7 @@ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_a
if (!ebitmap_get_bit(&type_bitmap, i)) continue;
src = DATUM(db->val_to_type[i]);
- rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor);
if (rc != SEPOL_OK) {
ebitmap_destroy(&type_bitmap);
goto exit;
@@ -1538,7 +1464,7 @@ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_a
}
ebitmap_destroy(&type_bitmap);
} else {
- rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
if (rc != SEPOL_OK) goto exit;
}
@@ -1548,9 +1474,289 @@ exit:
return rc;
}
-int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows)
+int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule)
+{
+ return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE);
+}
+
+// Copied from checkpolicy/policy_define.c
+
+/* index of the u32 containing the permission */
+#define XPERM_IDX(x) (x >> 5)
+/* set bits 0 through x-1 within the u32 */
+#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
+/* low value for this u32 */
+#define XPERM_LOW(x) (x << 5)
+/* high value for this u32 */
+#define XPERM_HIGH(x) (((x + 1) << 5) - 1)
+void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms)
{
- return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE);
+ unsigned int i;
+ uint16_t h = high + 1;
+ /* for each u32 that this low-high range touches, set driver permissions */
+ for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
+ /* set all bits in u32 */
+ if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+ xperms->perms[i] |= ~0U;
+ /* set low bits */
+ else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
+ xperms->perms[i] |= XPERM_SETBITS(h);
+ /* set high bits */
+ else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+ xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
+ /* set middle bits */
+ else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
+ xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
+ }
+}
+
+
+#define IOC_DRIV(x) (x >> 8)
+#define IOC_FUNC(x) (x & 0xff)
+
+int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
+{
+ int rc = SEPOL_OK;
+ struct policydb *pdb;
+ avtab_key_t *avtab_key;
+ avtab_datum_t avtab_datum;
+ ebitmap_t *xperms;
+ ebitmap_node_t *node;
+ unsigned int i;
+ uint16_t low = 0, high = 0;
+ struct avtab_extended_perms *partial = NULL;
+ struct avtab_extended_perms *complete = NULL;
+ int start_new_range;
+
+ avtab_key = (avtab_key_t *)k;
+ xperms = datum;
+ pdb = args;
+
+ avtab_datum.data = 0;
+
+ start_new_range = 1;
+
+ ebitmap_for_each_bit(xperms, node, i) {
+ if (!ebitmap_get_bit(xperms, i)) continue;
+
+ if (start_new_range) {
+ low = i;
+ start_new_range = 0;
+ }
+
+ // continue if the current bit isn't the end of the driver function or the next bit is set
+ if (IOC_FUNC(i) != 0xff && ebitmap_get_bit(xperms, i + 1)) {
+ continue;
+ }
+
+ // if we got here, i is the end of this range (either becuase the func
+ // is 0xff or the next bit isn't set). The next time around we are
+ // going to need a start a new range
+ high = i;
+ start_new_range = 1;
+
+ if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
+ if (!complete) {
+ complete = cil_calloc(1, sizeof(*complete));
+ complete->driver = 0x0;
+ complete->specified = AVTAB_XPERMS_IOCTLDRIVER;
+ }
+
+ __avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete);
+ } else {
+ if (partial && partial->driver != IOC_DRIV(low)) {
+ avtab_datum.xperms = partial;
+ rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ free(partial);
+ partial = NULL;
+ }
+
+ if (!partial) {
+ partial = cil_calloc(1, sizeof(*partial));
+ partial->driver = IOC_DRIV(low);
+ partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+ }
+
+ __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
+ }
+ }
+
+ if (partial) {
+ avtab_datum.xperms = partial;
+ rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ if (complete) {
+ avtab_datum.xperms = complete;
+ rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ rc = SEPOL_OK;
+
+exit:
+ free(partial);
+ free(complete);
+
+ // hashtab_t does not have a way to free keys or datum since it doesn't
+ // know what they are. We won't need the keys/datum after this function, so
+ // clean them up here.
+ free(avtab_key);
+ ebitmap_destroy(xperms);
+ free(xperms);
+
+ return rc;
+}
+
+int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
+{
+ uint16_t specified;
+ avtab_key_t *avtab_key;
+ ebitmap_t *hashtab_xperms;
+ int rc = SEPOL_ERR;
+
+ switch (kind) {
+ case CIL_AVRULE_ALLOWED:
+ specified = AVTAB_XPERMS_ALLOWED;
+ break;
+ case CIL_AVRULE_AUDITALLOW:
+ specified = AVTAB_XPERMS_AUDITALLOW;
+ break;
+ case CIL_AVRULE_DONTAUDIT:
+ specified = AVTAB_XPERMS_DONTAUDIT;
+ break;
+ default:
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
+ avtab_key = cil_malloc(sizeof(*avtab_key));
+ avtab_key->source_type = src;
+ avtab_key->target_type = tgt;
+ avtab_key->target_class = obj;
+ avtab_key->specified = specified;
+
+ hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key);
+ if (!hashtab_xperms) {
+ hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms));
+ rc = ebitmap_cpy(hashtab_xperms, xperms);
+ if (rc != SEPOL_OK) {
+ free(avtab_key);
+ goto exit;
+ }
+ rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms);
+ if (rc != SEPOL_OK) {
+ free(avtab_key);
+ goto exit;
+ }
+ } else {
+ free(avtab_key);
+ rc = ebitmap_union(hashtab_xperms, xperms);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
+int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args)
+{
+ int rc = SEPOL_ERR;
+ type_datum_t *sepol_src = NULL;
+ type_datum_t *sepol_tgt = NULL;
+ class_datum_t *sepol_obj = NULL;
+ struct cil_list *class_list = NULL;
+ struct cil_list_item *c;
+
+ rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
+ if (rc != SEPOL_OK) goto exit;
+
+ rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
+ if (rc != SEPOL_OK) goto exit;
+
+ class_list = cil_expand_class(permx->obj);
+
+ cil_list_for_each(c, class_list) {
+ rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
+ if (rc != SEPOL_OK) goto exit;
+
+ switch (permx->kind) {
+ case CIL_PERMX_KIND_IOCTL:
+ rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
+ if (rc != SEPOL_OK) goto exit;
+ break;
+ default:
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+ }
+
+ rc = SEPOL_OK;
+
+exit:
+ cil_list_destroy(&class_list, CIL_FALSE);
+
+ return rc;
+}
+
+int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrulex *cil_avrulex, struct cil_args_binary *args)
+{
+ int rc = SEPOL_ERR;
+ uint16_t kind;
+ struct cil_symtab_datum *src = NULL;
+ struct cil_symtab_datum *tgt = NULL;
+ ebitmap_t type_bitmap;
+ ebitmap_node_t *tnode;
+ unsigned int i;
+
+ ebitmap_init(&type_bitmap);
+
+ if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
+ // Do not add dontaudit rules to binary
+ rc = SEPOL_OK;
+ goto exit;
+ }
+
+ kind = cil_avrulex->rule_kind;
+ src = cil_avrulex->src;
+ tgt = cil_avrulex->tgt;
+
+ if (tgt->fqn == CIL_KEY_SELF) {
+ rc = __cil_expand_type(src, &type_bitmap);
+ if (rc != SEPOL_OK) goto exit;
+
+ ebitmap_for_each_bit(&type_bitmap, tnode, i) {
+ if (!ebitmap_get_bit(&type_bitmap, i)) continue;
+
+ src = DATUM(db->val_to_type[i]);
+ rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->permx, args);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ } else {
+ rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->permx, args);
+ if (rc != SEPOL_OK) goto exit;
+ }
+
+ rc = SEPOL_OK;
+
+exit:
+ ebitmap_destroy(&type_bitmap);
+
+ return rc;
}
int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
@@ -1593,7 +1799,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu
break;
case CIL_AVRULE:
cil_avrule = node->data;
- rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor);
+ rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path);
goto exit;
@@ -1762,7 +1968,7 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e
return SEPOL_OK;
}
-int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table)
+int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table)
{
int rc = SEPOL_ERR;
struct cil_args_booleanif bool_args;
@@ -1837,7 +2043,6 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
bool_args.db = db;
bool_args.pdb = pdb;
bool_args.cond_node = cond_node;
- bool_args.neverallows = neverallows;
bool_args.filename_trans_table = filename_trans_table;
if (true_node != NULL) {
@@ -2004,12 +2209,30 @@ int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_d
if (expr_flavor == CIL_USER) {
user_datum_t *sepol_user = NULL;
- rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user);
+ ebitmap_t user_bitmap;
+ ebitmap_node_t *unode;
+ unsigned int i;
+
+ rc = __cil_expand_user(item->data, &user_bitmap);
if (rc != SEPOL_OK) goto exit;
- if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
- goto exit;
+ ebitmap_for_each_bit(&user_bitmap, unode, i) {
+ if (!ebitmap_get_bit(&user_bitmap, i)) {
+ continue;
+ }
+
+ rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user);
+ if (rc != SEPOL_OK) {
+ ebitmap_destroy(&user_bitmap);
+ goto exit;
+ }
+
+ if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
+ ebitmap_destroy(&user_bitmap);
+ goto exit;
+ }
}
+ ebitmap_destroy(&user_bitmap);
} else if (expr_flavor == CIL_ROLE) {
role_datum_t *sepol_role = NULL;
ebitmap_t role_bitmap;
@@ -3115,12 +3338,15 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
hashtab_t filename_trans_table;
hashtab_t range_trans_table;
hashtab_t role_trans_table;
+ void **type_value_to_cil;
+
db = args->db;
pdb = args->pdb;
pass = args->pass;
filename_trans_table = args->filename_trans_table;
range_trans_table = args->range_trans_table;
role_trans_table = args->role_trans_table;
+ type_value_to_cil = args->type_value_to_cil;
if (node->flavor >= CIL_MIN_DECLARATIVE) {
if (node != DATUM(node->data)->nodes->head->data) {
@@ -3135,10 +3361,10 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
rc = cil_role_to_policydb(pdb, node->data);
break;
case CIL_TYPE:
- rc = cil_type_to_policydb(pdb, node->data);
+ rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
break;
case CIL_TYPEATTRIBUTE:
- rc = cil_typeattribute_to_policydb(pdb, node->data);
+ rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
break;
case CIL_POLICYCAP:
rc = cil_policycap_to_policydb(pdb, node->data);
@@ -3192,9 +3418,10 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
if (rc != SEPOL_OK) goto exit;
if (pdb->mls == CIL_TRUE) {
rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
}
- break;
- case CIL_USERROLE:
rc = cil_userrole_to_policydb(pdb, db, node->data);
break;
case CIL_TYPE_RULE:
@@ -3202,17 +3429,9 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
break;
case CIL_AVRULE: {
struct cil_avrule *rule = node->data;
- struct cil_list *neverallows = args->neverallows;
- if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
- struct cil_neverallow *new_rule = NULL;
-
- new_rule = cil_malloc(sizeof(*new_rule));
- cil_list_init(&new_rule->rules, CIL_LIST_ITEM);
- new_rule->node = node;
-
- cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule);
-
- rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows);
+ if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
+ struct cil_list *neverallows = args->neverallows;
+ cil_list_prepend(neverallows, CIL_LIST_ITEM, node);
}
break;
}
@@ -3261,15 +3480,18 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
case 3:
switch (node->flavor) {
case CIL_BOOLEANIF:
- rc = cil_booleanif_to_policydb(pdb, db, node, args->neverallows, filename_trans_table);
+ rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table);
break;
case CIL_AVRULE: {
struct cil_avrule *rule = node->data;
if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
- rc = cil_avrule_to_policydb(pdb, db, node->data, args->neverallows);
+ rc = cil_avrule_to_policydb(pdb, db, node->data);
}
}
break;
+ case CIL_AVRULEX:
+ rc = cil_avrulex_to_hashtable(pdb, db, node->data, args);
+ break;
case CIL_ROLEALLOW:
rc = cil_roleallow_to_policydb(pdb, db, node->data);
break;
@@ -3608,7 +3830,7 @@ exit:
}
-int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
+int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
{
int rc = SEPOL_ERR;
@@ -3618,7 +3840,7 @@ int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
pdb->handle_unknown = db->handle_unknown;
pdb->mls = db->mls;
- rc = cil_classorder_to_policydb(pdb, db);
+ rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -3703,6 +3925,58 @@ static int role_trans_compare(hashtab_t h
return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
}
+/* Based on MurmurHash3, written by Austin Appleby and placed in the
+ * public domain.
+ */
+static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, hashtab_key_t key)
+{
+ avtab_key_t *k = (avtab_key_t *)key;
+
+ static const uint32_t c1 = 0xcc9e2d51;
+ static const uint32_t c2 = 0x1b873593;
+ static const uint32_t r1 = 15;
+ static const uint32_t r2 = 13;
+ static const uint32_t m = 5;
+ static const uint32_t n = 0xe6546b64;
+
+ uint32_t hash = 0;
+
+#define mix(input) { \
+ uint32_t v = input; \
+ v *= c1; \
+ v = (v << r1) | (v >> (32 - r1)); \
+ v *= c2; \
+ hash ^= v; \
+ hash = (hash << r2) | (hash >> (32 - r2)); \
+ hash = hash * m + n; \
+}
+
+ mix(k->target_class);
+ mix(k->target_type);
+ mix(k->source_type);
+ mix(k->specified);
+
+#undef mix
+
+ hash ^= hash >> 16;
+ hash *= 0x85ebca6b;
+ hash ^= hash >> 13;
+ hash *= 0xc2b2ae35;
+ hash ^= hash >> 16;
+
+ return hash & (AVRULEX_TABLE_SIZE - 1);
+}
+
+static int avrulex_compare(hashtab_t h
+ __attribute__ ((unused)), hashtab_key_t key1,
+ hashtab_key_t key2)
+{
+ avtab_key_t *a = (avtab_key_t *)key1;
+ avtab_key_t *b = (avtab_key_t *)key2;
+
+ return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified;
+}
+
int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
{
int rc = SEPOL_ERR;
@@ -3728,6 +4002,413 @@ exit:
return rc;
}
+static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr)
+{
+ class_perm_node_t *next;
+
+ while (curr) {
+ next = curr->next;
+ free(curr);
+ curr = next;
+ }
+}
+
+static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms)
+{
+ int rc = SEPOL_ERR;
+ struct cil_list_item *i;
+ cil_list_for_each(i, classperms) {
+ if (i->flavor == CIL_CLASSPERMS) {
+ struct cil_classperms *cp = i->data;
+ if (FLAVOR(cp->class) == CIL_CLASS) {
+ class_perm_node_t *cpn = NULL;
+ class_datum_t *sepol_class = NULL;
+ uint32_t data = 0;
+
+ rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
+ if (rc != SEPOL_OK) goto exit;
+
+ rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
+ if (rc != SEPOL_OK) goto exit;
+ if (data == 0) {
+ /* No permissions */
+ return SEPOL_OK;
+ }
+ cpn = cil_malloc(sizeof(class_perm_node_t));
+ cpn->tclass = sepol_class->s.value;
+ cpn->data = data;
+ cpn->next = *sepol_class_perms;
+ *sepol_class_perms = cpn;
+ } else { /* MAP */
+ struct cil_list_item *j = NULL;
+ cil_list_for_each(j, cp->perms) {
+ struct cil_perm *cmp = j->data;
+ rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ }
+ } else { /* SET */
+ struct cil_classperms_set *cp_set = i->data;
+ struct cil_classpermission *cp = cp_set->set;
+ rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ }
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
+static void __cil_init_sepol_type_set(type_set_t *t)
+{
+ ebitmap_init(&t->types);
+ ebitmap_init(&t->negset);
+ t->flags = 0;
+}
+
+static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map)
+{
+ int rc = SEPOL_ERR;
+ struct cil_tree_node *n = datum->nodes->head->data;
+ type_datum_t *sepol_datum = NULL;
+
+ if (n->flavor == CIL_TYPEATTRIBUTE) {
+ ebitmap_node_t *tnode;
+ unsigned int i;
+ struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
+ ebitmap_for_each_bit(attr->types, tnode, i) {
+ if (!ebitmap_get_bit(attr->types, i)) continue;
+ datum = DATUM(db->val_to_type[i]);
+ rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
+ if (rc != SEPOL_OK) goto exit;
+ ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
+ }
+ } else {
+ rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
+ if (rc != SEPOL_OK) goto exit;
+ ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
+static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node)
+{
+ avrule_t *avrule;
+
+ avrule = cil_malloc(sizeof(avrule_t));
+ avrule->specified = kind;
+ avrule->flags = 0;
+ __cil_init_sepol_type_set(&avrule->stypes);
+ __cil_init_sepol_type_set(&avrule->ttypes);
+ avrule->perms = NULL;
+ avrule->line = node->line;
+ avrule->source_filename = node->path;
+ avrule->source_line = node->line;
+ avrule->next = NULL;
+ return avrule;
+}
+
+static void __cil_destroy_sepol_avrules(avrule_t *curr)
+{
+ avrule_t *next;
+
+ while (curr) {
+ next = curr->next;
+ ebitmap_destroy(&curr->stypes.types);
+ ebitmap_destroy(&curr->stypes.negset);
+ ebitmap_destroy(&curr->ttypes.types);
+ ebitmap_destroy(&curr->ttypes.negset);
+ __cil_destroy_sepol_class_perms(curr->perms);
+ free(curr);
+ curr = next;
+ }
+}
+
+static int __cil_rule_to_expanded_sepol_avrule(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, avrule_t **avrule)
+{
+ int rc = SEPOL_ERR;
+ struct cil_avrule *cil_rule = node->data;
+ struct cil_symtab_datum *tgt = cil_rule->tgt;
+ uint32_t kind;
+ avrule_t *rule;
+
+ *avrule = NULL;
+
+ switch (cil_rule->rule_kind) {
+ case CIL_AVRULE_AUDITALLOW:
+ kind = AVRULE_AUDITALLOW;
+ break;
+ case CIL_AVRULE_DONTAUDIT:
+ kind = AVRULE_AUDITDENY;
+ break;
+ case CIL_AVRULE_NEVERALLOW:
+ kind = AVRULE_NEVERALLOW;
+ break;
+ default:
+ kind = AVRULE_ALLOWED;
+ break;
+ }
+
+ rule = __cil_init_sepol_avrule(kind, node);
+
+ rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->classperms, &rule->perms);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ if (tgt->fqn == CIL_KEY_SELF) {
+ rule->flags = RULE_SELF;
+ } else {
+ rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ rule->next = NULL;
+ *avrule = rule;
+
+ return SEPOL_OK;
+
+exit:
+ __cil_destroy_sepol_avrules(rule);
+ return rc;
+}
+
+static void __cil_print_parents(const char *pad, struct cil_tree_node *n)
+{
+ if (!n) return;
+
+ __cil_print_parents(pad, n->parent);
+
+ if (!n->path) {
+ cil_log(CIL_ERR,"%s%s\n", pad, cil_node_to_string(n));
+ } else {
+ cil_log(CIL_ERR,"%s%s at line %d of %s\n", pad, cil_node_to_string(n), n->line, n->path);
+ }
+}
+
+static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule)
+{
+ struct cil_list *cp_list = avrule->classperms;
+ struct cil_list_item *i1, *i2;
+
+ cil_log(CIL_ERR,"%s(%s ", pad, kind);
+ cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn);
+
+ i1 = cp_list->head;
+ if (i1->flavor == CIL_CLASSPERMS) {
+ struct cil_classperms *cp = i1->data;
+ cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn);
+ cil_list_for_each(i2, cp->perms) {
+ cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn);
+ if (i2 != cp->perms->tail) {
+ cil_log(CIL_ERR," ");
+ } else {
+ cil_log(CIL_ERR,"))");
+ }
+ }
+ } else {
+ struct cil_classperms_set *cp_set = i1->data;
+ cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn);
+ }
+
+ cil_log(CIL_ERR,")\n");
+}
+
+static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows)
+{
+ int rc = SEPOL_OK;
+ struct cil_list_item *i1;
+
+ cil_list_for_each(i1, neverallows) {
+ struct cil_tree_node *node = i1->data;
+ avrule_t *avrule;
+ rc = __cil_rule_to_expanded_sepol_avrule(db, pdb, node, &avrule);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_ERR, "Failed to create expanded sepol avrules to check neverallow rules\n");
+ goto exit;
+ }
+
+ rc = check_assertion(pdb, avrule);
+
+ if (rc == CIL_TRUE) {
+ struct cil_list_item *i2;
+ struct cil_list *matching;
+ struct cil_avrule *cil_rule = node->data;
+ struct cil_avrule target;
+ struct cil_tree_node *n2;
+ struct cil_avrule *r2;
+ target.rule_kind = CIL_AVRULE_ALLOWED;
+ target.src = cil_rule->src;
+ target.tgt = cil_rule->tgt;
+ target.classperms = cil_rule->classperms;
+ cil_log(CIL_ERR, "Neverallow check failed at line %d of %s\n", node->line, node->path);
+ __cil_print_rule(" ", "neverallow", cil_rule);
+ cil_list_init(&matching, CIL_NODE);
+ rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
+ if (rc) {
+ cil_log(CIL_ERR, "Error occurred while checking neverallow rules\n");
+ cil_list_destroy(&matching, CIL_FALSE);
+ __cil_destroy_sepol_avrules(avrule);
+ goto exit;
+ }
+
+ cil_list_for_each(i2, matching) {
+ n2 = i2->data;
+ r2 = n2->data;
+ __cil_print_parents(" ", n2);
+ __cil_print_rule(" ", "allow", r2);
+ }
+ cil_log(CIL_ERR,"\n");
+ cil_list_destroy(&matching, CIL_FALSE);
+ }
+ __cil_destroy_sepol_avrules(avrule);
+ avrule = NULL;
+ }
+
+exit:
+ return rc;
+}
+
+static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+ struct cil_classperms *cp;
+ struct cil_list *cp_list;
+ class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1];
+ unsigned i;
+
+ cil_classperms_init(&cp);
+
+ cp->class = class_value_to_cil[class];
+ if (!cp->class) goto exit;
+
+ cil_list_init(&cp->perms, CIL_PERM);
+ for (i = 0; i < sepol_class->permissions.nprim; i++) {
+ struct cil_perm *perm;
+ if ((data & (1 << i)) == 0) continue;
+ perm = perm_value_to_cil[class][i+1];
+ if (!perm) goto exit;
+ cil_list_append(cp->perms, CIL_PERM, perm);
+ }
+
+ cil_list_init(&cp_list, CIL_CLASSPERMS);
+ cil_list_append(cp_list, CIL_CLASSPERMS, cp);
+
+ return cp_list;
+
+exit:
+ cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n");
+ return NULL;
+}
+
+static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+ int rc = SEPOL_ERR;
+ avtab_key_t *k = &sepol_rule->key;
+ avtab_datum_t *d = &sepol_rule->datum;
+ cil_rule->src = type_value_to_cil[k->source_type];
+ if (!cil_rule->src) goto exit;
+
+ cil_rule->tgt = type_value_to_cil[k->target_type];
+ if (!cil_rule->tgt) goto exit;
+
+ cil_rule->classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil);
+ if (!cil_rule->classperms) goto exit;
+
+ return SEPOL_OK;
+
+exit:
+ cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n");
+ return rc;
+}
+
+static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+ int rc = SEPOL_OK;
+ int i;
+
+ for (i = 0; i < db->num_types; i++) {
+ type_datum_t *child;
+ type_datum_t *parent;
+ avtab_ptr_t bad = NULL;
+ int numbad = 0;
+ struct cil_type *t = db->val_to_type[i];
+
+ if (!t->bounds) continue;
+
+ rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child);
+ if (rc != SEPOL_OK) goto exit;
+
+ rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent);
+ if (rc != SEPOL_OK) goto exit;
+
+ rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad);
+ if (rc != SEPOL_OK) goto exit;
+
+ if (bad) {
+ avtab_ptr_t cur;
+ struct cil_avrule target;
+
+ target.rule_kind = CIL_AVRULE_ALLOWED;
+ target.src_str = NULL;
+ target.tgt_str = NULL;
+
+ cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n",
+ t->datum.fqn, t->bounds->datum.fqn);
+ for (cur = bad; cur; cur = cur->next) {
+ struct cil_list_item *i2;
+ struct cil_list *matching;
+ struct cil_tree_node *n;
+
+ rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n");
+ goto exit;
+ }
+ __cil_print_rule(" ", "allow", &target);
+ cil_list_init(&matching, CIL_NODE);
+ rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
+ if (rc) {
+ cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
+ cil_list_destroy(&matching, CIL_FALSE);
+ cil_list_destroy(&target.classperms, CIL_TRUE);
+ bounds_destroy_bad(bad);
+ goto exit;
+ }
+
+ cil_list_for_each(i2, matching) {
+ __cil_print_parents(" ", (struct cil_tree_node *)i2->data);
+ }
+ i2 = matching->tail;
+ n = i2->data;
+ __cil_print_rule(" ", "allow", n->data);
+ cil_log(CIL_ERR,"\n");
+ cil_list_destroy(&matching, CIL_FALSE);
+ cil_list_destroy(&target.classperms, CIL_TRUE);
+ }
+ bounds_destroy_bad(bad);
+ }
+ }
+
+exit:
+ return rc;
+}
+
// assumes policydb is already allocated and initialized properly with things
// like policy type set to kernel and version set appropriately
int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
@@ -3740,6 +4421,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
hashtab_t filename_trans_table = NULL;
hashtab_t range_trans_table = NULL;
hashtab_t role_trans_table = NULL;
+ hashtab_t avrulex_ioctl_table = NULL;
+ void **type_value_to_cil = NULL;
+ struct cil_class **class_value_to_cil = NULL;
+ struct cil_perm ***perm_value_to_cil = NULL;
if (db == NULL || policydb == NULL) {
if (db == NULL) {
@@ -3750,7 +4435,23 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
return SEPOL_ERR;
}
- rc = __cil_policydb_init(pdb, db);
+ /* libsepol values start at 1. Just allocate extra memory rather than
+ * subtract 1 from the sepol value.
+ */
+ type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil));
+ if (!type_value_to_cil) goto exit;
+
+ class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil));
+ if (!class_value_to_cil) goto exit;
+
+ perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil));
+ if (!perm_value_to_cil) goto exit;
+ for (i=1; i < db->num_classes+1; i++) {
+ perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i]));
+ if (!perm_value_to_cil[i]) goto exit;
+ }
+
+ rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR,"Problem in policydb_init\n");
goto exit;
@@ -3774,6 +4475,12 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
goto exit;
}
+ avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
+ if (!avrulex_ioctl_table) {
+ cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
+ goto exit;
+ }
+
cil_list_init(&neverallows, CIL_LIST_ITEM);
extra_args.db = db;
@@ -3782,6 +4489,9 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
extra_args.filename_trans_table = filename_trans_table;
extra_args.range_trans_table = range_trans_table;
extra_args.role_trans_table = role_trans_table;
+ extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
+ extra_args.type_value_to_cil = type_value_to_cil;
+
for (i = 1; i <= 3; i++) {
extra_args.pass = i;
@@ -3798,6 +4508,14 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
goto exit;
}
}
+
+ if (i == 3) {
+ rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_INFO, "Failure creating avrulex rules\n");
+ goto exit;
+ }
+ }
}
rc = cil_sidorder_to_policydb(pdb, db);
@@ -3822,13 +4540,38 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
cond_optimize_lists(pdb->cond_list);
__cil_set_conditional_state_and_flags(pdb);
+ if (db->disable_neverallow != CIL_TRUE) {
+ cil_log(CIL_INFO, "Checking Neverallows\n");
+ rc = cil_check_neverallows(db, pdb, neverallows);
+ if (rc != SEPOL_OK) goto exit;
+
+ cil_log(CIL_INFO, "Checking User Bounds\n");
+ bounds_check_users(NULL, pdb);
+
+ cil_log(CIL_INFO, "Checking Role Bounds\n");
+ bounds_check_roles(NULL, pdb);
+
+ cil_log(CIL_INFO, "Checking Type Bounds\n");
+ rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
+ if (rc != SEPOL_OK) goto exit;
+
+ }
+
rc = SEPOL_OK;
exit:
hashtab_destroy(filename_trans_table);
hashtab_destroy(range_trans_table);
hashtab_destroy(role_trans_table);
- cil_neverallows_list_destroy(neverallows);
+ hashtab_destroy(avrulex_ioctl_table);
+ free(type_value_to_cil);
+ free(class_value_to_cil);
+ /* Range is because libsepol values start at 1. */
+ for (i=1; i < db->num_classes+1; i++) {
+ free(perm_value_to_cil[i]);
+ }
+ free(perm_value_to_cil);
+ cil_list_destroy(&neverallows, CIL_FALSE);
return rc;
}
diff --git a/libsepol/cil/src/cil_binary.h b/libsepol/cil/src/cil_binary.h
index 5045c6ed..c59b1e3c 100644
--- a/libsepol/cil/src/cil_binary.h
+++ b/libsepol/cil/src/cil_binary.h
@@ -112,7 +112,7 @@ int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct ci
*
* @return SEPOL_OK upon success or an error otherwise.
*/
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type);
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]);
/**
* Insert cil typealias structure into sepol policydb.
@@ -144,7 +144,7 @@ int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *c
*
* @return SEPOL_OK upon success or an error otherwise.
*/
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr);
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]);
/**
* Insert cil attribute structure into sepol type->attribute bitmap.
@@ -184,12 +184,13 @@ int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user);
/**
* Insert cil userrole structure into sepol policydb.
*
- * @param[in] pdb THe policy database to insert the userrole into.
- * @param[in] datum The cil_userrole datum.
+ * @param[in] pdb The policy database to insert the userrole into.
+ * @param[in] db The cil database
+ * @param[in] datum The cil_user
*
* @return SEPOL_OK upon success or SEPOL_ERR otherwise.
*/
-int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole);
+int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user);
/**
* Insert cil bool structure into sepol policydb.
@@ -250,7 +251,7 @@ int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
*
* @return SEPOL_OK upon success or an error otherwise.
*/
-int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows);
+int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule);
/**
* Insert cil booleanif structure into sepol policydb. This populates the
@@ -262,7 +263,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
*
* @return SEPOL_OK upon success or an error otherwise.
*/
-int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table);
+int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table);
/**
* Insert cil role transition structure into sepol policydb.
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 92c3e092..861b6061 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -1196,10 +1196,132 @@ void cil_destroy_user(struct cil_user *user)
}
cil_symtab_datum_destroy(&user->datum);
- cil_list_destroy(&user->roles, CIL_FALSE);
+ ebitmap_destroy(user->roles);
+ free(user->roles);
free(user);
}
+int cil_gen_userattribute(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+ enum cil_syntax syntax[] = {
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_END
+ };
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
+ char *key = NULL;
+ struct cil_userattribute *attr = NULL;
+ int rc = SEPOL_ERR;
+
+ if (parse_current == NULL || ast_node == NULL) {
+ goto exit;
+ }
+
+ rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ cil_userattribute_init(&attr);
+
+ key = parse_current->next->data;
+ rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USERATTRIBUTE);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ return SEPOL_OK;
+exit:
+ cil_log(CIL_ERR, "Bad userattribute declaration at line %d of %s\n",
+ parse_current->line, parse_current->path);
+ cil_destroy_userattribute(attr);
+ cil_clear_node(ast_node);
+ return rc;
+}
+
+void cil_destroy_userattribute(struct cil_userattribute *attr)
+{
+ struct cil_list_item *expr = NULL;
+ struct cil_list_item *next = NULL;
+
+ if (attr == NULL) {
+ return;
+ }
+
+ if (attr->expr_list != NULL) {
+ /* we don't want to destroy the expression stacks (cil_list) inside
+ * this list cil_list_destroy destroys sublists, so we need to do it
+ * manually */
+ expr = attr->expr_list->head;
+ while (expr != NULL) {
+ next = expr->next;
+ cil_list_item_destroy(&expr, CIL_FALSE);
+ expr = next;
+ }
+ free(attr->expr_list);
+ attr->expr_list = NULL;
+ }
+
+ cil_symtab_datum_destroy(&attr->datum);
+ ebitmap_destroy(attr->users);
+ free(attr->users);
+ free(attr);
+}
+
+int cil_gen_userattributeset(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+ enum cil_syntax syntax[] = {
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_STRING | CIL_SYN_LIST,
+ CIL_SYN_END
+ };
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
+ struct cil_userattributeset *attrset = NULL;
+ int rc = SEPOL_ERR;
+
+ if (db == NULL || parse_current == NULL || ast_node == NULL) {
+ goto exit;
+ }
+
+ rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ cil_userattributeset_init(&attrset);
+
+ attrset->attr_str = parse_current->next->data;
+
+ rc = cil_gen_expr(parse_current->next->next, CIL_USER, &attrset->str_expr);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ ast_node->data = attrset;
+ ast_node->flavor = CIL_USERATTRIBUTESET;
+
+ return SEPOL_OK;
+
+exit:
+ cil_log(CIL_ERR, "Bad userattributeset declaration at line %d of %s\n",
+ parse_current->line, parse_current->path);
+ cil_destroy_userattributeset(attrset);
+
+ return rc;
+}
+
+void cil_destroy_userattributeset(struct cil_userattributeset *attrset)
+{
+ if (attrset == NULL) {
+ return;
+ }
+
+ cil_list_destroy(&attrset->str_expr, CIL_TRUE);
+ cil_list_destroy(&attrset->datum_expr, CIL_FALSE);
+
+ free(attrset);
+}
+
int cil_gen_userlevel(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
{
enum cil_syntax syntax[] = {
@@ -1903,6 +2025,169 @@ void cil_destroy_avrule(struct cil_avrule *rule)
free(rule);
}
+int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permissionx *permx)
+{
+ enum cil_syntax syntax[] = {
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_LIST,
+ CIL_SYN_END
+ };
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
+ int rc = SEPOL_ERR;
+
+ rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ if (parse_current->data == CIL_KEY_IOCTL) {
+ permx->kind = CIL_PERMX_KIND_IOCTL;
+ } else {
+ cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
+ permx->obj_str = parse_current->next->data;
+
+ rc = cil_gen_expr(parse_current->next->next, CIL_PERMISSIONX, &permx->expr_str);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ return SEPOL_OK;
+
+exit:
+ cil_log(CIL_ERR, "Bad permissionx content at line %d of %s\n",
+ parse_current->line, parse_current->path);
+ return rc;
+}
+
+int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+ enum cil_syntax syntax[] = {
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_LIST,
+ CIL_SYN_END
+ };
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
+ char *key = NULL;
+ struct cil_permissionx *permx = NULL;
+ int rc = SEPOL_ERR;
+
+ if (parse_current == NULL || ast_node == NULL) {
+ goto exit;
+ }
+
+ rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ cil_permissionx_init(&permx);
+
+ key = parse_current->next->data;
+
+ rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)permx, (hashtab_key_t)key, CIL_SYM_PERMX, CIL_PERMISSIONX);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ rc = cil_fill_permissionx(parse_current->next->next->cl_head, permx);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ return SEPOL_OK;
+
+exit:
+ cil_log(CIL_ERR, "Bad permissionx statement at line %d of %s\n",
+ parse_current->line, parse_current->path);
+ cil_destroy_permissionx(permx);
+ cil_clear_node(ast_node);
+ return rc;
+}
+
+void cil_destroy_permissionx(struct cil_permissionx *permx)
+{
+ if (permx == NULL) {
+ return;
+ }
+
+ cil_symtab_datum_destroy(&permx->datum);
+
+ cil_list_destroy(&permx->expr_str, CIL_TRUE);
+ ebitmap_destroy(permx->perms);
+ free(permx->perms);
+ free(permx);
+}
+
+int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind)
+{
+ enum cil_syntax syntax[] = {
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_STRING,
+ CIL_SYN_STRING | CIL_SYN_LIST,
+ CIL_SYN_END
+ };
+ int syntax_len = sizeof(syntax)/sizeof(*syntax);
+ struct cil_avrulex *rule = NULL;
+ int rc = SEPOL_ERR;
+
+ if (parse_current == NULL || ast_node == NULL) {
+ goto exit;
+ }
+
+ rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ cil_avrulex_init(&rule);
+
+ rule->rule_kind = rule_kind;
+ rule->src_str = parse_current->next->data;
+ rule->tgt_str = parse_current->next->next->data;
+
+ if (parse_current->next->next->next->cl_head == NULL) {
+ rule->permx_str = parse_current->next->next->next->data;
+ } else {
+ cil_permissionx_init(&rule->permx);
+
+ rc = cil_fill_permissionx(parse_current->next->next->next->cl_head, rule->permx);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ ast_node->data = rule;
+ ast_node->flavor = CIL_AVRULEX;
+
+ return SEPOL_OK;
+
+exit:
+ cil_log(CIL_ERR, "Bad allowx rule at line %d of %s\n",
+ parse_current->line, parse_current->path);
+ cil_destroy_avrulex(rule);
+ return rc;
+}
+
+void cil_destroy_avrulex(struct cil_avrulex *rule)
+{
+ if (rule == NULL) {
+ return;
+ }
+
+ if (rule->permx_str == NULL && rule->permx != NULL) {
+ cil_destroy_permissionx(rule->permx);
+ }
+
+ free(rule);
+}
+
int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind)
{
enum cil_syntax syntax[] = {
@@ -2217,8 +2502,8 @@ static enum cil_flavor __cil_get_expr_operator_flavor(const char *op)
else if (op == CIL_KEY_EQ) return CIL_EQ; /* Only conditional */
else if (op == CIL_KEY_NEQ) return CIL_NEQ; /* Only conditional */
else if (op == CIL_KEY_XOR) return CIL_XOR;
- else if (op == CIL_KEY_ALL) return CIL_ALL; /* Only set */
- else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset */
+ else if (op == CIL_KEY_ALL) return CIL_ALL; /* Only set and permissionx */
+ else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset and permissionx */
else return CIL_NONE;
}
@@ -5587,27 +5872,14 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
}
if (macro != NULL) {
- if (parse_current->data == CIL_KEY_MACRO) {
+ if (parse_current->data == CIL_KEY_MACRO ||
+ parse_current->data == CIL_KEY_TUNABLE ||
+ parse_current->data == CIL_KEY_IN ||
+ parse_current->data == CIL_KEY_BLOCK ||
+ parse_current->data == CIL_KEY_BLOCKINHERIT ||
+ parse_current->data == CIL_KEY_BLOCKABSTRACT) {
rc = SEPOL_ERR;
- cil_log(CIL_ERR, "Found macro at line %d of %s\n",
- parse_current->line, parse_current->path);
- cil_log(CIL_ERR, "Macros cannot be defined within macro statement\n");
- goto exit;
- }
-
- if (parse_current->data == CIL_KEY_TUNABLE) {
- rc = SEPOL_ERR;
- cil_log(CIL_ERR, "Found tunable at line %d of %s\n",
- parse_current->line, parse_current->path);
- cil_log(CIL_ERR, "Tunables cannot be defined within macro statement\n");
- goto exit;
- }
-
- if (parse_current->data == CIL_KEY_IN) {
- rc = SEPOL_ERR;
- cil_log(CIL_ERR, "Found in at line %d of %s\n",
- parse_current->line, parse_current->path);
- cil_log(CIL_ERR, "in-statements cannot be defined within macro statement\n");
+ cil_log(CIL_ERR, "%s is not allowed in macros (%s:%d)\n", (char *)parse_current->data, parse_current->path, parse_current->line);
goto exit;
}
}
@@ -5705,6 +5977,11 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
*finished = CIL_TREE_SKIP_NEXT;
} else if (parse_current->data == CIL_KEY_USER) {
rc = cil_gen_user(db, parse_current, ast_node);
+ } else if (parse_current->data == CIL_KEY_USERATTRIBUTE) {
+ rc = cil_gen_userattribute(db, parse_current, ast_node);
+ } else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) {
+ rc = cil_gen_userattributeset(db, parse_current, ast_node);
+ *finished = CIL_TREE_SKIP_NEXT;
} else if (parse_current->data == CIL_KEY_USERLEVEL) {
rc = cil_gen_userlevel(db, parse_current, ast_node);
*finished = CIL_TREE_SKIP_NEXT;
@@ -5789,6 +6066,18 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
} else if (parse_current->data == CIL_KEY_NEVERALLOW) {
rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW);
*finished = CIL_TREE_SKIP_NEXT;
+ } else if (parse_current->data == CIL_KEY_ALLOWX) {
+ rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_ALLOWED);
+ *finished = CIL_TREE_SKIP_NEXT;
+ } else if (parse_current->data == CIL_KEY_AUDITALLOWX) {
+ rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_AUDITALLOW);
+ *finished = CIL_TREE_SKIP_NEXT;
+ } else if (parse_current->data == CIL_KEY_DONTAUDITX) {
+ rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_DONTAUDIT);
+ *finished = CIL_TREE_SKIP_NEXT;
+ } else if (parse_current->data == CIL_KEY_PERMISSIONX) {
+ rc = cil_gen_permissionx(db, parse_current, ast_node);
+ *finished = CIL_TREE_SKIP_NEXT;
} else if (parse_current->data == CIL_KEY_TYPETRANSITION) {
rc = cil_gen_typetransition(db, parse_current, ast_node);
} else if (parse_current->data == CIL_KEY_TYPECHANGE) {
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 43bc7f62..11f51f54 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -80,6 +80,10 @@ int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, str
void cil_destroy_sidorder(struct cil_sidorder *sidorder);
int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
void cil_destroy_user(struct cil_user *user);
+int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_userattribute(struct cil_userattribute *attr);
+int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_userattributeset(struct cil_userattributeset *attrset);
int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
void cil_destroy_userlevel(struct cil_userlevel *usrlvl);
int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
@@ -107,6 +111,10 @@ void cil_destroy_roleattributeset(struct cil_roleattributeset *attrset);
int cil_gen_rolebounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
void cil_destroy_avrule(struct cil_avrule *rule);
+int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
+void cil_destroy_avrulex(struct cil_avrulex *rule);
+int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_permissionx(struct cil_permissionx *permx);
int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
void cil_destroy_type_rule(struct cil_type_rule *rule);
int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 199ce1ce..8c50ff0d 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -282,6 +282,8 @@ int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *da
}
}
+ cil_classpermission_init(&new);
+
cil_copy_classperms_list(orig->classperms, &new->classperms);
*copy = new;
@@ -294,6 +296,8 @@ int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void
struct cil_classpermissionset *orig = data;
struct cil_classpermissionset *new = NULL;
+ cil_classpermissionset_init(&new);
+
new->set_str = orig->set_str;
cil_copy_classperms_list(orig->classperms, &new->classperms);
@@ -388,6 +392,41 @@ int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **
return SEPOL_OK;
}
+int cil_copy_userattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
+{
+ struct cil_userattribute *orig = data;
+ struct cil_userattribute *new = NULL;
+ char *key = orig->datum.name;
+ struct cil_symtab_datum *datum = NULL;
+
+ cil_symtab_get_datum(symtab, key, &datum);
+ if (datum == NULL) {
+ cil_userattribute_init(&new);
+ *copy = new;
+ } else {
+ *copy = datum;
+ }
+
+ return SEPOL_OK;
+}
+
+int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+ struct cil_userattributeset *orig = data;
+ struct cil_userattributeset *new = NULL;
+
+ cil_userattributeset_init(&new);
+
+ new->attr_str = orig->attr_str;
+
+ cil_copy_expr(db, orig->str_expr, &new->str_expr);
+ cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
+
+ *copy = new;
+
+ return SEPOL_OK;
+}
+
int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
{
struct cil_userrole *orig = data;
@@ -760,6 +799,59 @@ int cil_copy_avrule(__attribute__((unused)) struct cil_db *db, void *data, void
return SEPOL_OK;
}
+void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new)
+{
+ new->kind = orig->kind;
+ new->obj_str = orig->obj_str;
+ cil_copy_expr(db, orig->expr_str, &new->expr_str);
+}
+
+int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
+{
+ struct cil_permissionx *orig = data;
+ struct cil_permissionx *new = NULL;
+ char *key = orig->datum.name;
+ struct cil_symtab_datum *datum = NULL;
+
+
+ cil_symtab_get_datum(symtab, key, &datum);
+ if (datum != NULL) {
+ cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n");
+ return SEPOL_ERR;
+ }
+
+ cil_permissionx_init(&new);
+ cil_copy_fill_permissionx(db, orig, new);
+
+ *copy = new;
+
+ return SEPOL_OK;
+}
+
+
+int cil_copy_avrulex(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+ struct cil_avrulex *orig = data;
+ struct cil_avrulex *new = NULL;
+
+ cil_avrulex_init(&new);
+
+ new->rule_kind = orig->rule_kind;
+ new->src_str = orig->src_str;
+ new->tgt_str = orig->tgt_str;
+
+ if (new->permx_str != NULL) {
+ new->permx_str = orig->permx_str;
+ } else {
+ cil_permissionx_init(&new->permx);
+ cil_copy_fill_permissionx(db, orig->permx, new->permx);
+ }
+
+ *copy = new;
+
+ return SEPOL_OK;
+}
+
int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
{
struct cil_type_rule *orig = data;
@@ -1660,6 +1752,12 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
case CIL_USER:
copy_func = &cil_copy_user;
break;
+ case CIL_USERATTRIBUTE:
+ copy_func = &cil_copy_userattribute;
+ break;
+ case CIL_USERATTRIBUTESET:
+ copy_func = &cil_copy_userattributeset;
+ break;
case CIL_USERROLE:
copy_func = &cil_copy_userrole;
break;
@@ -1732,6 +1830,12 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
case CIL_AVRULE:
copy_func = &cil_copy_avrule;
break;
+ case CIL_AVRULEX:
+ copy_func = &cil_copy_avrulex;
+ break;
+ case CIL_PERMISSIONX:
+ copy_func = &cil_copy_permissionx;
+ break;
case CIL_TYPE_RULE:
copy_func = &cil_copy_type_rule;
break;
@@ -1909,7 +2013,14 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
if (new->flavor == CIL_BLOCKINHERIT) {
blockinherit = new->data;
- cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
+ // if a blockinherit statement is copied before blockinherit are
+ // resolved (like in an in-statement), the block will not have been
+ // resolved yet, so there's nothing to append yet. This is fine,
+ // the copied blockinherit statement will be handled later, as if
+ // it wasn't in an in-statement
+ if (blockinherit->block != NULL) {
+ cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
+ }
}
if (parent->cl_head == NULL) {
diff --git a/libsepol/cil/src/cil_copy_ast.h b/libsepol/cil/src/cil_copy_ast.h
index bd3a2313..78c34b87 100644
--- a/libsepol/cil/src/cil_copy_ast.h
+++ b/libsepol/cil/src/cil_copy_ast.h
@@ -57,6 +57,8 @@ int cil_copy_sid(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_sidorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_user(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
+int cil_copy_userattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
+int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_userrole(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
int cil_copy_userrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c
new file mode 100644
index 00000000..a76dc378
--- /dev/null
+++ b/libsepol/cil/src/cil_find.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include <sepol/policydb/ebitmap.h>
+
+#include "cil_internal.h"
+#include "cil_flavor.h"
+#include "cil_list.h"
+#include "cil_log.h"
+#include "cil_symtab.h"
+
+struct cil_args_find {
+ enum cil_flavor flavor;
+ void *target;
+ struct cil_list *matching;
+ int match_self;
+};
+
+static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+ enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+ enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+ if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+ struct cil_type *t1 = (struct cil_type *)d1;
+ struct cil_type *t2 = (struct cil_type *)d2;
+ if (t1->value == t2->value) {
+ return CIL_TRUE;
+ }
+ } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+ struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+ struct cil_type *t = (struct cil_type *)d2;
+ if (ebitmap_get_bit(a->types, t->value)) {
+ return CIL_TRUE;
+ }
+ } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+ struct cil_type *t = (struct cil_type *)d1;
+ struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+ if (ebitmap_get_bit(a->types, t->value)) {
+ return CIL_TRUE;
+ }
+ } else {
+ /* Both are attributes */
+ struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+ struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+ return ebitmap_match_any(a1->types, a2->types);
+ }
+ return CIL_FALSE;
+}
+
+static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+ int rc = SEPOL_OK;
+ enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+ enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+ if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+ struct cil_type *t1 = (struct cil_type *)d1;
+ struct cil_type *t2 = (struct cil_type *)d2;
+ if (t1->value == t2->value) {
+ ebitmap_set_bit(matches, t1->value, 1);
+ }
+ } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+ struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+ struct cil_type *t = (struct cil_type *)d2;
+ if (ebitmap_get_bit(a->types, t->value)) {
+ ebitmap_set_bit(matches, t->value, 1);
+ }
+ } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+ struct cil_type *t = (struct cil_type *)d1;
+ struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+ if (ebitmap_get_bit(a->types, t->value)) {
+ ebitmap_set_bit(matches, t->value, 1);
+ }
+ } else {
+ /* Both are attributes */
+ struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+ struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+ rc = ebitmap_and(matches, a1->types, a2->types);
+ }
+
+ return rc;
+}
+
+/* s1 is the src type that is matched with a self
+ * s2, and t2 are the source and type of the other rule
+ */
+static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
+{
+ int rc;
+ struct cil_tree_node *n1 = s1->nodes->head->data;
+ if (n1->flavor != CIL_TYPEATTRIBUTE) {
+ rc = cil_type_match_any(s1, t2);
+ } else {
+ struct cil_typeattribute *a = (struct cil_typeattribute *)s1;
+ ebitmap_t map;
+ ebitmap_init(&map);
+ rc = cil_type_matches(&map, s2, t2);
+ if (rc < 0) {
+ ebitmap_destroy(&map);
+ goto exit;
+ }
+ if (map.node == NULL) {
+ rc = CIL_FALSE;
+ goto exit;
+ }
+ rc = ebitmap_match_any(&map, a->types);
+ ebitmap_destroy(&map);
+ }
+
+exit:
+ return rc;
+}
+
+static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2)
+{
+ struct cil_class *c1 = cp1->class;
+ struct cil_class *c2 = cp2->class;
+ struct cil_list_item *i1, *i2;
+
+ if (&c1->datum != &c2->datum) return CIL_FALSE;
+
+ cil_list_for_each(i1, cp1->perms) {
+ struct cil_perm *p1 = i1->data;
+ cil_list_for_each(i2, cp2->perms) {
+ struct cil_perm *p2 = i2->data;
+ if (&p1->datum == &p2->datum) return CIL_TRUE;
+ }
+ }
+ return CIL_FALSE;
+}
+
+static int __cil_classperms_list_match_any(struct cil_classperms *cp1, struct cil_list *cpl2)
+{
+ int rc;
+ struct cil_list_item *curr;
+
+ cil_list_for_each(curr, cpl2) {
+ if (curr->flavor == CIL_CLASSPERMS) {
+ struct cil_classperms *cp = curr->data;
+ if (FLAVOR(cp->class) == CIL_CLASS) {
+ rc = cil_classperms_match_any(cp1, cp);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ } else { /* MAP */
+ struct cil_list_item *i = NULL;
+ cil_list_for_each(i, cp->perms) {
+ struct cil_perm *cmp = i->data;
+ rc = __cil_classperms_list_match_any(cp1, cmp->classperms);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ }
+ }
+ } else { /* SET */
+ struct cil_classperms_set *cp_set = curr->data;
+ struct cil_classpermission *cp = cp_set->set;
+ rc = __cil_classperms_list_match_any(cp1, cp->classperms);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ }
+ }
+ return CIL_FALSE;
+}
+
+static int cil_classperms_list_match_any(struct cil_list *cpl1, struct cil_list *cpl2)
+{
+ int rc;
+ struct cil_list_item *curr;
+
+ cil_list_for_each(curr, cpl1) {
+ if (curr->flavor == CIL_CLASSPERMS) {
+ struct cil_classperms *cp = curr->data;
+ if (FLAVOR(cp->class) == CIL_CLASS) {
+ rc = __cil_classperms_list_match_any(cp, cpl2);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ } else { /* MAP */
+ struct cil_list_item *i = NULL;
+ cil_list_for_each(i, cp->perms) {
+ struct cil_perm *cmp = i->data;
+ rc = cil_classperms_list_match_any(cmp->classperms, cpl2);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ }
+ }
+ } else { /* SET */
+ struct cil_classperms_set *cp_set = curr->data;
+ struct cil_classpermission *cp = cp_set->set;
+ rc = cil_classperms_list_match_any(cp->classperms, cpl2);
+ if (rc == CIL_TRUE) return CIL_TRUE;
+ }
+ }
+ return CIL_FALSE;
+}
+
+int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrule *avrule, struct cil_avrule *target, struct cil_list *matching, int match_self)
+{
+ int rc = SEPOL_OK;
+ struct cil_symtab_datum *s1 = avrule->src;
+ struct cil_symtab_datum *t1 = avrule->tgt;
+ struct cil_list *cp1 = avrule->classperms;
+ struct cil_symtab_datum *s2 = target->src;
+ struct cil_symtab_datum *t2 = target->tgt;
+ struct cil_list *cp2 = target->classperms;
+
+ if (match_self != CIL_TRUE && avrule == target) goto exit;
+
+ if (avrule->rule_kind != target->rule_kind) goto exit;
+
+ if (!cil_type_match_any(s1, s2)) goto exit;
+
+ if (t1->fqn != CIL_KEY_SELF && t2->fqn != CIL_KEY_SELF) {
+ if (!cil_type_match_any(t1, t2)) goto exit;
+ } else {
+ if (t1->fqn == CIL_KEY_SELF && t2->fqn == CIL_KEY_SELF) {
+ /* The earlier check whether s1 and s2 matches is all that is needed */
+ } else if (t1->fqn == CIL_KEY_SELF) {
+ rc = cil_self_match_any(s1, s2, t2);
+ if (rc < 0) {
+ goto exit;
+ } else if (rc == CIL_FALSE) {
+ rc = SEPOL_OK;
+ goto exit;
+ }
+ } else if (t2->fqn == CIL_KEY_SELF) {
+ rc = cil_self_match_any(s2, s1, t1);
+ if (rc < 0) {
+ goto exit;
+ } else if (rc == CIL_FALSE) {
+ rc = SEPOL_OK;
+ goto exit;
+ }
+ }
+ }
+
+ if (cil_classperms_list_match_any(cp1, cp2)) {
+ cil_list_append(matching, CIL_NODE, node);
+ }
+
+ rc = SEPOL_OK;
+
+exit:
+ return rc;
+}
+
+static int __cil_find_matching_avrule_in_ast(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
+{
+ int rc = SEPOL_OK;
+ struct cil_args_find *args = extra_args;
+
+ if (node->flavor == CIL_BLOCK) {
+ struct cil_block *blk = node->data;
+ if (blk->is_abstract == CIL_TRUE) {
+ *finished = CIL_TREE_SKIP_HEAD;
+ goto exit;
+ }
+ } else if (node->flavor == CIL_MACRO) {
+ *finished = CIL_TREE_SKIP_HEAD;
+ goto exit;
+ } else if (node->flavor == CIL_AVRULE) {
+ rc = cil_find_matching_avrule(node, node->data, args->target, args->matching, args->match_self);
+ }
+
+exit:
+ return rc;
+}
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self)
+{
+ int rc;
+ struct cil_args_find args;
+
+ args.flavor = flavor;
+ args.target = target;
+ args.matching = matching;
+ args.match_self = match_self;
+
+ rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args);
+ if (rc) {
+ cil_log(CIL_ERR, "An error occured while searching for avrule in AST\n");
+ }
+
+ return rc;
+}
diff --git a/libsepol/cil/src/cil_find.h b/libsepol/cil/src/cil_find.h
new file mode 100644
index 00000000..c8ca2d26
--- /dev/null
+++ b/libsepol/cil/src/cil_find.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include "cil_flavor.h"
+#include "cil_tree.h"
+#include "cil_list.h"
+
+#ifndef CIL_FIND_H_
+#define CIL_FIND_H_
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self);
+
+#endif
diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h
index d839f68b..9fb50837 100644
--- a/libsepol/cil/src/cil_flavor.h
+++ b/libsepol/cil/src/cil_flavor.h
@@ -63,6 +63,7 @@ enum cil_flavor {
CIL_CLASSPERMISSIONSET,
CIL_USERPREFIX,
CIL_USERROLE,
+ CIL_USERATTRIBUTESET,
CIL_USERLEVEL,
CIL_USERRANGE,
CIL_USERBOUNDS,
@@ -83,6 +84,7 @@ enum cil_flavor {
CIL_SIDORDER,
CIL_ROLEALLOW,
CIL_AVRULE,
+ CIL_AVRULEX,
CIL_ROLETRANSITION,
CIL_TYPE_RULE,
CIL_NAMETYPETRANSITION,
@@ -163,6 +165,7 @@ enum cil_flavor {
CIL_MAP_CLASS,
CIL_CLASSPERMISSION,
CIL_USER,
+ CIL_USERATTRIBUTE,
CIL_ROLE,
CIL_ROLEATTRIBUTE,
CIL_TYPE,
@@ -180,6 +183,7 @@ enum cil_flavor {
CIL_CONTEXT,
CIL_IPADDR,
CIL_POLICYCAP,
+ CIL_PERMISSIONX
};
diff --git a/libsepol/cil/src/cil_fqn.c b/libsepol/cil/src/cil_fqn.c
index dbdd995d..865bd7de 100644
--- a/libsepol/cil/src/cil_fqn.c
+++ b/libsepol/cil/src/cil_fqn.c
@@ -102,6 +102,7 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has
case CIL_SYM_LEVELRANGES:
case CIL_SYM_IPADDRS:
case CIL_SYM_NAMES:
+ case CIL_SYM_PERMX:
/* These do not show up in the kernal policy */
break;
case CIL_SYM_POLICYCAPS:
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index a43d1116..a736eff3 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -127,6 +127,8 @@ char *CIL_KEY_TRANS;
char *CIL_KEY_TYPE;
char *CIL_KEY_ROLE;
char *CIL_KEY_USER;
+char *CIL_KEY_USERATTRIBUTE;
+char *CIL_KEY_USERATTRIBUTESET;
char *CIL_KEY_SENSITIVITY;
char *CIL_KEY_CATEGORY;
char *CIL_KEY_CATSET;
@@ -216,6 +218,11 @@ char *CIL_KEY_DEFAULTTYPE;
char *CIL_KEY_ROOT;
char *CIL_KEY_NODE;
char *CIL_KEY_PERM;
+char *CIL_KEY_ALLOWX;
+char *CIL_KEY_AUDITALLOWX;
+char *CIL_KEY_DONTAUDITX;
+char *CIL_KEY_PERMISSIONX;
+char *CIL_KEY_IOCTL;
/*
Symbol Table Array Indices
@@ -239,6 +246,7 @@ enum cil_sym_index {
CIL_SYM_POLICYCAPS,
CIL_SYM_IPADDRS,
CIL_SYM_NAMES,
+ CIL_SYM_PERMX,
CIL_SYM_NUM,
CIL_SYM_UNKNOWN,
CIL_SYM_PERMS // Special case for permissions. This symtab is not included in arrays
@@ -279,11 +287,15 @@ struct cil_db {
struct cil_list *userprefixes;
struct cil_list *selinuxusers;
struct cil_list *names;
+ int num_types_and_attrs;
+ int num_classes;
int num_cats;
int num_types;
int num_roles;
+ int num_users;
struct cil_type **val_to_type;
struct cil_role **val_to_role;
+ struct cil_user **val_to_user;
int disable_dontaudit;
int disable_neverallow;
int preserve_tunables;
@@ -410,14 +422,27 @@ struct cil_sidorder {
struct cil_user {
struct cil_symtab_datum datum;
struct cil_user *bounds;
- struct cil_list *roles;
+ ebitmap_t *roles;
struct cil_level *dftlevel;
struct cil_levelrange *range;
+ int value;
+};
+
+struct cil_userattribute {
+ struct cil_symtab_datum datum;
+ struct cil_list *expr_list;
+ ebitmap_t *users;
+};
+
+struct cil_userattributeset {
+ char *attr_str;
+ struct cil_list *str_expr;
+ struct cil_list *datum_expr;
};
struct cil_userrole {
char *user_str;
- struct cil_user *user;
+ void *user;
char *role_str;
void *role;
};
@@ -552,6 +577,26 @@ struct cil_avrule {
struct cil_list *classperms;
};
+#define CIL_PERMX_KIND_IOCTL 1
+struct cil_permissionx {
+ struct cil_symtab_datum datum;
+ uint32_t kind;
+ char *obj_str;
+ void *obj;
+ struct cil_list *expr_str;
+ ebitmap_t *perms;
+};
+
+struct cil_avrulex {
+ uint32_t rule_kind;
+ char *src_str;
+ void *src; /* type, alias, or attribute */
+ char *tgt_str;
+ void *tgt; /* type, alias, or attribute */
+ char *permx_str;
+ struct cil_permissionx *permx;
+};
+
#define CIL_TYPE_TRANSITION 16
#define CIL_TYPE_MEMBER 32
#define CIL_TYPE_CHANGE 64
@@ -928,6 +973,8 @@ void cil_condblock_init(struct cil_condblock **cb);
void cil_tunable_init(struct cil_tunable **ciltun);
void cil_tunif_init(struct cil_tunableif **tif);
void cil_avrule_init(struct cil_avrule **avrule);
+void cil_avrulex_init(struct cil_avrulex **avrulex);
+void cil_permissionx_init(struct cil_permissionx **permx);
void cil_type_rule_init(struct cil_type_rule **type_rule);
void cil_roletransition_init(struct cil_roletransition **roletrans);
void cil_roleallow_init(struct cil_roleallow **role_allow);
@@ -972,5 +1019,7 @@ void cil_default_init(struct cil_default **def);
void cil_defaultrange_init(struct cil_defaultrange **def);
void cil_handleunknown_init(struct cil_handleunknown **unk);
void cil_mls_init(struct cil_mls **mls);
+void cil_userattribute_init(struct cil_userattribute **attribute);
+void cil_userattributeset_init(struct cil_userattributeset **attrset);
#endif
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index eefcbc10..a9e2426b 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1155,11 +1155,6 @@ int __cil_gen_policy_node_helper(struct cil_tree_node *node, uint32_t *finished,
case CIL_USER:
cil_multimap_insert(users, node->data, NULL, CIL_USERROLE, CIL_NONE);
break;
- case CIL_USERROLE: {
- struct cil_userrole *userrole = node->data;
- cil_multimap_insert(users, &userrole->user->datum, (struct cil_symtab_datum *)userrole->role, CIL_USERROLE, CIL_ROLE);
- }
- break;
case CIL_CATALIAS: {
struct cil_alias *alias = node->data;
struct cil_symtab_datum *datum = alias->actual;
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index f91727f4..8050bbbd 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -339,28 +339,53 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini
case CIL_MACRO:
*finished = CIL_TREE_SKIP_HEAD;
break;
+ case CIL_CLASS: {
+ struct cil_class *class = node->data;
+ if (class->datum.nodes->head->data == node) {
+ // Multiple nodes can point to the same datum. Only count once.
+ db->num_classes++;
+ }
+ break;
+ }
case CIL_TYPE: {
struct cil_type *type = node->data;
if (type->datum.nodes->head->data == node) {
- // multiple AST nodes can point to the same cil_type data (like if
- // copied from a macro). This check ensures we only count the
- // duplicates once
+ // Multiple nodes can point to the same datum. Only count once.
type->value = db->num_types;
db->num_types++;
+ db->num_types_and_attrs++;
+ }
+ break;
+ }
+ case CIL_TYPEATTRIBUTE: {
+ struct cil_typeattribute *attr = node->data;
+ if (attr->datum.nodes->head->data == node) {
+ // Multiple nodes can point to the same datum. Only count once.
+ db->num_types_and_attrs++;
}
break;
}
+
case CIL_ROLE: {
struct cil_role *role = node->data;
if (role->datum.nodes->head->data == node) {
- // multiple AST nodes can point to the same cil_role data (like if
- // copied from a macro). This check ensures we only count the
- // duplicates once
+ // Multiple nodes can point to the same datum. Only count once.
role->value = db->num_roles;
db->num_roles++;
}
break;
}
+ case CIL_USER: {
+ struct cil_user *user = node->data;
+ if (user->datum.nodes->head->data == node) {
+ // multiple AST nodes can point to the same cil_user data (like if
+ // copied from a macro). This check ensures we only count the
+ // duplicates once
+ user->value = db->num_users;
+ db->num_users++;
+ }
+ break;
+ }
case CIL_NETIFCON:
db->netifcon->count++;
break;
@@ -432,6 +457,14 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__(
db->val_to_role[role->value] = role;
break;
}
+ case CIL_USER: {
+ struct cil_user *user= node->data;
+ if (db->val_to_user == NULL) {
+ db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users);
+ }
+ db->val_to_user[user->value] = user;
+ break;
+ }
case CIL_USERPREFIX: {
cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data);
break;
@@ -624,6 +657,54 @@ exit:
return rc;
}
+static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db)
+{
+ int rc;
+
+ attr->users = cil_malloc(sizeof(*attr->users));
+ rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n");
+ ebitmap_destroy(attr->users);
+ free(attr->users);
+ attr->users = NULL;
+ }
+ return rc;
+}
+
+static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
+{
+ int rc = SEPOL_ERR;
+ struct cil_tree_node *node = datum->nodes->head->data;
+ struct cil_userattribute *attr = NULL;
+ struct cil_user *user = NULL;
+
+ ebitmap_init(bitmap);
+
+ if (node->flavor == CIL_USERATTRIBUTE) {
+ attr = (struct cil_userattribute *)datum;
+ if (attr->users == NULL) {
+ rc = __evaluate_user_expression(attr, db);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ ebitmap_union(bitmap, attr->users);
+ } else {
+ user = (struct cil_user *)datum;
+ if (ebitmap_set_bit(bitmap, user->value, 1)) {
+ cil_log(CIL_ERR, "Failed to set user bit\n");
+ ebitmap_destroy(bitmap);
+ goto exit;
+ }
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db)
{
int rc;
@@ -668,6 +749,70 @@ exit:
return rc;
}
+static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db)
+{
+ int rc;
+
+ permx->perms = cil_malloc(sizeof(*permx->perms));
+ ebitmap_init(permx->perms);
+
+ rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_ERR, "Failed to expand permissionx expression\n");
+ ebitmap_destroy(permx->perms);
+ free(permx->perms);
+ permx->perms = NULL;
+ }
+
+ return rc;
+}
+
+static int __cil_permx_str_to_int(char *permx_str, uint16_t *val)
+{
+ char *endptr = NULL;
+ long lval = strtol(permx_str, &endptr, 0);
+
+ if (*endptr != '\0') {
+ cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str);
+ goto exit;
+ }
+ if (lval < 0x0000 || lval > 0xFFFF) {
+ cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str);
+ goto exit;
+ }
+
+ *val = (uint16_t)lval;
+
+ return SEPOL_OK;
+
+exit:
+ return SEPOL_ERR;
+}
+
+static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
+{
+ int rc = SEPOL_ERR;
+ uint16_t val;
+
+ ebitmap_init(bitmap);
+
+ rc = __cil_permx_str_to_int((char*)datum, &val);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) {
+ cil_log(CIL_ERR, "Failed to set permissionx bit\n");
+ ebitmap_destroy(bitmap);
+ goto exit;
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
{
struct cil_perm *perm = (struct cil_perm *)datum;
@@ -778,7 +923,7 @@ exit:
return rc;
}
-static int __cil_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
+static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
{
int rc = SEPOL_ERR;
struct cil_symtab_datum *d1 = i1->data;
@@ -818,6 +963,39 @@ exit:
return rc;
}
+static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
+{
+ int rc = SEPOL_ERR;
+ char *p1 = i1->data;
+ char *p2 = i2->data;
+ uint16_t v1;
+ uint16_t v2;
+ uint32_t i;
+
+ rc = __cil_permx_str_to_int(p1, &v1);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ rc = __cil_permx_str_to_int(p2, &v2);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ for (i = v1; i <= v2; i++) {
+ if (ebitmap_set_bit(bitmap, i, 1)) {
+ cil_log(CIL_ERR, "Failed to set permissionx bit\n");
+ ebitmap_destroy(bitmap);
+ goto exit;
+ }
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flavor flavor, ebitmap_t *bitmap, int max, struct cil_db *db)
{
int rc = SEPOL_ERR;
@@ -830,6 +1008,9 @@ static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flav
case CIL_ROLE:
rc = __cil_role_to_bitmap(curr->data, bitmap, db);
break;
+ case CIL_USER:
+ rc = __cil_user_to_bitmap(curr->data, bitmap, db);
+ break;
case CIL_PERM:
rc = __cil_perm_to_bitmap(curr->data, bitmap, db);
break;
@@ -846,6 +1027,10 @@ static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flav
if (rc != SEPOL_OK) {
ebitmap_destroy(bitmap);
}
+ } else if (flavor == CIL_PERMISSIONX) {
+ // permissionx expressions aren't resolved into anything, so curr->flavor
+ // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
+ rc = __cil_permx_to_bitmap(curr->data, bitmap, db);
}
return rc;
@@ -878,18 +1063,27 @@ static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max,
goto exit;
}
} else if (op == CIL_RANGE) {
- if (flavor != CIL_CAT) {
- cil_log(CIL_INFO, "Range operation only supported for categories\n");
+ if (flavor == CIL_CAT) {
+ ebitmap_init(&tmp);
+ rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_INFO, "Failed to expand category range\n");
+ ebitmap_destroy(&tmp);
+ goto exit;
+ }
+ } else if (flavor == CIL_PERMISSIONX) {
+ ebitmap_init(&tmp);
+ rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_INFO, "Failed to expand category range\n");
+ ebitmap_destroy(&tmp);
+ goto exit;
+ }
+ } else {
+ cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n");
rc = SEPOL_ERR;
goto exit;
}
- ebitmap_init(&tmp);
- rc = __cil_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
- if (rc != SEPOL_OK) {
- cil_log(CIL_INFO, "Failed to expand category range\n");
- ebitmap_destroy(&tmp);
- goto exit;
- }
} else {
rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db);
if (rc != SEPOL_OK) {
@@ -1025,6 +1219,30 @@ static int __cil_post_db_attr_helper(struct cil_tree_node *node, __attribute__((
}
break;
}
+ case CIL_AVRULEX: {
+ struct cil_avrulex *rule = node->data;
+ if (rule->permx_str == NULL) {
+ rc = __evaluate_permissionx_expression(rule->permx, db);
+ if (rc != SEPOL_OK) goto exit;
+ }
+ break;
+ }
+ case CIL_PERMISSIONX: {
+ struct cil_permissionx *permx = node->data;
+ rc = __evaluate_permissionx_expression(permx, db);
+ if (rc != SEPOL_OK) goto exit;
+ break;
+ }
+ case CIL_USERATTRIBUTE: {
+ struct cil_userattribute *attr = node->data;
+ if (attr->users == NULL) {
+ rc = __evaluate_user_expression(attr, db);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ break;
+ }
default:
break;
}
@@ -1130,6 +1348,102 @@ exit:
return rc;
}
+static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum)
+{
+ struct cil_tree_node *node = datum->nodes->head->data;
+ struct cil_role *role = NULL;
+ struct cil_roleattribute *attr = NULL;
+
+ if (user->roles == NULL) {
+ user->roles = cil_malloc(sizeof(*user->roles));
+ ebitmap_init(user->roles);
+ }
+
+ if (node->flavor == CIL_ROLE) {
+ role = (struct cil_role *)datum;
+ if (ebitmap_set_bit(user->roles, role->value, 1)) {
+ cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n");
+ goto exit;
+ }
+ } else if (node->flavor == CIL_ROLEATTRIBUTE) {
+ attr = (struct cil_roleattribute *)datum;
+ ebitmap_union(user->roles, attr->roles);
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return SEPOL_ERR;
+}
+
+static int __cil_post_db_userrole_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
+{
+ int rc = SEPOL_ERR;
+ struct cil_db *db = extra_args;
+ struct cil_block *blk = NULL;
+ struct cil_userrole *userrole = NULL;
+ struct cil_symtab_datum *user_datum = NULL;
+ struct cil_symtab_datum *role_datum = NULL;
+ struct cil_tree_node *user_node = NULL;
+ struct cil_userattribute *u_attr = NULL;
+ unsigned int i;
+ struct cil_user *user = NULL;
+ ebitmap_node_t *unode = NULL;
+
+ switch (node->flavor) {
+ case CIL_BLOCK: {
+ blk = node->data;
+ if (blk->is_abstract == CIL_TRUE) {
+ *finished = CIL_TREE_SKIP_HEAD;
+ }
+ break;
+ }
+ case CIL_MACRO: {
+ *finished = CIL_TREE_SKIP_HEAD;
+ break;
+ }
+ case CIL_USERROLE: {
+ userrole = node->data;
+ user_datum = userrole->user;
+ role_datum = userrole->role;
+ user_node = user_datum->nodes->head->data;
+
+ if (user_node->flavor == CIL_USERATTRIBUTE) {
+ u_attr = userrole->user;
+
+ ebitmap_for_each_bit(u_attr->users, unode, i) {
+ if (!ebitmap_get_bit(u_attr->users, i)) {
+ continue;
+ }
+
+ user = db->val_to_user[i];
+
+ rc = __cil_user_assign_roles(user, role_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+ } else {
+ user = userrole->user;
+
+ rc = __cil_user_assign_roles(user, role_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ return SEPOL_OK;
+exit:
+ cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n");
+ return rc;
+}
+
static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db)
{
if (level->cats != NULL) {
@@ -1601,6 +1915,12 @@ static int cil_post_db(struct cil_db *db)
goto exit;
}
+ rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_INFO, "Failed during userrole association\n");
+ goto exit;
+ }
+
rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db);
if (rc != SEPOL_OK) {
cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n");
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 92f7720b..09cff053 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -99,7 +99,32 @@ static void cil_reset_user(struct cil_user *user)
user->bounds = NULL;
user->dftlevel = NULL;
user->range = NULL;
- cil_list_destroy(&user->roles, CIL_FALSE);
+}
+
+static void cil_reset_userattr(struct cil_userattribute *attr)
+{
+ struct cil_list_item *expr = NULL;
+ struct cil_list_item *next = NULL;
+
+ /* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a userattribute statement */
+ if (attr->expr_list != NULL) {
+ /* we don't want to destroy the expression stacks (cil_list) inside
+ * this list cil_list_destroy destroys sublists, so we need to do it
+ * manually */
+ expr = attr->expr_list->head;
+ while (expr != NULL) {
+ next = expr->next;
+ cil_list_item_destroy(&expr, CIL_FALSE);
+ expr = next;
+ }
+ free(attr->expr_list);
+ attr->expr_list = NULL;
+ }
+}
+
+static void cil_reset_userattributeset(struct cil_userattributeset *uas)
+{
+ cil_list_destroy(&uas->datum_expr, CIL_FALSE);
}
static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser)
@@ -403,6 +428,12 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
case CIL_USER:
cil_reset_user(node->data);
break;
+ case CIL_USERATTRIBUTE:
+ cil_reset_userattr(node->data);
+ break;
+ case CIL_USERATTRIBUTESET:
+ cil_reset_userattributeset(node->data);
+ break;
case CIL_SELINUXUSERDEFAULT:
case CIL_SELINUXUSER:
cil_reset_selinuxuser(node->data);
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index c9738da1..e332cbd8 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -51,7 +51,7 @@ struct cil_args_resolve {
struct cil_db *db;
enum cil_pass pass;
uint32_t *changed;
- struct cil_tree_node *callstack;
+ char *last_resolved_name;
struct cil_tree_node *optstack;
struct cil_tree_node *boolif;
struct cil_tree_node *macro;
@@ -319,6 +319,75 @@ exit:
return rc;
}
+int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args)
+{
+ struct cil_symtab_datum *obj_datum = NULL;
+ int rc = SEPOL_ERR;
+
+ rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ permx->obj = (struct cil_class*)obj_datum;
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
+int cil_resolve_avrulex(struct cil_tree_node *current, void *extra_args)
+{
+ struct cil_args_resolve *args = extra_args;
+ struct cil_db *db = NULL;
+
+ struct cil_avrulex *rule = current->data;
+ struct cil_symtab_datum *src_datum = NULL;
+ struct cil_symtab_datum *tgt_datum = NULL;
+ struct cil_symtab_datum *permx_datum = NULL;
+ int rc = SEPOL_ERR;
+
+ if (args != NULL) {
+ db = args->db;
+ }
+
+ rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ rule->src = src_datum;
+ cil_type_used(src_datum);
+
+ if (rule->tgt_str == CIL_KEY_SELF) {
+ rule->tgt = db->selftype;
+ } else {
+ rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ rule->tgt = tgt_datum;
+ cil_type_used(tgt_datum);
+ }
+
+ if (rule->permx_str != NULL) {
+ rc = cil_resolve_name(current, rule->permx_str, CIL_SYM_PERMX, args, &permx_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ rule->permx = (struct cil_permissionx*)permx_datum;
+ } else {
+ rc = cil_resolve_permissionx(current, rule->permx, extra_args);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ }
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
+
int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
{
struct cil_type_rule *rule = current->data;
@@ -750,12 +819,6 @@ int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args)
}
userrole->role = role_datum;
- if (userrole->user->roles == NULL) {
- cil_list_init(&userrole->user->roles, CIL_LIST_ITEM);
- }
-
- cil_list_append(userrole->user->roles, CIL_ROLE, userrole->role);
-
return SEPOL_OK;
exit:
@@ -768,12 +831,22 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
struct cil_symtab_datum *user_datum = NULL;
struct cil_symtab_datum *lvl_datum = NULL;
struct cil_user *user = NULL;
+ struct cil_tree_node *user_node = NULL;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum);
if (rc != SEPOL_OK) {
goto exit;
}
+
+ user_node = user_datum->nodes->head->data;
+
+ if (user_node->flavor != CIL_USER) {
+ cil_log(CIL_ERR, "Userlevel must be a user\n");
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
user = (struct cil_user*)user_datum;
if (usrlvl->level_str != NULL) {
@@ -811,12 +884,22 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
struct cil_symtab_datum *user_datum = NULL;
struct cil_symtab_datum *range_datum = NULL;
struct cil_user *user = NULL;
+ struct cil_tree_node *user_node = NULL;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum);
if (rc != SEPOL_OK) {
goto exit;
}
+
+ user_node = user_datum->nodes->head->data;
+
+ if (user_node->flavor != CIL_USER) {
+ cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
user = (struct cil_user*)user_datum;
if (userrange->range_str != NULL) {
@@ -852,12 +935,22 @@ int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args)
{
struct cil_userprefix *userprefix = current->data;
struct cil_symtab_datum *user_datum = NULL;
+ struct cil_tree_node *user_node = NULL;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum);
if (rc != SEPOL_OK) {
goto exit;
}
+
+ user_node = user_datum->nodes->head->data;
+
+ if (user_node->flavor != CIL_USER) {
+ cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
userprefix->user = (struct cil_user*)user_datum;
exit:
@@ -869,18 +962,27 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
struct cil_selinuxuser *selinuxuser = current->data;
struct cil_symtab_datum *user_datum = NULL;
struct cil_symtab_datum *lvlrange_datum = NULL;
+ struct cil_tree_node *user_node = NULL;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum);
if (rc != SEPOL_OK) {
goto exit;
}
+
+ user_node = user_datum->nodes->head->data;
+
+ if (user_node->flavor != CIL_USER) {
+ cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
selinuxuser->user = (struct cil_user*)user_datum;
if (selinuxuser->range_str != NULL) {
rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Unable to resolve name: %s\n", selinuxuser->range_str);
goto exit;
}
selinuxuser->range = (struct cil_levelrange*)lvlrange_datum;
@@ -1455,7 +1557,6 @@ int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, void
rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR,"Unable to resolve categories\n");
goto exit;
}
@@ -1647,34 +1748,48 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
struct cil_symtab_datum *user_datum = NULL;
struct cil_symtab_datum *role_datum = NULL;
struct cil_symtab_datum *type_datum = NULL;
- struct cil_tree_node *type_node = NULL;
+ struct cil_tree_node *node = NULL;
struct cil_symtab_datum *lvlrange_datum = NULL;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->user_str);
goto exit;
}
+
+ node = user_datum->nodes->head->data;
+
+ if (node->flavor != CIL_USER) {
+ cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
context->user = (struct cil_user*)user_datum;
rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->role_str);
goto exit;
}
+
+ node = role_datum->nodes->head->data;
+ if (node->flavor != CIL_ROLE) {
+ rc = SEPOL_ERR;
+ cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn);
+ goto exit;
+ }
+
context->role = (struct cil_role*)role_datum;
rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->type_str);
goto exit;
}
- type_node = type_datum->nodes->head->data;
+ node = type_datum->nodes->head->data;
- if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
+ if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) {
rc = SEPOL_ERR;
cil_log(CIL_ERR, "Type not a type or type alias\n");
goto exit;
@@ -1684,7 +1799,6 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
if (context->range_str != NULL) {
rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->range_str);
goto exit;
}
context->range = (struct cil_levelrange*)lvlrange_datum;
@@ -2095,6 +2209,73 @@ exit:
return rc;
}
+void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
+{
+ struct cil_list *trace = NULL;
+ struct cil_list_item *item = NULL;
+ struct cil_tree_node *curr = NULL;
+
+ cil_list_init(&trace, CIL_NODE);
+
+ for (curr = bi_node; curr != terminating_node; curr = curr->parent) {
+ if (curr->flavor == CIL_BLOCK) {
+ cil_list_prepend(trace, CIL_NODE, curr);
+ } else {
+ if (curr != bi_node) {
+ cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block));
+ }
+ cil_list_prepend(trace, CIL_NODE, curr);
+ }
+ }
+ cil_list_prepend(trace, CIL_NODE, terminating_node);
+
+ cil_list_for_each(item, trace) {
+ curr = item->data;
+ cil_log(CIL_ERR, " %s:%d: ", curr->path, curr->line);
+
+ if (curr->flavor == CIL_BLOCK) {
+ cil_log(CIL_ERR, "block %s\n", DATUM(curr->data)->name);
+ } else {
+ cil_log(CIL_ERR, "blockinherit %s\n", ((struct cil_blockinherit *)curr->data)->block_str);
+ }
+ }
+
+ cil_list_destroy(&trace, CIL_FALSE);
+}
+
+int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
+{
+ struct cil_tree_node *curr = NULL;
+ struct cil_blockinherit *bi = NULL;
+ struct cil_block *block = NULL;
+ int rc = SEPOL_ERR;
+
+ bi = bi_node->data;
+
+ for (curr = bi_node->parent; curr != NULL; curr = curr->parent) {
+ if (curr->flavor != CIL_BLOCK) {
+ continue;
+ }
+
+ block = curr->data;
+
+ if (block != bi->block) {
+ continue;
+ }
+
+ cil_log(CIL_ERR, "Recursive blockinherit found:\n");
+ cil_print_recursive_blockinherit(bi_node, curr);
+
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
+ rc = SEPOL_OK;
+
+exit:
+ return rc;
+}
+
int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
{
struct cil_block *block = current->data;
@@ -2118,6 +2299,11 @@ int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_arg
}
cil_list_for_each(item, block->bi_nodes) {
+ rc = cil_check_recursive_blockinherit(item->data);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
rc = cil_copy_ast(db, current, item->data);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n");
@@ -2351,7 +2537,6 @@ int cil_resolve_default(struct cil_tree_node *current, void *extra_args)
cil_list_for_each(curr, def->class_strs) {
rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to resolve class %s in %s\n", (char *)curr->data, cil_node_to_string(current));
goto exit;
}
cil_list_append(def->class_datums, CIL_CLASS, datum);
@@ -2375,7 +2560,6 @@ int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_args)
cil_list_for_each(curr, def->class_strs) {
rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to resolve class %s in defaultrange\n", (char *)curr->data);
goto exit;
}
cil_list_append(def->class_datums, CIL_CLASS, datum);
@@ -2387,6 +2571,80 @@ exit:
return rc;
}
+void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node)
+{
+ struct cil_list *trace = NULL;
+ struct cil_list_item * item = NULL;
+ struct cil_tree_node *curr = NULL;
+
+ cil_list_init(&trace, CIL_NODE);
+
+ for (curr = call_node; curr != terminating_node; curr = curr->parent) {
+ if (curr->flavor == CIL_CALL) {
+ if (curr != call_node) {
+ cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro));
+ }
+ cil_list_prepend(trace, CIL_NODE, curr);
+ }
+ }
+
+ if (terminating_node->flavor == CIL_MACRO) {
+ cil_list_prepend(trace, CIL_NODE, terminating_node);
+ } else {
+ cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro));
+ }
+
+ cil_list_for_each(item, trace) {
+ curr = item->data;
+ cil_log(CIL_ERR, " %s:%d: ", curr->path, curr->line);
+
+ if (curr->flavor == CIL_MACRO) {
+ cil_log(CIL_ERR, "macro %s\n", DATUM(curr->data)->name);
+ } else {
+ cil_log(CIL_ERR, "call %s\n", ((struct cil_call *)curr->data)->macro_str);
+ }
+ }
+
+ cil_list_destroy(&trace, CIL_FALSE);
+}
+
+int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node)
+{
+ struct cil_tree_node *curr = NULL;
+ struct cil_call * call = NULL;
+ int rc = SEPOL_ERR;
+
+ for (curr = call_node; curr != NULL; curr = curr->parent) {
+ if (curr->flavor == CIL_CALL) {
+ if (curr == call_node) {
+ continue;
+ }
+
+ call = curr->data;
+ if (call->macro != macro_node->data) {
+ continue;
+ }
+ } else if (curr->flavor == CIL_MACRO) {
+ if (curr != macro_node) {
+ rc = SEPOL_OK;
+ goto exit;
+ }
+ } else {
+ continue;
+ }
+
+ cil_log(CIL_ERR, "Recursive macro call found:\n");
+ cil_print_recursive_call(call_node, curr);
+
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
+ rc = SEPOL_OK;
+exit:
+ return rc;
+}
+
int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
{
struct cil_call *new_call = current->data;
@@ -2408,7 +2666,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
macro_node = macro_datum->nodes->head->data;
if (macro_node->flavor != CIL_MACRO) {
- printf("Failed to resolve macro %s\n", new_call->macro_str);
+ printf("Failed to resolve %s to a macro\n", new_call->macro_str);
rc = SEPOL_ERR;
goto exit;
}
@@ -2623,6 +2881,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
if (new_call->copied == 0) {
new_call->copied = 1;
+
+ rc = cil_check_recursive_call(current, macro_node);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
rc = cil_copy_ast(db, macro_node, current);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
@@ -2974,6 +3238,48 @@ exit:
return rc;
}
+int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args)
+{
+ int rc = SEPOL_ERR;
+ struct cil_userattributeset *attrusers = current->data;
+ struct cil_symtab_datum *attr_datum = NULL;
+ struct cil_tree_node *attr_node = NULL;
+ struct cil_userattribute *attr = NULL;
+
+ rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+ attr_node = attr_datum->nodes->head->data;
+
+ if (attr_node->flavor != CIL_USERATTRIBUTE) {
+ rc = SEPOL_ERR;
+ cil_log(CIL_ERR, "Attribute user not an attribute\n");
+ goto exit;
+ }
+ attr = (struct cil_userattribute*)attr_datum;
+
+ rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ if (attr->expr_list == NULL) {
+ cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE);
+ }
+
+ cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr);
+
+ return SEPOL_OK;
+
+exit:
+ return rc;
+}
int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
{
@@ -3128,6 +3434,12 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
case CIL_AVRULE:
rc = cil_resolve_avrule(node, args);
break;
+ case CIL_AVRULEX:
+ rc = cil_resolve_avrulex(node, args);
+ break;
+ case CIL_PERMISSIONX:
+ rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args);
+ break;
case CIL_TYPE_RULE:
rc = cil_resolve_type_rule(node, args);
break;
@@ -3228,6 +3540,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
case CIL_DEFAULTRANGE:
rc = cil_resolve_defaultrange(node, args);
break;
+ case CIL_USERATTRIBUTESET:
+ rc = cil_resolve_userattributeset(node, args);
+ break;
default:
break;
}
@@ -3250,6 +3565,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu
struct cil_tree_node *optstack = args->optstack;
struct cil_tree_node *boolif = args->boolif;
struct cil_tree_node *blockstack = args->blockstack;
+ struct cil_tree_node *macro = args->macro;
if (node == NULL) {
goto exit;
@@ -3272,6 +3588,17 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu
}
}
+ if (macro != NULL) {
+ if (node->flavor == CIL_BLOCKINHERIT ||
+ node->flavor == CIL_BLOCK ||
+ node->flavor == CIL_BLOCKABSTRACT ||
+ node->flavor == CIL_MACRO) {
+ cil_log(CIL_ERR, "%s statement is not allowed in macros (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+ }
+
if (boolif != NULL) {
if (!(node->flavor == CIL_CONDBLOCK ||
node->flavor == CIL_AVRULE ||
@@ -3304,14 +3631,22 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu
}
rc = __cil_resolve_ast_node(node, extra_args);
- if (rc == SEPOL_ENOENT && optstack != NULL) {
- struct cil_optional *opt = (struct cil_optional *)optstack->data;
- cil_log(CIL_WARN, "Disabling optional %s at %d of %s\n", opt->datum.name, node->parent->line, node->parent->path);
- /* disable an optional if something failed to resolve */
- opt->enabled = CIL_FALSE;
- rc = SEPOL_OK;
- } else if (rc != SEPOL_OK) {
- cil_log(CIL_ERR, "Failed to resolve %s statement at %d of %s\n", cil_node_to_string(node), node->line, node->path);
+ if (rc == SEPOL_ENOENT) {
+ enum cil_log_level lvl = CIL_ERR;
+
+ if (optstack != NULL) {
+ lvl = CIL_WARN;
+
+ struct cil_optional *opt = (struct cil_optional *)optstack->data;
+ struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
+ cil_log(lvl, "Disabling optional '%s' at line %d of %s: ", opt->datum.name, opt_node->line, opt_node->path);
+ /* disable an optional if something failed to resolve */
+ opt->enabled = CIL_FALSE;
+ rc = SEPOL_OK;
+ }
+
+ cil_log(lvl, "Failed to resolve '%s' in %s statement at line %d of %s\n",
+ args->last_resolved_name, cil_node_to_string(node), node->line, node->path);
goto exit;
}
@@ -3325,7 +3660,6 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex
{
int rc = SEPOL_ERR;
struct cil_args_resolve *args = extra_args;
- struct cil_tree_node *callstack = NULL;
struct cil_tree_node *optstack = NULL;
struct cil_tree_node *parent = NULL;
struct cil_tree_node *blockstack = NULL;
@@ -3335,36 +3669,18 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex
goto exit;
}
- callstack = args->callstack;
optstack = args->optstack;
parent = current->parent;
blockstack = args->blockstack;
- if (parent->flavor == CIL_CALL || parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
+ if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
/* push this node onto a stack */
cil_tree_node_init(&new);
new->data = parent->data;
new->flavor = parent->flavor;
- if (parent->flavor == CIL_CALL) {
- if (callstack != NULL) {
- struct cil_tree_node *curr = NULL;
- struct cil_call *new_call = new->data;
- for (curr = callstack->cl_head; curr != NULL;
- curr = curr->cl_head) {
- struct cil_call *curr_call = curr->data;
- if (curr_call->macro == new_call->macro) {
- cil_log(CIL_ERR, "Recursive macro call found\n");
- rc = SEPOL_ERR;
- goto exit;
- }
- }
- callstack->parent = new;
- new->cl_head = callstack;
- }
- args->callstack = new;
- } else if (parent->flavor == CIL_OPTIONAL) {
+ if (parent->flavor == CIL_OPTIONAL) {
if (optstack != NULL) {
optstack->parent = new;
new->cl_head = optstack;
@@ -3403,15 +3719,7 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
parent = current->parent;
- if (parent->flavor == CIL_CALL) {
- /* pop off the stack */
- struct cil_tree_node *callstack = args->callstack;
- args->callstack = callstack->cl_head;
- if (callstack->cl_head) {
- callstack->cl_head->parent = NULL;
- }
- free(callstack);
- } else if (parent->flavor == CIL_MACRO) {
+ if (parent->flavor == CIL_MACRO) {
args->macro = NULL;
} else if (parent->flavor == CIL_OPTIONAL) {
struct cil_tree_node *optstack;
@@ -3460,7 +3768,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
extra_args.db = db;
extra_args.pass = pass;
extra_args.changed = &changed;
- extra_args.callstack = NULL;
+ extra_args.last_resolved_name = NULL;
extra_args.optstack = NULL;
extra_args.boolif= NULL;
extra_args.macro = NULL;
@@ -3552,12 +3860,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
/* reset the arguments */
changed = 0;
- while (extra_args.callstack != NULL) {
- struct cil_tree_node *curr = extra_args.callstack;
- struct cil_tree_node *next = curr->cl_head;
- free(curr);
- extra_args.callstack = next;
- }
while (extra_args.optstack != NULL) {
struct cil_tree_node *curr = extra_args.optstack;
struct cil_tree_node *next = curr->cl_head;
@@ -3579,6 +3881,12 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
rc = SEPOL_OK;
exit:
+ __cil_ordered_lists_destroy(&extra_args.sidorder_lists);
+ __cil_ordered_lists_destroy(&extra_args.classorder_lists);
+ __cil_ordered_lists_destroy(&extra_args.catorder_lists);
+ __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
+ cil_list_destroy(&extra_args.in_list, CIL_FALSE);
+
return rc;
}
@@ -3734,8 +4042,6 @@ int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_in
exit:
if (rc != SEPOL_OK) {
*datum = NULL;
- cil_log(CIL_WARN, "Failed to resolve %s in %s statement on line %d of %s\n",
- name, cil_node_to_string(ast_node), ast_node->line, ast_node->path);
}
if (*datum != NULL) {
@@ -3752,5 +4058,7 @@ exit:
}
}
+ args->last_resolved_name = name;
+
return rc;
}
diff --git a/libsepol/cil/src/cil_resolve_ast.h b/libsepol/cil/src/cil_resolve_ast.h
index e99f0a46..1175f974 100644
--- a/libsepol/cil/src/cil_resolve_ast.h
+++ b/libsepol/cil/src/cil_resolve_ast.h
@@ -54,6 +54,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args);
int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args);
int cil_resolve_userbounds(struct cil_tree_node *current, void *extra_args);
int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args);
+int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args);
int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args);
int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args);
int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args);
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 6a731f22..f641baaf 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -640,15 +640,18 @@ void cil_tree_print_node(struct cil_tree_node *node)
case CIL_USERROLE: {
struct cil_userrole *userrole = node->data;
cil_log(CIL_INFO, "USERROLE:");
+ struct cil_symtab_datum *datum = NULL;
if (userrole->user != NULL) {
- cil_log(CIL_INFO, " %s", userrole->user->datum.name);
+ datum = userrole->user;
+ cil_log(CIL_INFO, " %s", datum->name);
} else if (userrole->user_str != NULL) {
cil_log(CIL_INFO, " %s", userrole->user_str);
}
if (userrole->role != NULL) {
- cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)userrole->role)->name);
+ datum = userrole->role;
+ cil_log(CIL_INFO, " %s", datum->name);
} else if (userrole->role_str != NULL) {
cil_log(CIL_INFO, " %s", userrole->role_str);
}
@@ -785,6 +788,21 @@ void cil_tree_print_node(struct cil_tree_node *node)
cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name);
return;
}
+ case CIL_USERATTRIBUTESET: {
+ struct cil_userattributeset *attr = node->data;
+
+ cil_log(CIL_INFO, "(USERATTRIBUTESET %s ", attr->attr_str);
+
+ cil_tree_print_expr(attr->datum_expr, attr->str_expr);
+
+ cil_log(CIL_INFO, "\n");
+ return;
+ }
+ case CIL_USERATTRIBUTE: {
+ struct cil_userattribute *attr = node->data;
+ cil_log(CIL_INFO, "USERATTRIBUTE: %s\n", attr->datum.name);
+ return;
+ }
case CIL_ROLEBOUNDS: {
struct cil_bounds *bnds = node->data;
cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str);
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 62b88d06..c2d5ce91 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -179,8 +179,8 @@ int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, en
syntax_len = 2;
break;
case CIL_RANGE:
- if (expr_flavor != CIL_CAT) {
- cil_log(CIL_ERR,"Operator (%s) only valid for catset expression\n", (char*)current->data);
+ if (expr_flavor != CIL_CAT && expr_flavor != CIL_PERMISSIONX) {
+ cil_log(CIL_ERR,"Operator (%s) only valid for catset and permissionx expression\n", (char*)current->data);
goto exit;
}
syntax[1] = CIL_SYN_STRING;
@@ -737,16 +737,8 @@ int __cil_verify_context(struct cil_db *db, struct cil_context *ctx)
int found = CIL_FALSE;
if (user->roles != NULL) {
- cil_list_for_each(curr, user->roles) {
- struct cil_role *userrole = curr->data;
- if (userrole == role) {
- break;
- }
- }
-
- if (curr == NULL) {
- cil_log(CIL_ERR, "Role %s is invalid for user %s\n",
- ctx->role_str, ctx->user_str);
+ if (!ebitmap_get_bit(user->roles, role->value)) {
+ cil_log(CIL_ERR, "Role %s is invalid for user %s\n", ctx->role_str, ctx->user_str);
rc = SEPOL_ERR;
goto exit;
}
@@ -1494,13 +1486,22 @@ static int __cil_verify_classpermission(struct cil_tree_node *node)
int rc = SEPOL_ERR;
struct cil_classpermission *cp = node->data;
+ if (cp->classperms == NULL) {
+ cil_log(CIL_ERR, "Classpermission %s does not have a classpermissionset at line %d of %s\n", cp->datum.name, node->line, node->path);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+
rc = __cil_verify_classperms(cp->classperms, &cp->datum);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Found circular class permissions involving the set %s at line %d of %s\n",cp->datum.name, node->line, node->path);
- return rc;
+ goto exit;
}
- return SEPOL_OK;
+ rc = SEPOL_OK;
+
+exit:
+ return rc;
}
struct cil_verify_map_args {
@@ -1515,12 +1516,20 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k,
struct cil_verify_map_args *map_args = args;
struct cil_perm *cmp = (struct cil_perm *)d;
+ if (cmp->classperms == NULL) {
+ cil_log(CIL_ERR, "Map class %s does not have a classmapping for %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
+ map_args->rc = SEPOL_ERR;
+ goto exit;
+ }
+
rc = __cil_verify_classperms(cmp->classperms, &cmp->datum);
if (rc != SEPOL_OK) {
cil_log(CIL_ERR, "Found circular class permissions involving the map class %s and permission %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
map_args->rc = SEPOL_ERR;
+ goto exit;
}
+exit:
return SEPOL_OK;
}
diff --git a/libsepol/include/sepol/policydb/avtab.h b/libsepol/include/sepol/policydb/avtab.h
index 2ea821c3..d3ea84e6 100644
--- a/libsepol/include/sepol/policydb/avtab.h
+++ b/libsepol/include/sepol/policydb/avtab.h
@@ -59,28 +59,29 @@ typedef struct avtab_key {
#define AVTAB_MEMBER 0x0020
#define AVTAB_CHANGE 0x0040
#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
-#define AVTAB_OPNUM_ALLOWED 0x0100
-#define AVTAB_OPNUM_AUDITALLOW 0x0200
-#define AVTAB_OPNUM_DONTAUDIT 0x0400
-#define AVTAB_OPNUM (AVTAB_OPNUM_ALLOWED | AVTAB_OPNUM_AUDITALLOW | AVTAB_OPNUM_DONTAUDIT)
-#define AVTAB_OPTYPE_ALLOWED 0x1000
-#define AVTAB_OPTYPE_AUDITALLOW 0x2000
-#define AVTAB_OPTYPE_DONTAUDIT 0x4000
-#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | AVTAB_OPTYPE_AUDITALLOW | AVTAB_OPTYPE_DONTAUDIT)
-#define AVTAB_OP (AVTAB_OPNUM | AVTAB_OPTYPE)
+#define AVTAB_XPERMS_ALLOWED 0x0100
+#define AVTAB_XPERMS_AUDITALLOW 0x0200
+#define AVTAB_XPERMS_DONTAUDIT 0x0400
+#define AVTAB_XPERMS_NEVERALLOW 0x0800
+#define AVTAB_XPERMS (AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | AVTAB_XPERMS_DONTAUDIT)
#define AVTAB_ENABLED_OLD 0x80000000
#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
uint16_t specified; /* what fields are specified */
} avtab_key_t;
-typedef struct avtab_operations {
- uint8_t type;
+typedef struct avtab_extended_perms {
+
+#define AVTAB_XPERMS_IOCTLFUNCTION 0x01
+#define AVTAB_XPERMS_IOCTLDRIVER 0x02
+ /* extension of the avtab_key specified */
+ uint8_t specified;
+ uint8_t driver;
uint32_t perms[8];
-} avtab_operations_t;
+} avtab_extended_perms_t;
typedef struct avtab_datum {
uint32_t data; /* access vector or type */
- avtab_operations_t *ops;
+ avtab_extended_perms_t *xperms;
} avtab_datum_t;
typedef struct avtab_node *avtab_ptr_t;
diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
index 801438cc..7b3508d1 100644
--- a/libsepol/include/sepol/policydb/ebitmap.h
+++ b/libsepol/include/sepol/policydb/ebitmap.h
@@ -86,6 +86,7 @@ extern unsigned int ebitmap_cardinality(ebitmap_t *e1);
extern int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2);
extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src);
extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2);
+extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2);
extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit);
extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value);
extern void ebitmap_destroy(ebitmap_t * e);
diff --git a/libsepol/include/sepol/policydb/hierarchy.h b/libsepol/include/sepol/policydb/hierarchy.h
index b4eb9bc2..88bc02ec 100644
--- a/libsepol/include/sepol/policydb/hierarchy.h
+++ b/libsepol/include/sepol/policydb/hierarchy.h
@@ -25,11 +25,22 @@
#ifndef _SEPOL_POLICYDB_HIERARCHY_H_
#define _SEPOL_POLICYDB_HIERARCHY_H_
+#include <sepol/policydb/avtab.h>
#include <sepol/policydb/policydb.h>
#include <sys/cdefs.h>
__BEGIN_DECLS
+extern int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p);
+
+extern void bounds_destroy_bad(avtab_ptr_t cur);
+extern int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+ uint32_t parent, avtab_ptr_t *bad, int *numbad);
+
+extern int bounds_check_users(sepol_handle_t *handle, policydb_t *p);
+extern int bounds_check_roles(sepol_handle_t *handle, policydb_t *p);
+extern int bounds_check_types(sepol_handle_t *handle, policydb_t *p);
+
extern int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p);
__END_DECLS
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 1d8310c7..26cec13f 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -241,11 +241,19 @@ typedef struct class_perm_node {
struct class_perm_node *next;
} class_perm_node_t;
-typedef struct av_operations {
- uint8_t type;
- /* 256 bits of ioctl number permissions */
- uint32_t perms[8];
-} av_operations_t;
+#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
+#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
+#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
+#define EXTENDED_PERMS_LEN 8
+
+typedef struct av_extended_perms {
+#define AVRULE_XPERMS_IOCTLFUNCTION 0x01
+#define AVRULE_XPERMS_IOCTLDRIVER 0x02
+ uint8_t specified;
+ uint8_t driver;
+ /* 256 bits of permissions */
+ uint32_t perms[EXTENDED_PERMS_LEN];
+} av_extended_perms_t;
typedef struct avrule {
/* these typedefs are almost exactly the same as those in avtab.h - they are
@@ -260,24 +268,19 @@ typedef struct avrule {
#define AVRULE_MEMBER 0x0020
#define AVRULE_CHANGE 0x0040
#define AVRULE_TYPE (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE)
-#define AVRULE_OPNUM_ALLOWED 0x0100
-#define AVRULE_OPNUM_AUDITALLOW 0x0200
-#define AVRULE_OPNUM_DONTAUDIT 0x0400
-#define AVRULE_OPNUM (AVRULE_OPNUM_ALLOWED | AVRULE_OPNUM_AUDITALLOW | \
- AVRULE_OPNUM_DONTAUDIT)
-#define AVRULE_OPTYPE_ALLOWED 0x1000
-#define AVRULE_OPTYPE_AUDITALLOW 0x2000
-#define AVRULE_OPTYPE_DONTAUDIT 0x4000
-#define AVRULE_OPTYPE (AVRULE_OPTYPE_ALLOWED | AVRULE_OPTYPE_AUDITALLOW | \
- AVRULE_OPTYPE_DONTAUDIT)
-#define AVRULE_OP (AVRULE_OPNUM | AVRULE_OPTYPE)
+#define AVRULE_XPERMS_ALLOWED 0x0100
+#define AVRULE_XPERMS_AUDITALLOW 0x0200
+#define AVRULE_XPERMS_DONTAUDIT 0x0400
+#define AVRULE_XPERMS_NEVERALLOW 0x0800
+#define AVRULE_XPERMS (AVRULE_XPERMS_ALLOWED | AVRULE_XPERMS_AUDITALLOW | \
+ AVRULE_XPERMS_DONTAUDIT | AVRULE_XPERMS_NEVERALLOW)
uint32_t specified;
#define RULE_SELF 1
uint32_t flags;
type_set_t stypes;
type_set_t ttypes;
class_perm_node_t *perms;
- av_operations_t * ops;
+ av_extended_perms_t *xperms;
unsigned long line; /* line number from policy.conf where
* this rule originated */
/* source file name and line number (e.g. .te file) */
@@ -652,7 +655,7 @@ extern void level_datum_init(level_datum_t * x);
extern void level_datum_destroy(level_datum_t * x);
extern void cat_datum_init(cat_datum_t * x);
extern void cat_datum_destroy(cat_datum_t * x);
-
+extern int check_assertion(policydb_t *p, avrule_t *avrule);
extern int check_assertions(sepol_handle_t * handle,
policydb_t * p, avrule_t * avrules);
@@ -709,11 +712,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
#define POLICYDB_VERSION_DEFAULT_TYPE 28
#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
#define POLICYDB_VERSION_XEN_DEVICETREE 30 /* Xen-specific */
-#define POLICYDB_VERSION_IOCTL_OPERATIONS 30 /* Linux-specific */
+#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */
/* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_IOCTL_OPERATIONS
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL
/* Module versions and specific changes*/
#define MOD_POLICYDB_VERSION_BASE 4
diff --git a/libsepol/include/sepol/policydb/util.h b/libsepol/include/sepol/policydb/util.h
index ef1c90d4..fa12661a 100644
--- a/libsepol/include/sepol/policydb/util.h
+++ b/libsepol/include/sepol/policydb/util.h
@@ -32,5 +32,13 @@ extern int add_i_to_a(uint32_t i, uint32_t * cnt, uint32_t ** a);
extern char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass,
sepol_access_vector_t av);
+char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms);
+
+/*
+ * The tokenize function may be used to
+ * replace sscanf
+ */
+extern int tokenize(char *line_buf, char delim, int num_args, ...);
+
__END_DECLS
#endif
diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c
index c3359686..5aec6588 100644
--- a/libsepol/src/assertion.c
+++ b/libsepol/src/assertion.c
@@ -1,8 +1,8 @@
/* Authors: Joshua Brindle <jbrindle@tresys.com>
- *
- * Assertion checker for avtab entries, taken from
+ *
+ * Assertion checker for avtab entries, taken from
* checkpolicy.c by Stephen Smalley <sds@tycho.nsa.gov>
- *
+ *
* Copyright (C) 2005 Tresys Technology, LLC
*
* This library is free software; you can redistribute it and/or
@@ -25,13 +25,20 @@
#include <sepol/policydb/expand.h>
#include <sepol/policydb/util.h>
+#include "private.h"
#include "debug.h"
-static void report_failure(sepol_handle_t *handle, policydb_t *p,
- const avrule_t * avrule,
+struct avtab_match_args {
+ sepol_handle_t *handle;
+ policydb_t *p;
+ avrule_t *avrule;
+ avtab_t *avtab;
+ unsigned long errors;
+};
+
+static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule,
unsigned int stype, unsigned int ttype,
- const class_perm_node_t *curperm,
- const avtab_ptr_t node)
+ const class_perm_node_t *curperm, uint32_t perms)
{
if (avrule->source_filename) {
ERR(handle, "neverallow on line %lu of %s (or line %lu of policy.conf) violated by allow %s %s:%s {%s };",
@@ -39,126 +46,411 @@ static void report_failure(sepol_handle_t *handle, policydb_t *p,
p->p_type_val_to_name[stype],
p->p_type_val_to_name[ttype],
p->p_class_val_to_name[curperm->tclass - 1],
- sepol_av_to_string(p, curperm->tclass,
- node->datum.data & curperm->data));
+ sepol_av_to_string(p, curperm->tclass, perms));
} else if (avrule->line) {
ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
avrule->line, p->p_type_val_to_name[stype],
p->p_type_val_to_name[ttype],
p->p_class_val_to_name[curperm->tclass - 1],
- sepol_av_to_string(p, curperm->tclass,
- node->datum.data & curperm->data));
+ sepol_av_to_string(p, curperm->tclass, perms));
} else {
ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
p->p_type_val_to_name[stype],
p->p_type_val_to_name[ttype],
p->p_class_val_to_name[curperm->tclass - 1],
- sepol_av_to_string(p, curperm->tclass,
- node->datum.data & curperm->data));
+ sepol_av_to_string(p, curperm->tclass, perms));
+ }
+}
+
+static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data)
+{
+ for (; cp; cp = cp->next) {
+ if ((cp->tclass == class) && (cp->data & data)) {
+ break;
+ }
}
+ if (!cp)
+ return 0;
+
+ return 1;
+}
+
+static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) {
+ size_t i;
+ for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
+ if (perms1[i] & perms2[i])
+ return 1;
+ }
+
+ return 0;
}
-static unsigned long check_assertion_helper(sepol_handle_t * handle,
- policydb_t * p,
- avtab_t * te_avtab, avtab_t * te_cond_avtab,
- unsigned int stype, unsigned int ttype,
- const avrule_t * avrule)
+static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow)
+{
+ int rc = 0;
+ if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+ && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+ if (neverallow->driver == allow->driver)
+ rc = extended_permissions_and(neverallow->perms, allow->perms);
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+ && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+ rc = xperm_test(neverallow->driver, allow->perms);
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+ && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+ rc = xperm_test(allow->driver, neverallow->perms);
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+ && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+ rc = extended_permissions_and(neverallow->perms, allow->perms);
+ }
+
+ return rc;
+}
+
+/* Compute which allowed extended permissions violate the neverallow rule */
+static void extended_permissions_violated(avtab_extended_perms_t *result,
+ av_extended_perms_t *neverallow,
+ avtab_extended_perms_t *allow)
+{
+ size_t i;
+ if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+ && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+ result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+ result->driver = allow->driver;
+ for (i = 0; i < EXTENDED_PERMS_LEN; i++)
+ result->perms[i] = neverallow->perms[i] & allow->perms[i];
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+ && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+ result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+ result->driver = neverallow->driver;
+ memcpy(result->perms, neverallow->perms, sizeof(result->perms));
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+ && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+ result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+ result->driver = allow->driver;
+ memcpy(result->perms, allow->perms, sizeof(result->perms));
+ } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+ && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+ result->specified = AVTAB_XPERMS_IOCTLDRIVER;
+ for (i = 0; i < EXTENDED_PERMS_LEN; i++)
+ result->perms[i] = neverallow->perms[i] & allow->perms[i];
+ }
+}
+
+/* Same scenarios of interest as check_assertion_extended_permissions */
+static int report_assertion_extended_permissions(sepol_handle_t *handle,
+ policydb_t *p, const avrule_t *avrule,
+ unsigned int stype, unsigned int ttype,
+ const class_perm_node_t *curperm, uint32_t perms,
+ avtab_key_t *k, avtab_t *avtab)
{
- avtab_key_t avkey;
avtab_ptr_t node;
- class_perm_node_t *curperm;
- unsigned long errors = 0;
+ avtab_key_t tmp_key;
+ avtab_extended_perms_t *xperms;
+ avtab_extended_perms_t error;
+ int rc = 1;
+ int ret = 0;
- for (curperm = avrule->perms; curperm != NULL; curperm = curperm->next) {
- avkey.source_type = stype + 1;
- avkey.target_type = ttype + 1;
- avkey.target_class = curperm->tclass;
- avkey.specified = AVTAB_ALLOWED;
- for (node = avtab_search_node(te_avtab, &avkey);
- node != NULL;
- node = avtab_search_node_next(node, avkey.specified)) {
- if (node->datum.data & curperm->data) {
- report_failure(handle, p, avrule, stype, ttype, curperm, node);
- errors++;
- }
- }
- for (node = avtab_search_node(te_cond_avtab, &avkey);
- node != NULL;
- node = avtab_search_node_next(node, avkey.specified)) {
- if (node->datum.data & curperm->data) {
- report_failure(handle, p, avrule, stype, ttype, curperm, node);
- errors++;
- }
+ memcpy(&tmp_key, k, sizeof(avtab_key_t));
+ tmp_key.specified = AVTAB_XPERMS_ALLOWED;
+
+ for (node = avtab_search_node(avtab, &tmp_key);
+ node;
+ node = avtab_search_node_next(node, tmp_key.specified)) {
+ xperms = node->datum.xperms;
+ if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+ && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+ continue;
+
+ rc = check_extended_permissions(avrule->xperms, xperms);
+ /* failure on the extended permission check_extended_permissionss */
+ if (rc) {
+ extended_permissions_violated(&error, avrule->xperms, xperms);
+ ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
+ "allowxperm %s %s:%s %s;",
+ avrule->source_line, avrule->source_filename, avrule->line,
+ p->p_type_val_to_name[stype],
+ p->p_type_val_to_name[ttype],
+ p->p_class_val_to_name[curperm->tclass - 1],
+ sepol_extended_perms_to_string(&error));
+
+ rc = 0;
+ ret++;
}
+
+ }
+
+ /* failure on the regular permissions */
+ if (rc) {
+ ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
+ "allow %s %s:%s {%s };",
+ avrule->source_line, avrule->source_filename, avrule->line,
+ p->p_type_val_to_name[stype],
+ p->p_type_val_to_name[ttype],
+ p->p_class_val_to_name[curperm->tclass - 1],
+ sepol_av_to_string(p, curperm->tclass, perms));
+ ret++;
+
}
- return errors;
+ return ret;
}
-int check_assertions(sepol_handle_t * handle, policydb_t * p,
- avrule_t * avrules)
+static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
{
- avrule_t *a;
- avtab_t te_avtab, te_cond_avtab;
+ int rc = 0;
+ struct avtab_match_args *a = (struct avtab_match_args *)args;
+ sepol_handle_t *handle = a->handle;
+ policydb_t *p = a->p;
+ avtab_t *avtab = a->avtab;
+ avrule_t *avrule = a->avrule;
+ class_perm_node_t *cp;
+ uint32_t perms;
+ ebitmap_t src_matches, tgt_matches, matches;
ebitmap_node_t *snode, *tnode;
unsigned int i, j;
- unsigned long errors = 0;
- if (!avrules) {
- /* Since assertions are stored in avrules, if it is NULL
- there won't be any to check. This also prevents an invalid
- free if the avtabs are never initialized */
+ if (k->specified != AVTAB_ALLOWED)
return 0;
- }
- if (avrules) {
- if (avtab_init(&te_avtab))
+ if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
+ return 0;
+
+ ebitmap_init(&src_matches);
+ ebitmap_init(&tgt_matches);
+ ebitmap_init(&matches);
+
+ rc = ebitmap_and(&src_matches, &avrule->stypes.types,
+ &p->attr_type_map[k->source_type - 1]);
+ if (rc)
+ goto oom;
+
+ if (ebitmap_length(&src_matches) == 0)
+ goto exit;
+
+ if (avrule->flags == RULE_SELF) {
+ rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1]);
+ if (rc)
goto oom;
- if (avtab_init(&te_cond_avtab)) {
- avtab_destroy(&te_avtab);
+ rc = ebitmap_and(&tgt_matches, &avrule->stypes.types, &matches);
+ if (rc)
goto oom;
- }
- if (expand_avtab(p, &p->te_avtab, &te_avtab) ||
- expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) {
- avtab_destroy(&te_avtab);
- avtab_destroy(&te_cond_avtab);
+ } else {
+ rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
+ if (rc)
goto oom;
- }
}
- for (a = avrules; a != NULL; a = a->next) {
- ebitmap_t *stypes = &a->stypes.types;
- ebitmap_t *ttypes = &a->ttypes.types;
+ if (ebitmap_length(&tgt_matches) == 0)
+ goto exit;
- if (!(a->specified & AVRULE_NEVERALLOW))
+ for (cp = avrule->perms; cp; cp = cp->next) {
+
+ perms = cp->data & d->data;
+ if ((cp->tclass != k->target_class) || !perms) {
continue;
+ }
- ebitmap_for_each_bit(stypes, snode, i) {
+ ebitmap_for_each_bit(&src_matches, snode, i) {
if (!ebitmap_node_get_bit(snode, i))
continue;
- if (a->flags & RULE_SELF) {
- errors += check_assertion_helper
- (handle, p, &te_avtab, &te_cond_avtab, i, i,
- a);
- }
- ebitmap_for_each_bit(ttypes, tnode, j) {
+ ebitmap_for_each_bit(&tgt_matches, tnode, j) {
if (!ebitmap_node_get_bit(tnode, j))
continue;
- errors += check_assertion_helper
- (handle, p, &te_avtab, &te_cond_avtab, i, j,
- a);
+
+ if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
+ a->errors += report_assertion_extended_permissions(handle,p, avrule,
+ i, j, cp, perms, k, avtab);
+ } else {
+ a->errors++;
+ report_failure(handle, p, avrule, i, j, cp, perms);
+ }
+ }
+ }
+ }
+ goto exit;
+
+oom:
+ ERR(NULL, "Out of memory - unable to check neverallows");
+
+exit:
+ ebitmap_destroy(&src_matches);
+ ebitmap_destroy(&tgt_matches);
+ ebitmap_destroy(&matches);
+ return rc;
+}
+
+int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
+{
+ int rc;
+ struct avtab_match_args args;
+
+ args.handle = handle;
+ args.p = p;
+ args.avrule = avrule;
+ args.errors = 0;
+
+ rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
+ if (rc)
+ goto oom;
+
+ rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
+ if (rc)
+ goto oom;
+
+ return args.errors;
+
+oom:
+ return rc;
+}
+
+/*
+ * If the ioctl permission is granted in check_assertion_avtab_match for the
+ * source/target/class matching the current avrule neverallow, a lookup is
+ * performed to determine if extended permissions exist for the source/target/class.
+ *
+ * Four scenarios of interest:
+ * 1. PASS - the ioctl permission is not granted for this source/target/class
+ * This case is handled in check_assertion_avtab_match
+ * 2. PASS - The ioctl permission is granted AND the extended permission
+ * is NOT granted
+ * 3. FAIL - The ioctl permission is granted AND no extended permissions
+ * exist
+ * 4. FAIL - The ioctl permission is granted AND the extended permission is
+ * granted
+ */
+static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
+ avtab_key_t *k)
+{
+ avtab_ptr_t node;
+ avtab_key_t tmp_key;
+ avtab_extended_perms_t *xperms;
+ av_extended_perms_t *neverallow_xperms = avrule->xperms;
+ int rc = 1;
+
+ memcpy(&tmp_key, k, sizeof(avtab_key_t));
+ tmp_key.specified = AVTAB_XPERMS_ALLOWED;
+
+ for (node = avtab_search_node(avtab, &tmp_key);
+ node;
+ node = avtab_search_node_next(node, tmp_key.specified)) {
+ xperms = node->datum.xperms;
+ if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+ && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+ continue;
+
+ rc = check_extended_permissions(neverallow_xperms, xperms);
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
+
+static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
+{
+ int rc;
+ struct avtab_match_args *a = (struct avtab_match_args *)args;
+ policydb_t *p = a->p;
+ avrule_t *avrule = a->avrule;
+ avtab_t *avtab = a->avtab;
+
+ if (k->specified != AVTAB_ALLOWED)
+ goto exit;
+
+ if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
+ goto exit;
+
+ rc = ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
+ if (rc == 0)
+ goto exit;
+
+ if (avrule->flags == RULE_SELF) {
+ /* If the neverallow uses SELF, then it is not enough that the
+ * neverallow's source matches the src and tgt of the rule being checked.
+ * It must match the same thing in the src and tgt, so AND the source
+ * and target together and check for a match on the result.
+ */
+ ebitmap_t match;
+ rc = ebitmap_and(&match, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1] );
+ if (rc) {
+ ebitmap_destroy(&match);
+ goto oom;
+ }
+ rc = ebitmap_match_any(&avrule->stypes.types, &match);
+ ebitmap_destroy(&match);
+ } else {
+ rc = ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
+ }
+ if (rc == 0)
+ goto exit;
+
+ if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
+ rc = check_assertion_extended_permissions(avrule, avtab, k);
+ if (rc == 0)
+ goto exit;
+ }
+ return 1;
+
+exit:
+ return 0;
+
+oom:
+ ERR(NULL, "Out of memory - unable to check neverallows");
+ return rc;
+}
+
+int check_assertion(policydb_t *p, avrule_t *avrule)
+{
+ int rc;
+ struct avtab_match_args args;
+
+ args.handle = NULL;
+ args.p = p;
+ args.avrule = avrule;
+ args.errors = 0;
+ args.avtab = &p->te_avtab;
+
+ rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
+
+ if (rc == 0) {
+ args.avtab = &p->te_cond_avtab;
+ rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
+ }
+
+ return rc;
+}
+
+int check_assertions(sepol_handle_t * handle, policydb_t * p,
+ avrule_t * avrules)
+{
+ int rc;
+ avrule_t *a;
+ unsigned long errors = 0;
+
+ if (!avrules) {
+ /* Since assertions are stored in avrules, if it is NULL
+ there won't be any to check. This also prevents an invalid
+ free if the avtabs are never initialized */
+ return 0;
+ }
+
+ for (a = avrules; a != NULL; a = a->next) {
+ if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
+ continue;
+ rc = check_assertion(p, a);
+ if (rc) {
+ rc = report_assertion_failures(handle, p, a);
+ if (rc < 0) {
+ ERR(handle, "Error occurred while checking neverallows");
+ return -1;
}
+ errors += rc;
}
}
if (errors)
ERR(handle, "%lu neverallow failures occurred", errors);
- avtab_destroy(&te_avtab);
- avtab_destroy(&te_cond_avtab);
return errors ? -1 : 0;
-
- oom:
- ERR(handle, "Out of memory - unable to check neverallows");
- return -1;
}
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
index d3745feb..c32fda16 100644
--- a/libsepol/src/avtab.c
+++ b/libsepol/src/avtab.c
@@ -93,7 +93,7 @@ avtab_insert_node(avtab_t * h, int hvalue, avtab_ptr_t prev, avtab_key_t * key,
avtab_datum_t * datum)
{
avtab_ptr_t newnode;
- avtab_operations_t *ops;
+ avtab_extended_perms_t *xperms;
newnode = (avtab_ptr_t) malloc(sizeof(struct avtab_node));
if (newnode == NULL)
@@ -101,16 +101,16 @@ avtab_insert_node(avtab_t * h, int hvalue, avtab_ptr_t prev, avtab_key_t * key,
memset(newnode, 0, sizeof(struct avtab_node));
newnode->key = *key;
- if (key->specified & AVTAB_OP) {
- ops = calloc(1, sizeof(avtab_operations_t));
- if (ops == NULL) {
+ if (key->specified & AVTAB_XPERMS) {
+ xperms = calloc(1, sizeof(avtab_extended_perms_t));
+ if (xperms == NULL) {
free(newnode);
return NULL;
}
- if (datum->ops) /* else caller populates ops*/
- *ops = *(datum->ops);
+ if (datum->xperms) /* else caller populates xperms */
+ *xperms = *(datum->xperms);
- newnode->datum.ops = ops;
+ newnode->datum.xperms = xperms;
} else {
newnode->datum = *datum;
}
@@ -144,7 +144,8 @@ int avtab_insert(avtab_t * h, avtab_key_t * key, avtab_datum_t * datum)
key->target_type == cur->key.target_type &&
key->target_class == cur->key.target_class &&
(specified & cur->key.specified)) {
- if (specified & AVTAB_OPNUM)
+ /* Extended permissions are not necessarily unique */
+ if (specified & AVTAB_XPERMS)
break;
return SEPOL_EEXIST;
}
@@ -308,6 +309,9 @@ void avtab_destroy(avtab_t * h)
for (i = 0; i < h->nslot; i++) {
cur = h->htable[i];
while (cur != NULL) {
+ if (cur->key.specified & AVTAB_XPERMS) {
+ free(cur->datum.xperms);
+ }
temp = cur;
cur = cur->next;
free(temp);
@@ -416,12 +420,9 @@ static uint16_t spec_order[] = {
AVTAB_TRANSITION,
AVTAB_CHANGE,
AVTAB_MEMBER,
- AVTAB_OPNUM_ALLOWED,
- AVTAB_OPNUM_AUDITALLOW,
- AVTAB_OPNUM_DONTAUDIT,
- AVTAB_OPTYPE_ALLOWED,
- AVTAB_OPTYPE_AUDITALLOW,
- AVTAB_OPTYPE_DONTAUDIT
+ AVTAB_XPERMS_ALLOWED,
+ AVTAB_XPERMS_AUDITALLOW,
+ AVTAB_XPERMS_DONTAUDIT
};
int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
@@ -433,14 +434,14 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
uint32_t buf32[8], items, items2, val;
avtab_key_t key;
avtab_datum_t datum;
- avtab_operations_t ops;
+ avtab_extended_perms_t xperms;
unsigned set;
unsigned int i;
int rc;
memset(&key, 0, sizeof(avtab_key_t));
memset(&datum, 0, sizeof(avtab_datum_t));
- memset(&ops, 0, sizeof(avtab_operations_t));
+ memset(&xperms, 0, sizeof(avtab_extended_perms_t));
if (vers < POLICYDB_VERSION_AVTAB) {
rc = next_entry(buf32, fp, sizeof(uint32_t));
@@ -533,26 +534,32 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
return -1;
}
- if ((vers < POLICYDB_VERSION_IOCTL_OPERATIONS) &&
- (key.specified & AVTAB_OP)) {
- ERR(fp->handle, "policy version %u does not support ioctl "
- "operation rules and one was specified\n", vers);
+ if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) &&
+ (key.specified & AVTAB_XPERMS)) {
+ ERR(fp->handle, "policy version %u does not support extended "
+ "permissions rules and one was specified\n", vers);
return -1;
- } else if (key.specified & AVTAB_OP) {
+ } else if (key.specified & AVTAB_XPERMS) {
+ rc = next_entry(&buf8, fp, sizeof(uint8_t));
+ if (rc < 0) {
+ ERR(fp->handle, "truncated entry");
+ return -1;
+ }
+ xperms.specified = buf8;
rc = next_entry(&buf8, fp, sizeof(uint8_t));
if (rc < 0) {
ERR(fp->handle, "truncated entry");
return -1;
}
- ops.type = buf8;
+ xperms.driver = buf8;
rc = next_entry(buf32, fp, sizeof(uint32_t)*8);
if (rc < 0) {
ERR(fp->handle, "truncated entry");
return -1;
}
- for (i = 0; i < ARRAY_SIZE(ops.perms); i++)
- ops.perms[i] = le32_to_cpu(buf32[i]);
- datum.ops = &ops;
+ for (i = 0; i < ARRAY_SIZE(xperms.perms); i++)
+ xperms.perms[i] = le32_to_cpu(buf32[i]);
+ datum.xperms = &xperms;
} else {
rc = next_entry(buf32, fp, sizeof(uint32_t));
if (rc < 0) {
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
index be6b5911..58f2fc4f 100644
--- a/libsepol/src/ebitmap.c
+++ b/libsepol/src/ebitmap.c
@@ -224,6 +224,28 @@ int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2)
return 1;
}
+int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2)
+{
+ ebitmap_node_t *n1 = e1->node;
+ ebitmap_node_t *n2 = e2->node;
+
+ while (n1 && n2) {
+ if (n1->startbit < n2->startbit) {
+ n1 = n1->next;
+ } else if (n2->startbit < n1->startbit) {
+ n2 = n2->next;
+ } else {
+ if (n1->map & n2->map) {
+ return 1;
+ }
+ n1 = n1->next;
+ n2 = n2->next;
+ }
+ }
+
+ return 0;
+}
+
int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit)
{
ebitmap_node_t *n;
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index b999890f..9047c6da 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -1604,24 +1604,25 @@ static int expand_range_trans(expand_state_t * state,
static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
avtab_t * avtab, avtab_key_t * key,
cond_av_list_t ** cond,
- av_operations_t *operations)
+ av_extended_perms_t *xperms)
{
avtab_ptr_t node;
avtab_datum_t avdatum;
cond_av_list_t *nl;
- int type_match = 0;
+ int match = 0;
- /* AVTAB_OPNUM entries are not necessarily unique */
- if (key->specified & AVTAB_OPNUM) {
+ /* AVTAB_XPERMS entries are not necessarily unique */
+ if (key->specified & AVTAB_XPERMS) {
node = avtab_search_node(avtab, key);
while (node) {
- if (node->datum.ops->type == operations->type) {
- type_match = 1;
+ if ((node->datum.xperms->specified == xperms->specified) &&
+ (node->datum.xperms->driver == xperms->driver)) {
+ match = 1;
break;
}
node = avtab_search_node_next(node, key->specified);
}
- if (!type_match)
+ if (!match)
node = NULL;
} else {
node = avtab_search_node(avtab, key);
@@ -1780,11 +1781,11 @@ static int expand_avrule_helper(sepol_handle_t * handle,
cond_av_list_t ** cond,
uint32_t stype, uint32_t ttype,
class_perm_node_t * perms, avtab_t * avtab,
- int enabled, av_operations_t *operations)
+ int enabled, av_extended_perms_t *extended_perms)
{
avtab_key_t avkey;
avtab_datum_t *avdatump;
- avtab_operations_t *ops;
+ avtab_extended_perms_t *xperms;
avtab_ptr_t node;
class_perm_node_t *cur;
uint32_t spec = 0;
@@ -1802,22 +1803,14 @@ static int expand_avrule_helper(sepol_handle_t * handle,
spec = AVTAB_AUDITDENY;
} else if (specified & AVRULE_NEVERALLOW) {
spec = AVTAB_NEVERALLOW;
- } else if (specified & AVRULE_OPNUM_ALLOWED) {
- spec = AVTAB_OPNUM_ALLOWED;
- } else if (specified & AVRULE_OPNUM_AUDITALLOW) {
- spec = AVTAB_OPNUM_AUDITALLOW;
- } else if (specified & AVRULE_OPNUM_DONTAUDIT) {
+ } else if (specified & AVRULE_XPERMS_ALLOWED) {
+ spec = AVTAB_XPERMS_ALLOWED;
+ } else if (specified & AVRULE_XPERMS_AUDITALLOW) {
+ spec = AVTAB_XPERMS_AUDITALLOW;
+ } else if (specified & AVRULE_XPERMS_DONTAUDIT) {
if (handle && handle->disable_dontaudit)
return EXPAND_RULE_SUCCESS;
- spec = AVTAB_OPNUM_DONTAUDIT;
- } else if (specified & AVRULE_OPTYPE_ALLOWED) {
- spec = AVTAB_OPTYPE_ALLOWED;
- } else if (specified & AVRULE_OPTYPE_AUDITALLOW) {
- spec = AVTAB_OPTYPE_AUDITALLOW;
- } else if (specified & AVRULE_OPTYPE_DONTAUDIT) {
- if (handle && handle->disable_dontaudit)
- return EXPAND_RULE_SUCCESS;
- spec = AVTAB_OPTYPE_DONTAUDIT;
+ spec = AVTAB_XPERMS_DONTAUDIT;
} else {
assert(0); /* unreachable */
}
@@ -1829,7 +1822,7 @@ static int expand_avrule_helper(sepol_handle_t * handle,
avkey.target_class = cur->tclass;
avkey.specified = spec;
- node = find_avtab_node(handle, avtab, &avkey, cond, operations);
+ node = find_avtab_node(handle, avtab, &avkey, cond, extended_perms);
if (!node)
return EXPAND_RULE_ERROR;
if (enabled) {
@@ -1859,20 +1852,21 @@ static int expand_avrule_helper(sepol_handle_t * handle,
avdatump->data &= ~cur->data;
else
avdatump->data = ~cur->data;
- } else if (specified & AVRULE_OP) {
- if (!avdatump->ops) {
- ops = (avtab_operations_t *)
- calloc(1, sizeof(avtab_operations_t));
- if (!ops) {
+ } else if (specified & AVRULE_XPERMS) {
+ if (!avdatump->xperms) {
+ xperms = (avtab_extended_perms_t *)
+ calloc(1, sizeof(avtab_extended_perms_t));
+ if (!xperms) {
ERR(handle, "Out of memory!");
return -1;
}
- node->datum.ops = ops;
- }
- node->datum.ops->type = operations->type;
- for (i = 0; i < ARRAY_SIZE(operations->perms); i++) {
- node->datum.ops->perms[i] |= operations->perms[i];
+ node->datum.xperms = xperms;
}
+ node->datum.xperms->specified = extended_perms->specified;
+ node->datum.xperms->driver = extended_perms->driver;
+
+ for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
+ node->datum.xperms->perms[i] |= extended_perms->perms[i];
} else {
assert(0); /* should never occur */
}
@@ -1897,10 +1891,10 @@ static int expand_rule_helper(sepol_handle_t * handle,
if (!ebitmap_node_get_bit(snode, i))
continue;
if (source_rule->flags & RULE_SELF) {
- if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) {
+ if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
retval = expand_avrule_helper(handle, source_rule->specified,
cond, i, i, source_rule->perms,
- dest_avtab, enabled, source_rule->ops);
+ dest_avtab, enabled, source_rule->xperms);
if (retval != EXPAND_RULE_SUCCESS)
return retval;
} else {
@@ -1915,10 +1909,10 @@ static int expand_rule_helper(sepol_handle_t * handle,
ebitmap_for_each_bit(ttypes, tnode, j) {
if (!ebitmap_node_get_bit(tnode, j))
continue;
- if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) {
+ if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
retval = expand_avrule_helper(handle, source_rule->specified,
cond, i, j, source_rule->perms,
- dest_avtab, enabled, source_rule->ops);
+ dest_avtab, enabled, source_rule->xperms);
if (retval != EXPAND_RULE_SUCCESS)
return retval;
} else {
@@ -1954,6 +1948,8 @@ static int convert_and_expand_rule(sepol_handle_t * handle,
if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW)
return EXPAND_RULE_SUCCESS;
+ if (source_rule->specified & AVRULE_XPERMS_NEVERALLOW)
+ return EXPAND_RULE_SUCCESS;
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
@@ -2317,25 +2313,33 @@ static int type_attr_map(hashtab_key_t key
policydb_t *p = state->out;
unsigned int i;
ebitmap_node_t *tnode;
+ int value;
type = (type_datum_t *) datum;
+ value = type->s.value;
+
if (type->flavor == TYPE_ATTRIB) {
- if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1],
- &type->types)) {
- ERR(state->handle, "Out of memory!");
- return -1;
+ if (ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) {
+ goto oom;
}
ebitmap_for_each_bit(&type->types, tnode, i) {
if (!ebitmap_node_get_bit(tnode, i))
continue;
- if (ebitmap_set_bit(&p->type_attr_map[i],
- type->s.value - 1, 1)) {
- ERR(state->handle, "Out of memory!");
- return -1;
+ if (ebitmap_set_bit(&p->type_attr_map[i], value - 1, 1)) {
+ goto oom;
}
}
+ } else {
+ if (ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) {
+ goto oom;
+ }
}
+
return 0;
+
+oom:
+ ERR(state->handle, "Out of memory!");
+ return -1;
}
/* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy.
@@ -2376,7 +2380,8 @@ int expand_rule(sepol_handle_t * handle,
int retval;
ebitmap_t stypes, ttypes;
- if (source_rule->specified & AVRULE_NEVERALLOW)
+ if ((source_rule->specified & AVRULE_NEVERALLOW)
+ || (source_rule->specified & AVRULE_XPERMS_NEVERALLOW))
return 1;
ebitmap_init(&stypes);
@@ -2590,6 +2595,7 @@ static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
ebitmap_t stypes, ttypes;
avrule_t *avrule;
class_perm_node_t *cur_perm, *new_perm, *tail_perm;
+ av_extended_perms_t *xperms = NULL;
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
@@ -2606,7 +2612,7 @@ static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
return -1;
avrule_init(avrule);
- avrule->specified = AVRULE_NEVERALLOW;
+ avrule->specified = source_rule->specified;
avrule->line = source_rule->line;
avrule->flags = source_rule->flags;
avrule->source_line = source_rule->source_line;
@@ -2645,6 +2651,15 @@ static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
cur_perm = cur_perm->next;
}
+ /* copy over extended permissions */
+ if (source_rule->xperms) {
+ xperms = calloc(1, sizeof(av_extended_perms_t));
+ if (!xperms)
+ goto err;
+ memcpy(xperms, source_rule->xperms, sizeof(av_extended_perms_t));
+ avrule->xperms = xperms;
+ }
+
/* just prepend the avrule to the first branch; it'll never be
written to disk */
if (!dest_pol->global->branch_list->avrules)
@@ -2670,6 +2685,7 @@ static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap,
free(cur_perm);
cur_perm = tail_perm;
}
+ free(xperms);
free(avrule);
return -1;
}
@@ -2722,16 +2738,15 @@ static int copy_and_expand_avrule_block(expand_state_t * state)
cur_avrule = decl->avrules;
while (cur_avrule != NULL) {
if (!(state->expand_neverallow)
- && cur_avrule->specified & AVRULE_NEVERALLOW) {
+ && cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)) {
/* copy this over directly so that assertions are checked later */
if (copy_neverallow
(state->out, state->typemap, cur_avrule))
ERR(state->handle,
"Error while copying neverallow.");
} else {
- if (cur_avrule->specified & AVRULE_NEVERALLOW) {
+ if (cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW))
state->out->unsupported_format = 1;
- }
if (convert_and_expand_rule
(state->handle, state->out, state->typemap,
cur_avrule, &state->out->te_avtab, NULL,
@@ -3155,24 +3170,25 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
{
avtab_ptr_t node;
avtab_datum_t *avd;
- avtab_operations_t *ops;
+ avtab_extended_perms_t *xperms;
unsigned int i;
- unsigned int type_match = 0;
+ unsigned int match = 0;
- if (k->specified & AVTAB_OPNUM) {
+ if (k->specified & AVTAB_XPERMS) {
/*
- * AVTAB_OPNUM entries are not necessarily unique.
- * find node with matching ops->type
+ * AVTAB_XPERMS entries are not necessarily unique.
+ * find node with matching xperms
*/
node = avtab_search_node(a, k);
while (node) {
- if (node->datum.ops->type == d->ops->type) {
- type_match = 1;
+ if ((node->datum.xperms->specified == d->xperms->specified) &&
+ (node->datum.xperms->driver == d->xperms->driver)) {
+ match = 1;
break;
}
node = avtab_search_node_next(node, k->specified);
}
- if (!type_match)
+ if (!match)
node = NULL;
} else {
node = avtab_search_node(a, k);
@@ -3189,7 +3205,7 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
}
avd = &node->datum;
- ops = node->datum.ops;
+ xperms = node->datum.xperms;
switch (k->specified & ~AVTAB_ENABLED) {
case AVTAB_ALLOWED:
case AVTAB_AUDITALLOW:
@@ -3198,14 +3214,11 @@ static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d)
case AVTAB_AUDITDENY:
avd->data &= d->data;
break;
- case AVTAB_OPNUM_ALLOWED:
- case AVTAB_OPNUM_AUDITALLOW:
- case AVTAB_OPNUM_DONTAUDIT:
- case AVTAB_OPTYPE_ALLOWED:
- case AVTAB_OPTYPE_AUDITALLOW:
- case AVTAB_OPTYPE_DONTAUDIT:
- for (i = 0; i < ARRAY_SIZE(ops->perms); i++)
- ops->perms[i] |= d->ops->perms[i];
+ case AVTAB_XPERMS_ALLOWED:
+ case AVTAB_XPERMS_AUDITALLOW:
+ case AVTAB_XPERMS_DONTAUDIT:
+ for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
+ xperms->perms[i] |= d->xperms->perms[i];
break;
default:
ERR(NULL, "Type conflict!");
diff --git a/libsepol/src/hierarchy.c b/libsepol/src/hierarchy.c
index d787a64b..f6c5fae9 100644
--- a/libsepol/src/hierarchy.c
+++ b/libsepol/src/hierarchy.c
@@ -37,466 +37,702 @@
#include "debug.h"
-typedef struct hierarchy_args {
- policydb_t *p;
- avtab_t *expa; /* expanded avtab */
- /* This tells check_avtab_hierarchy to check this list in addition to the unconditional avtab */
- cond_av_list_t *opt_cond_list;
- sepol_handle_t *handle;
- int numerr;
-} hierarchy_args_t;
+#define BOUNDS_AVTAB_SIZE 1024
-/*
- * find_parent_(type|role|user)
- *
- * This function returns the parent datum of given XXX_datum_t
- * object or NULL, if it doesn't exist.
- *
- * If the given datum has a valid bounds, this function merely
- * returns the indicated object. Otherwise, it looks up the
- * parent based on the based hierarchy.
- */
-#define find_parent_template(prefix) \
-int find_parent_##prefix(hierarchy_args_t *a, \
- prefix##_datum_t *datum, \
- prefix##_datum_t **parent) \
-{ \
- char *parent_name, *datum_name, *tmp; \
- \
- if (datum->bounds) \
- *parent = a->p->prefix##_val_to_struct[datum->bounds - 1]; \
- else { \
- datum_name = a->p->p_##prefix##_val_to_name[datum->s.value - 1]; \
- \
- tmp = strrchr(datum_name, '.'); \
- /* no '.' means it has no parent */ \
- if (!tmp) { \
- *parent = NULL; \
- return 0; \
- } \
- \
- parent_name = strdup(datum_name); \
- if (!parent_name) \
- return -1; \
- parent_name[tmp - datum_name] = '\0'; \
- \
- *parent = hashtab_search(a->p->p_##prefix##s.table, parent_name); \
- if (!*parent) { \
- /* Orphan type/role/user */ \
- ERR(a->handle, \
- "%s doesn't exist, %s is an orphan", \
- parent_name, \
- a->p->p_##prefix##_val_to_name[datum->s.value - 1]); \
- free(parent_name); \
- return -1; \
- } \
- free(parent_name); \
- } \
- \
- return 0; \
+static int bounds_insert_helper(sepol_handle_t *handle, avtab_t *avtab,
+ avtab_key_t *avtab_key, avtab_datum_t *datum)
+{
+ int rc = avtab_insert(avtab, avtab_key, datum);
+ if (rc) {
+ if (rc == SEPOL_ENOMEM)
+ ERR(handle, "Insufficient memory");
+ else
+ ERR(handle, "Unexpected error (%d)", rc);
+ }
+ return rc;
}
-static find_parent_template(type)
-static find_parent_template(role)
-static find_parent_template(user)
-static void compute_avtab_datum(hierarchy_args_t *args,
- avtab_key_t *key,
- avtab_datum_t *result)
+static int bounds_insert_rule(sepol_handle_t *handle, avtab_t *avtab,
+ avtab_t *global, avtab_t *other,
+ avtab_key_t *avtab_key, avtab_datum_t *datum)
{
- avtab_datum_t *avdatp;
- uint32_t av = 0;
-
- avdatp = avtab_search(args->expa, key);
- if (avdatp)
- av = avdatp->data;
- if (args->opt_cond_list) {
- avdatp = cond_av_list_search(key, args->opt_cond_list);
- if (avdatp)
- av |= avdatp->data;
+ int rc = 0;
+ avtab_datum_t *dup = avtab_search(avtab, avtab_key);
+
+ if (!dup) {
+ rc = bounds_insert_helper(handle, avtab, avtab_key, datum);
+ if (rc) goto exit;
+ } else {
+ dup->data |= datum->data;
}
- result->data = av;
+ if (other) {
+ /* Search the other conditional avtab for the key and
+ * add any common permissions to the global avtab
+ */
+ uint32_t data = 0;
+ dup = avtab_search(other, avtab_key);
+ if (dup) {
+ data = dup->data & datum->data;
+ if (data) {
+ dup = avtab_search(global, avtab_key);
+ if (!dup) {
+ avtab_datum_t d;
+ d.data = data;
+ rc = bounds_insert_helper(handle, global,
+ avtab_key, &d);
+ if (rc) goto exit;
+ } else {
+ dup->data |= data;
+ }
+ }
+ }
+ }
+
+exit:
+ return rc;
}
-/* This function verifies that the type passed in either has a parent or is in the
- * root of the namespace, 0 on success, 1 on orphan and -1 on error
- */
-static int check_type_hierarchy_callback(hashtab_key_t k, hashtab_datum_t d,
- void *args)
+static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p,
+ avtab_t *avtab, avtab_t *global, avtab_t *other,
+ uint32_t parent, uint32_t src, uint32_t tgt,
+ uint32_t class, uint32_t data)
{
- hierarchy_args_t *a;
- type_datum_t *t, *tp;
-
- a = (hierarchy_args_t *) args;
- t = (type_datum_t *) d;
+ int rc = 0;
+ avtab_key_t avtab_key;
+ avtab_datum_t datum;
+ ebitmap_node_t *tnode;
+ unsigned int i;
+
+ avtab_key.specified = AVTAB_ALLOWED;
+ avtab_key.target_class = class;
+ datum.data = data;
+
+ if (ebitmap_get_bit(&p->attr_type_map[src - 1], parent - 1)) {
+ avtab_key.source_type = parent;
+ ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
+ if (!ebitmap_node_get_bit(tnode, i))
+ continue;
+ avtab_key.target_type = i + 1;
+ rc = bounds_insert_rule(handle, avtab, global, other,
+ &avtab_key, &datum);
+ if (rc) goto exit;
+ }
+ }
- if (t->flavor == TYPE_ATTRIB) {
- /* It's an attribute, we don't care */
- return 0;
+ if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], parent - 1)) {
+ avtab_key.target_type = parent;
+ ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
+ if (!ebitmap_node_get_bit(tnode, i))
+ continue;
+ avtab_key.source_type = i + 1;
+ rc = bounds_insert_rule(handle, avtab, global, other,
+ &avtab_key, &datum);
+ if (rc) goto exit;
+ }
}
- if (find_parent_type(a, t, &tp) < 0)
- return -1;
-
- if (tp && tp->flavor == TYPE_ATTRIB) {
- /* The parent is an attribute but the child isn't, not legal */
- ERR(a->handle, "type %s is a child of an attribute %s",
- (char *) k, a->p->p_type_val_to_name[tp->s.value - 1]);
- a->numerr++;
- return -1;
+
+exit:
+ return rc;
+}
+
+static int bounds_expand_cond_rules(sepol_handle_t *handle, policydb_t *p,
+ cond_av_list_t *cur, avtab_t *avtab,
+ avtab_t *global, avtab_t *other,
+ uint32_t parent)
+{
+ int rc = 0;
+
+ for (; cur; cur = cur->next) {
+ avtab_ptr_t n = cur->node;
+ rc = bounds_expand_rule(handle, p, avtab, global, other, parent,
+ n->key.source_type, n->key.target_type,
+ n->key.target_class, n->datum.data);
+ if (rc) goto exit;
}
- return 0;
+
+exit:
+ return rc;
}
-/* This function only verifies that the avtab node passed in does not violate any
- * hiearchy constraint via any relationship with other types in the avtab.
- * it should be called using avtab_map, returns 0 on success, 1 on violation and
- * -1 on error. opt_cond_list is an optional argument that tells this to check
- * a conditional list for the relationship as well as the unconditional avtab
- */
-static int check_avtab_hierarchy_callback(avtab_key_t * k, avtab_datum_t * d,
- void *args)
+struct bounds_expand_args {
+ sepol_handle_t *handle;
+ policydb_t *p;
+ avtab_t *avtab;
+ uint32_t parent;
+};
+
+static int bounds_expand_rule_callback(avtab_key_t *k, avtab_datum_t *d,
+ void *args)
{
- avtab_key_t key;
- hierarchy_args_t *a = (hierarchy_args_t *) args;
- type_datum_t *s, *t1 = NULL, *t2 = NULL;
- avtab_datum_t av;
+ struct bounds_expand_args *a = (struct bounds_expand_args *)args;
- if (!(k->specified & AVTAB_ALLOWED)) {
- /* This is not an allow rule, no checking done */
+ if (!(k->specified & AVTAB_ALLOWED))
return 0;
- }
- /* search for parent first */
- s = a->p->type_val_to_struct[k->source_type - 1];
- if (find_parent_type(a, s, &t1) < 0)
- return -1;
- if (t1) {
- /*
- * search for access allowed between type 1's
- * parent and type 2.
- */
- key.source_type = t1->s.value;
- key.target_type = k->target_type;
- key.target_class = k->target_class;
- key.specified = AVTAB_ALLOWED;
- compute_avtab_datum(a, &key, &av);
-
- if ((av.data & d->data) == d->data)
- return 0;
+ return bounds_expand_rule(a->handle, a->p, a->avtab, NULL, NULL,
+ a->parent, k->source_type, k->target_type,
+ k->target_class, d->data);
+}
+
+struct bounds_cond_info {
+ avtab_t true_avtab;
+ avtab_t false_avtab;
+ cond_list_t *cond_list;
+ struct bounds_cond_info *next;
+};
+
+static void bounds_destroy_cond_info(struct bounds_cond_info *cur)
+{
+ struct bounds_cond_info *next;
+
+ for (; cur; cur = next) {
+ next = cur->next;
+ avtab_destroy(&cur->true_avtab);
+ avtab_destroy(&cur->false_avtab);
+ cur->next = NULL;
+ free(cur);
}
+}
- /* next we try type 1 and type 2's parent */
- s = a->p->type_val_to_struct[k->target_type - 1];
- if (find_parent_type(a, s, &t2) < 0)
- return -1;
- if (t2) {
- /*
- * search for access allowed between type 1 and
- * type 2's parent.
- */
- key.source_type = k->source_type;
- key.target_type = t2->s.value;
- key.target_class = k->target_class;
- key.specified = AVTAB_ALLOWED;
- compute_avtab_datum(a, &key, &av);
-
- if ((av.data & d->data) == d->data)
- return 0;
+static int bounds_expand_parent_rules(sepol_handle_t *handle, policydb_t *p,
+ avtab_t *global_avtab,
+ struct bounds_cond_info **cond_info,
+ uint32_t parent)
+{
+ int rc = 0;
+ struct bounds_expand_args args;
+ cond_list_t *cur;
+
+ avtab_init(global_avtab);
+ rc = avtab_alloc(global_avtab, BOUNDS_AVTAB_SIZE);
+ if (rc) goto oom;
+
+ args.handle = handle;
+ args.p = p;
+ args.avtab = global_avtab;
+ args.parent = parent;
+ rc = avtab_map(&p->te_avtab, bounds_expand_rule_callback, &args);
+ if (rc) goto exit;
+
+ *cond_info = NULL;
+ for (cur = p->cond_list; cur; cur = cur->next) {
+ struct bounds_cond_info *ci;
+ ci = malloc(sizeof(struct bounds_cond_info));
+ if (!ci) goto oom;
+ avtab_init(&ci->true_avtab);
+ avtab_init(&ci->false_avtab);
+ ci->cond_list = cur;
+ ci->next = *cond_info;
+ *cond_info = ci;
+ if (cur->true_list) {
+ rc = avtab_alloc(&ci->true_avtab, BOUNDS_AVTAB_SIZE);
+ if (rc) goto oom;
+ rc = bounds_expand_cond_rules(handle, p, cur->true_list,
+ &ci->true_avtab, NULL,
+ NULL, parent);
+ if (rc) goto exit;
+ }
+ if (cur->false_list) {
+ rc = avtab_alloc(&ci->false_avtab, BOUNDS_AVTAB_SIZE);
+ if (rc) goto oom;
+ rc = bounds_expand_cond_rules(handle, p, cur->false_list,
+ &ci->false_avtab,
+ global_avtab,
+ &ci->true_avtab, parent);
+ if (rc) goto exit;
+ }
}
- if (t1 && t2) {
- /*
- * search for access allowed between type 1's parent
- * and type 2's parent.
- */
- key.source_type = t1->s.value;
- key.target_type = t2->s.value;
- key.target_class = k->target_class;
- key.specified = AVTAB_ALLOWED;
- compute_avtab_datum(a, &key, &av);
-
- if ((av.data & d->data) == d->data)
- return 0;
+ return 0;
+
+oom:
+ ERR(handle, "Insufficient memory");
+
+exit:
+ ERR(handle,"Failed to expand parent rules\n");
+ avtab_destroy(global_avtab);
+ bounds_destroy_cond_info(*cond_info);
+ *cond_info = NULL;
+ return rc;
+}
+
+static int bounds_not_covered(avtab_t *global_avtab, avtab_t *cur_avtab,
+ avtab_key_t *avtab_key, uint32_t data)
+{
+ avtab_datum_t *datum = avtab_search(cur_avtab, avtab_key);
+ if (datum)
+ data &= ~datum->data;
+ if (global_avtab && data) {
+ datum = avtab_search(global_avtab, avtab_key);
+ if (datum)
+ data &= ~datum->data;
}
- /*
- * Neither one of these types have parents and
- * therefore the hierarchical constraint does not apply
- */
- if (!t1 && !t2)
- return 0;
+ return data;
+}
+
+static int bounds_add_bad(sepol_handle_t *handle, uint32_t src, uint32_t tgt,
+ uint32_t class, uint32_t data, avtab_ptr_t *bad)
+{
+ struct avtab_node *new = malloc(sizeof(struct avtab_node));
+ if (new == NULL) {
+ ERR(handle, "Insufficient memory");
+ return SEPOL_ENOMEM;
+ }
+ memset(new, 0, sizeof(struct avtab_node));
+ new->key.source_type = src;
+ new->key.target_type = tgt;
+ new->key.target_class = class;
+ new->datum.data = data;
+ new->next = *bad;
+ *bad = new;
- /*
- * At this point there is a violation of the hierarchal
- * constraint, send error condition back
- */
- ERR(a->handle,
- "hierarchy violation between types %s and %s : %s { %s }",
- a->p->p_type_val_to_name[k->source_type - 1],
- a->p->p_type_val_to_name[k->target_type - 1],
- a->p->p_class_val_to_name[k->target_class - 1],
- sepol_av_to_string(a->p, k->target_class, d->data & ~av.data));
- a->numerr++;
return 0;
}
-/*
- * If same permissions are allowed for same combination of
- * source and target, we can evaluate them as unconditional
- * one.
- * See the following example. A_t type is bounds of B_t type,
- * so B_t can never have wider permissions then A_t.
- * A_t has conditional permission on X_t, however, a part of
- * them (getattr and read) are unconditionaly allowed to A_t.
- *
- * Example)
- * typebounds A_t B_t;
- *
- * allow B_t X_t : file { getattr };
- * if (foo_bool) {
- * allow A_t X_t : file { getattr read };
- * } else {
- * allow A_t X_t : file { getattr read write };
- * }
- *
- * We have to pull up them as unconditional ones in this case,
- * because it seems to us B_t is violated to bounds constraints
- * during unconditional policy checking.
- */
-static int pullup_unconditional_perms(cond_list_t * cond_list,
- hierarchy_args_t * args)
+static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p,
+ avtab_t *global_avtab, avtab_t *cur_avtab,
+ uint32_t child, uint32_t parent, uint32_t src,
+ uint32_t tgt, uint32_t class, uint32_t data,
+ avtab_ptr_t *bad, int *numbad)
{
- cond_list_t *cur_node;
- cond_av_list_t *cur_av, *expl_true = NULL, *expl_false = NULL;
- avtab_t expa_true, expa_false;
- avtab_datum_t *avdatp;
- avtab_datum_t avdat;
- avtab_ptr_t avnode;
-
- for (cur_node = cond_list; cur_node; cur_node = cur_node->next) {
- if (avtab_init(&expa_true))
- goto oom0;
- if (avtab_init(&expa_false))
- goto oom1;
- if (expand_cond_av_list(args->p, cur_node->true_list,
- &expl_true, &expa_true))
- goto oom2;
- if (expand_cond_av_list(args->p, cur_node->false_list,
- &expl_false, &expa_false))
- goto oom3;
- for (cur_av = expl_true; cur_av; cur_av = cur_av->next) {
- avdatp = avtab_search(&expa_false,
- &cur_av->node->key);
- if (!avdatp)
+ int rc = 0;
+ avtab_key_t avtab_key;
+ type_datum_t *td;
+ ebitmap_node_t *tnode;
+ unsigned int i;
+ uint32_t d;
+
+ avtab_key.specified = AVTAB_ALLOWED;
+ avtab_key.target_class = class;
+
+ if (ebitmap_get_bit(&p->attr_type_map[src - 1], child - 1)) {
+ avtab_key.source_type = parent;
+ ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
+ if (!ebitmap_node_get_bit(tnode, i))
continue;
-
- avdat.data = (cur_av->node->datum.data
- & avdatp->data);
- if (!avdat.data)
+ avtab_key.target_type = i + 1;
+ d = bounds_not_covered(global_avtab, cur_avtab,
+ &avtab_key, data);
+ if (!d) continue;
+ td = p->type_val_to_struct[i];
+ if (td && td->bounds) {
+ avtab_key.target_type = td->bounds;
+ d = bounds_not_covered(global_avtab, cur_avtab,
+ &avtab_key, data);
+ if (!d) continue;
+ }
+ (*numbad)++;
+ rc = bounds_add_bad(handle, child, i+1, class, d, bad);
+ if (rc) goto exit;
+ }
+ }
+ if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], child - 1)) {
+ avtab_key.target_type = parent;
+ ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
+ if (!ebitmap_node_get_bit(tnode, i))
continue;
-
- avnode = avtab_search_node(args->expa,
- &cur_av->node->key);
- if (avnode) {
- avnode->datum.data |= avdat.data;
- } else {
- if (avtab_insert(args->expa,
- &cur_av->node->key,
- &avdat))
- goto oom4;
+ avtab_key.source_type = i + 1;
+ if (avtab_key.source_type == child) {
+ /* Checked above */
+ continue;
+ }
+ d = bounds_not_covered(global_avtab, cur_avtab,
+ &avtab_key, data);
+ if (!d) continue;
+ td = p->type_val_to_struct[i];
+ if (td && td->bounds) {
+ avtab_key.source_type = td->bounds;
+ d = bounds_not_covered(global_avtab, cur_avtab,
+ &avtab_key, data);
+ if (!d) continue;
}
+ (*numbad)++;
+ rc = bounds_add_bad(handle, i+1, child, class, d, bad);
+ if (rc) goto exit;
}
- cond_av_list_destroy(expl_false);
- cond_av_list_destroy(expl_true);
- avtab_destroy(&expa_false);
- avtab_destroy(&expa_true);
}
- return 0;
-oom4:
- cond_av_list_destroy(expl_false);
-oom3:
- cond_av_list_destroy(expl_true);
-oom2:
- avtab_destroy(&expa_false);
-oom1:
- avtab_destroy(&expa_true);
-oom0:
- ERR(args->handle, "out of memory on conditional av list expansion");
- return 1;
+exit:
+ return rc;
+}
+
+static int bounds_check_cond_rules(sepol_handle_t *handle, policydb_t *p,
+ avtab_t *global_avtab, avtab_t *cond_avtab,
+ cond_av_list_t *rules, uint32_t child,
+ uint32_t parent, avtab_ptr_t *bad,
+ int *numbad)
+{
+ int rc = 0;
+ cond_av_list_t *cur;
+
+ for (cur = rules; cur; cur = cur->next) {
+ avtab_ptr_t ap = cur->node;
+ avtab_key_t *key = &ap->key;
+ avtab_datum_t *datum = &ap->datum;
+ if (!(key->specified & AVTAB_ALLOWED))
+ continue;
+ rc = bounds_check_rule(handle, p, global_avtab, cond_avtab,
+ child, parent, key->source_type,
+ key->target_type, key->target_class,
+ datum->data, bad, numbad);
+ if (rc) goto exit;
+ }
+
+exit:
+ return rc;
+}
+
+struct bounds_check_args {
+ sepol_handle_t *handle;
+ policydb_t *p;
+ avtab_t *cur_avtab;
+ uint32_t child;
+ uint32_t parent;
+ avtab_ptr_t bad;
+ int numbad;
+};
+
+static int bounds_check_rule_callback(avtab_key_t *k, avtab_datum_t *d,
+ void *args)
+{
+ struct bounds_check_args *a = (struct bounds_check_args *)args;
+
+ if (!(k->specified & AVTAB_ALLOWED))
+ return 0;
+
+ return bounds_check_rule(a->handle, a->p, NULL, a->cur_avtab, a->child,
+ a->parent, k->source_type, k->target_type,
+ k->target_class, d->data, &a->bad, &a->numbad);
}
-static int check_cond_avtab_hierarchy(cond_list_t * cond_list,
- hierarchy_args_t * args)
+static int bounds_check_child_rules(sepol_handle_t *handle, policydb_t *p,
+ avtab_t *global_avtab,
+ struct bounds_cond_info *cond_info,
+ uint32_t child, uint32_t parent,
+ avtab_ptr_t *bad, int *numbad)
{
int rc;
- cond_list_t *cur_node;
- cond_av_list_t *cur_av, *expl = NULL;
- avtab_t expa;
- hierarchy_args_t *a = (hierarchy_args_t *) args;
- avtab_datum_t avdat, *uncond;
-
- for (cur_node = cond_list; cur_node; cur_node = cur_node->next) {
- /*
- * Check true condition
- */
- if (avtab_init(&expa))
- goto oom;
- if (expand_cond_av_list(args->p, cur_node->true_list,
- &expl, &expa)) {
- avtab_destroy(&expa);
- goto oom;
- }
- args->opt_cond_list = expl;
- for (cur_av = expl; cur_av; cur_av = cur_av->next) {
- avdat.data = cur_av->node->datum.data;
- uncond = avtab_search(a->expa, &cur_av->node->key);
- if (uncond)
- avdat.data |= uncond->data;
- rc = check_avtab_hierarchy_callback(&cur_av->node->key,
- &avdat, args);
- if (rc)
- args->numerr++;
- }
- cond_av_list_destroy(expl);
- avtab_destroy(&expa);
+ struct bounds_check_args args;
+ struct bounds_cond_info *cur;
- /*
- * Check false condition
- */
- if (avtab_init(&expa))
- goto oom;
- if (expand_cond_av_list(args->p, cur_node->false_list,
- &expl, &expa)) {
- avtab_destroy(&expa);
- goto oom;
- }
- args->opt_cond_list = expl;
- for (cur_av = expl; cur_av; cur_av = cur_av->next) {
- avdat.data = cur_av->node->datum.data;
- uncond = avtab_search(a->expa, &cur_av->node->key);
- if (uncond)
- avdat.data |= uncond->data;
-
- rc = check_avtab_hierarchy_callback(&cur_av->node->key,
- &avdat, args);
- if (rc)
- a->numerr++;
+ args.handle = handle;
+ args.p = p;
+ args.cur_avtab = global_avtab;
+ args.child = child;
+ args.parent = parent;
+ args.bad = NULL;
+ args.numbad = 0;
+ rc = avtab_map(&p->te_avtab, bounds_check_rule_callback, &args);
+ if (rc) goto exit;
+
+ for (cur = cond_info; cur; cur = cur->next) {
+ cond_list_t *node = cur->cond_list;
+ rc = bounds_check_cond_rules(handle, p, global_avtab,
+ &cur->true_avtab,
+ node->true_list, child, parent,
+ &args.bad, &args.numbad);
+ if (rc) goto exit;
+
+ rc = bounds_check_cond_rules(handle, p, global_avtab,
+ &cur->false_avtab,
+ node->false_list, child, parent,
+ &args.bad, &args.numbad);
+ if (rc) goto exit;
+ }
+
+ *numbad += args.numbad;
+ *bad = args.bad;
+
+exit:
+ return rc;
+}
+
+int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+ uint32_t parent, avtab_ptr_t *bad, int *numbad)
+{
+ int rc = 0;
+ avtab_t global_avtab;
+ struct bounds_cond_info *cond_info = NULL;
+
+ rc = bounds_expand_parent_rules(handle, p, &global_avtab, &cond_info, parent);
+ if (rc) goto exit;
+
+ rc = bounds_check_child_rules(handle, p, &global_avtab, cond_info,
+ child, parent, bad, numbad);
+
+ bounds_destroy_cond_info(cond_info);
+ avtab_destroy(&global_avtab);
+
+exit:
+ return rc;
+}
+
+struct bounds_args {
+ sepol_handle_t *handle;
+ policydb_t *p;
+ int numbad;
+};
+
+static void bounds_report(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+ uint32_t parent, avtab_ptr_t cur)
+{
+ ERR(handle, "Child type %s exceeds bounds of parent %s in the following rules:",
+ p->p_type_val_to_name[child - 1],
+ p->p_type_val_to_name[parent - 1]);
+ for (; cur; cur = cur->next) {
+ ERR(handle, " %s %s : %s { %s }",
+ p->p_type_val_to_name[cur->key.source_type - 1],
+ p->p_type_val_to_name[cur->key.target_type - 1],
+ p->p_class_val_to_name[cur->key.target_class - 1],
+ sepol_av_to_string(p, cur->key.target_class,
+ cur->datum.data));
+ }
+}
+
+void bounds_destroy_bad(avtab_ptr_t cur)
+{
+ avtab_ptr_t next;
+
+ for (; cur; cur = next) {
+ next = cur->next;
+ cur->next = NULL;
+ free(cur);
+ }
+}
+
+static int bounds_check_type_callback(hashtab_key_t k __attribute__ ((unused)),
+ hashtab_datum_t d, void *args)
+{
+ int rc = 0;
+ struct bounds_args *a = (struct bounds_args *)args;
+ type_datum_t *t = (type_datum_t *)d;
+ avtab_ptr_t bad = NULL;
+
+ if (t->bounds) {
+ rc = bounds_check_type(a->handle, a->p, t->s.value, t->bounds,
+ &bad, &a->numbad);
+ if (bad) {
+ bounds_report(a->handle, a->p, t->s.value, t->bounds,
+ bad);
+ bounds_destroy_bad(bad);
}
- cond_av_list_destroy(expl);
- avtab_destroy(&expa);
}
- return 0;
+ return rc;
+}
+
+int bounds_check_types(sepol_handle_t *handle, policydb_t *p)
+{
+ int rc;
+ struct bounds_args args;
+
+ args.handle = handle;
+ args.p = p;
+ args.numbad = 0;
+
+ rc = hashtab_map(p->p_types.table, bounds_check_type_callback, &args);
+ if (rc) goto exit;
+
+ if (args.numbad > 0) {
+ ERR(handle, "%d errors found during type bounds check",
+ args.numbad);
+ rc = SEPOL_ERR;
+ }
- oom:
- ERR(args->handle, "out of memory on conditional av list expansion");
- return 1;
+exit:
+ return rc;
}
-/* The role hierarchy is defined as: a child role cannot have more types than it's parent.
- * This function should be called with hashtab_map, it will return 0 on success, 1 on
- * constraint violation and -1 on error
+/* The role bounds is defined as: a child role cannot have a type that
+ * its parent doesn't have.
*/
-static int check_role_hierarchy_callback(hashtab_key_t k
- __attribute__ ((unused)),
- hashtab_datum_t d, void *args)
+static int bounds_check_role_callback(hashtab_key_t k __attribute__ ((unused)),
+ hashtab_datum_t d, void *args)
{
- hierarchy_args_t *a;
- role_datum_t *r, *rp;
+ struct bounds_args *a = (struct bounds_args *)args;
+ role_datum_t *r = (role_datum_t *) d;
+ role_datum_t *rp = NULL;
- a = (hierarchy_args_t *) args;
- r = (role_datum_t *) d;
+ if (!r->bounds)
+ return 0;
- if (find_parent_role(a, r, &rp) < 0)
- return -1;
+ rp = a->p->role_val_to_struct[r->bounds - 1];
if (rp && !ebitmap_contains(&rp->types.types, &r->types.types)) {
- /* hierarchical constraint violation, return error */
- ERR(a->handle, "Role hierarchy violation, %s exceeds %s",
- (char *) k, a->p->p_role_val_to_name[rp->s.value - 1]);
- a->numerr++;
+ ERR(a->handle, "Role bounds violation, %s exceeds %s",
+ (char *)k, a->p->p_role_val_to_name[rp->s.value - 1]);
+ a->numbad++;
+ }
+
+ return 0;
+}
+
+int bounds_check_roles(sepol_handle_t *handle, policydb_t *p)
+{
+ struct bounds_args args;
+
+ args.handle = handle;
+ args.p = p;
+ args.numbad = 0;
+
+ hashtab_map(p->p_roles.table, bounds_check_role_callback, &args);
+
+ if (args.numbad > 0) {
+ ERR(handle, "%d errors found during role bounds check",
+ args.numbad);
+ return SEPOL_ERR;
}
+
return 0;
}
-/* The user hierarchy is defined as: a child user cannot have a role that
- * its parent doesn't have. This function should be called with hashtab_map,
- * it will return 0 on success, 1 on constraint violation and -1 on error.
+/* The user bounds is defined as: a child user cannot have a role that
+ * its parent doesn't have.
*/
-static int check_user_hierarchy_callback(hashtab_key_t k
- __attribute__ ((unused)),
- hashtab_datum_t d, void *args)
+static int bounds_check_user_callback(hashtab_key_t k __attribute__ ((unused)),
+ hashtab_datum_t d, void *args)
{
- hierarchy_args_t *a;
- user_datum_t *u, *up;
+ struct bounds_args *a = (struct bounds_args *)args;
+ user_datum_t *u = (user_datum_t *) d;
+ user_datum_t *up = NULL;
- a = (hierarchy_args_t *) args;
- u = (user_datum_t *) d;
+ if (!u->bounds)
+ return 0;
- if (find_parent_user(a, u, &up) < 0)
- return -1;
+ up = a->p->user_val_to_struct[u->bounds - 1];
if (up && !ebitmap_contains(&up->roles.roles, &u->roles.roles)) {
- /* hierarchical constraint violation, return error */
- ERR(a->handle, "User hierarchy violation, %s exceeds %s",
+ ERR(a->handle, "User bounds violation, %s exceeds %s",
(char *) k, a->p->p_user_val_to_name[up->s.value - 1]);
- a->numerr++;
+ a->numbad++;
}
+
return 0;
}
-int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p)
+int bounds_check_users(sepol_handle_t *handle, policydb_t *p)
{
- hierarchy_args_t args;
- avtab_t expa;
-
- if (avtab_init(&expa))
- goto oom;
- if (expand_avtab(p, &p->te_avtab, &expa)) {
- avtab_destroy(&expa);
- goto oom;
- }
+ struct bounds_args args;
- args.p = p;
- args.expa = &expa;
- args.opt_cond_list = NULL;
args.handle = handle;
- args.numerr = 0;
+ args.p = p;
+ args.numbad = 0;
- if (hashtab_map(p->p_types.table, check_type_hierarchy_callback, &args))
- goto bad;
+ hashtab_map(p->p_users.table, bounds_check_user_callback, &args);
- if (pullup_unconditional_perms(p->cond_list, &args))
- return -1;
+ if (args.numbad > 0) {
+ ERR(handle, "%d errors found during user bounds check",
+ args.numbad);
+ return SEPOL_ERR;
+ }
- if (avtab_map(&expa, check_avtab_hierarchy_callback, &args))
- goto bad;
+ return 0;
+}
- if (check_cond_avtab_hierarchy(p->cond_list, &args))
- goto bad;
+#define add_hierarchy_callback_template(prefix) \
+ int hierarchy_add_##prefix##_callback(hashtab_key_t k __attribute__ ((unused)), \
+ hashtab_datum_t d, void *args) \
+{ \
+ struct bounds_args *a = (struct bounds_args *)args; \
+ sepol_handle_t *handle = a->handle; \
+ policydb_t *p = a->p; \
+ prefix##_datum_t *datum = (prefix##_datum_t *)d; \
+ prefix##_datum_t *parent; \
+ char *parent_name, *datum_name, *tmp; \
+ \
+ if (!datum->bounds) { \
+ datum_name = p->p_##prefix##_val_to_name[datum->s.value - 1]; \
+ \
+ tmp = strrchr(datum_name, '.'); \
+ /* no '.' means it has no parent */ \
+ if (!tmp) return 0; \
+ \
+ parent_name = strdup(datum_name); \
+ if (!parent_name) { \
+ ERR(handle, "Insufficient memory"); \
+ return SEPOL_ENOMEM; \
+ } \
+ parent_name[tmp - datum_name] = '\0'; \
+ \
+ parent = hashtab_search(p->p_##prefix##s.table, parent_name); \
+ if (!parent) { \
+ /* Orphan type/role/user */ \
+ ERR(handle, "%s doesn't exist, %s is an orphan",\
+ parent_name, \
+ p->p_##prefix##_val_to_name[datum->s.value - 1]); \
+ free(parent_name); \
+ a->numbad++; \
+ return 0; \
+ } \
+ datum->bounds = parent->s.value; \
+ free(parent_name); \
+ } \
+ \
+ return 0; \
+} \
+
+static add_hierarchy_callback_template(type)
+static add_hierarchy_callback_template(role)
+static add_hierarchy_callback_template(user)
- if (hashtab_map(p->p_roles.table, check_role_hierarchy_callback, &args))
- goto bad;
+int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p)
+{
+ int rc = 0;
+ struct bounds_args args;
+
+ args.handle = handle;
+ args.p = p;
+ args.numbad = 0;
+
+ rc = hashtab_map(p->p_users.table, hierarchy_add_user_callback, &args);
+ if (rc) goto exit;
+
+ rc = hashtab_map(p->p_roles.table, hierarchy_add_role_callback, &args);
+ if (rc) goto exit;
- if (hashtab_map(p->p_users.table, check_user_hierarchy_callback, &args))
- goto bad;
+ rc = hashtab_map(p->p_types.table, hierarchy_add_type_callback, &args);
+ if (rc) goto exit;
- if (args.numerr) {
- ERR(handle, "%d total errors found during hierarchy check",
- args.numerr);
- goto bad;
+ if (args.numbad > 0) {
+ ERR(handle, "%d errors found while adding hierarchies",
+ args.numbad);
+ rc = SEPOL_ERR;
}
- avtab_destroy(&expa);
- return 0;
+exit:
+ return rc;
+}
+
+int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p)
+{
+ int rc = 0;
+ int violation = 0;
+
+ rc = hierarchy_add_bounds(handle, p);
+ if (rc) goto exit;
+
+ rc = bounds_check_users(handle, p);
+ if (rc)
+ violation = 1;
+
+ rc = bounds_check_roles(handle, p);
+ if (rc)
+ violation = 1;
+
+ rc = bounds_check_types(handle, p);
+ if (rc) {
+ if (rc == SEPOL_ERR)
+ violation = 1;
+ else
+ goto exit;
+ }
- bad:
- avtab_destroy(&expa);
- return -1;
+ if (violation)
+ rc = SEPOL_ERR;
- oom:
- ERR(handle, "Out of memory");
- return -1;
+exit:
+ return rc;
}
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 2d8046c9..18ec6b93 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -2859,7 +2859,7 @@ static int level_string_to_cil(char *levelstr)
char *token = NULL;
char *ranged = NULL;
- matched = sscanf(levelstr, "%m[^:]:%ms", &sens, &cats);
+ matched = tokenize(levelstr, ':', 2, &sens, &cats);
if (matched < 1 || matched > 2) {
log_err("Invalid level: %s", levelstr);
rc = -1;
@@ -2924,7 +2924,7 @@ static int context_string_to_cil(char *contextstr)
char *type = NULL;
char *level = NULL;
- matched = sscanf(contextstr, "%m[^:]:%m[^:]:%m[^:]:%ms", &user, &role, &type, &level);
+ matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level);
if (matched < 3 || matched > 4) {
log_err("Invalid context: %s", contextstr);
rc = -1;
@@ -2965,6 +2965,7 @@ static int seusers_to_cil(struct sepol_module_package *mod_pkg)
char *user = NULL;
char *seuser = NULL;
char *level = NULL;
+ char *tmp = NULL;
int matched;
if (seusers_len == 0) {
@@ -2972,11 +2973,18 @@ static int seusers_to_cil(struct sepol_module_package *mod_pkg)
}
while ((rc = get_line(&cur, end, &line)) > 0) {
- if (line[0] == '#') {
+ tmp = line;
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+
+ if (tmp[0] == '#' || tmp[0] == '\0') {
+ free(line);
+ line = NULL;
continue;
}
- matched = sscanf(line, "%m[^:]:%m[^:]:%ms", &user, &seuser, &level);
+ matched = tokenize(tmp, ':', 3, &user, &seuser, &level);
if (matched < 2 || matched > 3) {
log_err("Invalid seuser line: %s", line);
@@ -3045,28 +3053,51 @@ static int user_extra_to_cil(struct sepol_module_package *mod_pkg)
int matched;
char *user = NULL;
char *prefix = NULL;
+ int prefix_len = 0;
+ char *user_str = NULL;
+ char *prefix_str = NULL;
+ char *eol = NULL;
+ char *tmp = NULL;
if (userx_len == 0) {
return 0;
}
while ((rc = get_line(&cur, end, &line)) > 0) {
- if (line[0] == '#') {
+ tmp = line;
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+
+ if (tmp[0] == '#' || tmp[0] == '\0') {
+ free(line);
+ line = NULL;
continue;
}
- matched = sscanf(line, "user %ms prefix %m[^;];", &user, &prefix);
- if (matched != 2) {
+ matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix);
+ if (matched != 4) {
rc = -1;
- log_err("Invalid file context line: %s", line);
+ log_err("Invalid user extra line: %s", line);
goto exit;
}
+ prefix_len = strlen(prefix);
+ eol = prefix + prefix_len - 1;
+ if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) {
+ rc = -1;
+ log_err("Invalid user extra line: %s", line);
+ goto exit;
+ }
+ *eol = '\0';
+
cil_println(0, "(userprefix %s %s)", user, prefix);
free(user);
free(prefix);
free(line);
- user = prefix = line = NULL;
+ free(user_str);
+ free(prefix_str);
+ user = prefix = line = user_str = prefix_str = NULL;
}
if (rc == -1) {
@@ -3096,17 +3127,25 @@ static int file_contexts_to_cil(struct sepol_module_package *mod_pkg)
char *mode = NULL;
char *context = NULL;
const char *cilmode;
+ char *tmp = NULL;
if (fc_len == 0) {
return 0;
}
while ((rc = get_line(&cur, end, &line)) > 0) {
- if (line[0] == '#') {
+ tmp = line;
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+
+ if (tmp[0] == '#' || tmp[0] == '\0') {
+ free(line);
+ line = NULL;
continue;
}
- matched = sscanf(line, "%ms %ms %ms", &regex, &mode, &context);
+ matched = tokenize(tmp, ' ', 3, &regex, &mode, &context);
if (matched < 2 || matched > 3) {
rc = -1;
log_err("Invalid file context line: %s", line);
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 8c3c7ac0..665f7a98 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -180,7 +180,7 @@ static struct policydb_compat_info policydb_compat[] = {
},
{
.type = POLICY_KERN,
- .version = POLICYDB_VERSION_IOCTL_OPERATIONS,
+ .version = POLICYDB_VERSION_XPERMS_IOCTL,
.sym_num = SYM_NUM,
.ocon_num = OCON_NODE6 + 1,
.target_platform = SEPOL_TARGET_SELINUX,
@@ -3936,6 +3936,10 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
/* add the type itself as the degenerate case */
if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
goto bad;
+ if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
+ if (ebitmap_set_bit(&p->attr_type_map[i], i, 1))
+ goto bad;
+ }
}
}
diff --git a/libsepol/src/util.c b/libsepol/src/util.c
index a824e611..ff8f7f28 100644
--- a/libsepol/src/util.c
+++ b/libsepol/src/util.c
@@ -19,11 +19,15 @@
*/
#include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sepol/policydb/flask_types.h>
#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/util.h>
+#include <dso.h>
struct val_to_name {
unsigned int val;
@@ -114,3 +118,169 @@ char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass,
return avbuf;
}
+
+#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p))
+
+char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
+{
+ uint16_t value;
+ uint16_t low_bit;
+ uint16_t low_value;
+ unsigned int bit;
+ unsigned int in_range = 0;
+ static char xpermsbuf[2048];
+ xpermsbuf[0] = '\0';
+ char *p;
+ int len, xpermslen = 0;
+ p = xpermsbuf;
+
+ if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+ && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+ return NULL;
+
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "ioctl { ");
+ p += len;
+ xpermslen += len;
+
+ for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
+ if (!xperm_test(bit, xperms->perms))
+ continue;
+
+ if (in_range && next_bit_in_range(bit, xperms->perms)) {
+ /* continue until high value found */
+ continue;
+ } else if (next_bit_in_range(bit, xperms->perms)) {
+ /* low value */
+ low_bit = bit;
+ in_range = 1;
+ continue;
+ }
+
+ if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
+ value = xperms->driver<<8 | bit;
+ low_value = xperms->driver<<8 | low_bit;
+ if (in_range) {
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, value);
+ } else {
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx ", value);
+ }
+ } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
+ value = bit << 8;
+ low_value = low_bit << 8;
+ if (in_range) {
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
+ } else {
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
+ }
+
+ }
+
+ if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
+ return NULL;
+
+ p += len;
+ xpermslen += len;
+ if (in_range)
+ in_range = 0;
+ }
+
+ len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "}");
+ if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
+ return NULL;
+
+ return xpermsbuf;
+}
+
+/*
+ * The tokenize and tokenize_str functions may be used to
+ * replace sscanf to read tokens from buffers.
+ */
+
+/* Read a token from a buffer */
+static inline int tokenize_str(char delim, char **str, char **ptr, size_t *len)
+{
+ char *tmp_buf = *ptr;
+ *str = NULL;
+
+ while (**ptr != '\0') {
+ if (isspace(delim) && isspace(**ptr)) {
+ (*ptr)++;
+ break;
+ } else if (!isspace(delim) && **ptr == delim) {
+ (*ptr)++;
+ break;
+ }
+
+ (*ptr)++;
+ }
+
+ *len = *ptr - tmp_buf;
+ /* If the end of the string has not been reached, this will ensure the
+ * delimiter is not included when returning the token.
+ */
+ if (**ptr != '\0') {
+ (*len)--;
+ }
+
+ *str = strndup(tmp_buf, *len);
+ if (!*str) {
+ return -1;
+ }
+
+ /* Squash spaces if the delimiter is a whitespace character */
+ while (**ptr != '\0' && isspace(delim) && isspace(**ptr)) {
+ (*ptr)++;
+ }
+
+ return 0;
+}
+
+/*
+ * line_buf - Buffer containing string to tokenize.
+ * delim - The delimiter used to tokenize line_buf. A whitespace delimiter will
+ * be tokenized using isspace().
+ * num_args - The number of parameter entries to process.
+ * ... - A 'char **' for each parameter.
+ * returns - The number of items processed.
+ *
+ * This function calls tokenize_str() to do the actual string processing. The
+ * caller is responsible for calling free() on each additional argument. The
+ * function will not tokenize more than num_args and the last argument will
+ * contain the remaining content of line_buf. If the delimiter is any whitespace
+ * character, then all whitespace will be squashed.
+ */
+int hidden tokenize(char *line_buf, char delim, int num_args, ...)
+{
+ char **arg, *buf_p;
+ int rc, items;
+ size_t arg_len = 0;
+ va_list ap;
+
+ buf_p = line_buf;
+
+ /* Process the arguments */
+ va_start(ap, num_args);
+
+ for (items = 0; items < num_args && *buf_p != '\0'; items++) {
+ arg = va_arg(ap, char **);
+
+ /* Save the remainder of the string in arg */
+ if (items == num_args - 1) {
+ *arg = strdup(buf_p);
+ if (*arg == NULL) {
+ goto exit;
+ }
+
+ continue;
+ }
+
+ rc = tokenize_str(delim, arg, &buf_p, &arg_len);
+ if (rc < 0) {
+ goto exit;
+ }
+ }
+
+exit:
+ va_end(ap);
+ return items;
+}
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 6e78eb31..d87ea61b 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -221,28 +221,32 @@ static int avtab_write_item(policydb_t * p,
items = put_entry(buf16, sizeof(uint16_t), 4, fp);
if (items != 4)
return POLICYDB_ERROR;
- if ((p->policyvers < POLICYDB_VERSION_IOCTL_OPERATIONS) &&
- (cur->key.specified & AVTAB_OP)) {
- ERR(fp->handle, "policy version %u does not support ioctl operation"
- " rules and one was specified", p->policyvers);
+ if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) &&
+ (cur->key.specified & AVTAB_XPERMS)) {
+ ERR(fp->handle, "policy version %u does not support ioctl extended"
+ "permissions rules and one was specified", p->policyvers);
return POLICYDB_ERROR;
}
if (p->target_platform != SEPOL_TARGET_SELINUX &&
- (cur->key.specified & AVTAB_OP)) {
+ (cur->key.specified & AVTAB_XPERMS)) {
ERR(fp->handle, "Target platform %s does not support ioctl "
- "operation rules and one was specified",
+ "extended permissions rules and one was specified",
policydb_target_strings[p->target_platform]);
return POLICYDB_ERROR;
}
- if (cur->key.specified & AVTAB_OP) {
- buf8 = cur->datum.ops->type;
+ if (cur->key.specified & AVTAB_XPERMS) {
+ buf8 = cur->datum.xperms->specified;
items = put_entry(&buf8, sizeof(uint8_t),1,fp);
if (items != 1)
return POLICYDB_ERROR;
- for (i = 0; i < ARRAY_SIZE(cur->datum.ops->perms); i++)
- buf32[i] = cpu_to_le32(cur->datum.ops->perms[i]);
+ buf8 = cur->datum.xperms->driver;
+ items = put_entry(&buf8, sizeof(uint8_t),1,fp);
+ if (items != 1)
+ return POLICYDB_ERROR;
+ for (i = 0; i < ARRAY_SIZE(cur->datum.xperms->perms); i++)
+ buf32[i] = cpu_to_le32(cur->datum.xperms->perms[i]);
items = put_entry(buf32, sizeof(uint32_t),8,fp);
if (items != 8)
return POLICYDB_ERROR;
@@ -1546,9 +1550,9 @@ static int avrule_write(avrule_t * avrule, struct policy_file *fp)
uint32_t buf[32], len;
class_perm_node_t *cur;
- if (avrule->specified & AVRULE_OP) {
- ERR(fp->handle, "module policy does not support ioctl operation"
- " rules and one was specified");
+ if (avrule->specified & AVRULE_XPERMS) {
+ ERR(fp->handle, "module policy does not support extended"
+ " permissions rules and one was specified");
return POLICYDB_ERROR;
}
diff --git a/policycoreutils/ChangeLog b/policycoreutils/ChangeLog
index cc2bc714..f78e5c0d 100644
--- a/policycoreutils/ChangeLog
+++ b/policycoreutils/ChangeLog
@@ -1,3 +1,11 @@
+ * audit2allow/why: ignore setlocale errors, from Petr Lautrbach.
+ * semodule: Add --extract/-E, --cil/-c, and --hll/-H to extract modules, from Yuli Khodorkovskiy.
+ * audit2allow: Comment constraint rules in output, from Miroslav Grepl via Petr Lautrbach.
+ * Fix PEP8 issues, from Jason Zaman.
+ * semanage: fix moduleRecords deleteall method, from Stephen Smalley.
+ * Improve compatibility with Python 3, from Michal Srb.
+ * semanage: Set self.sename to sename after calling semanage_seuser_set_sename(), from Laurent Bigonville.
+ * semanage: Fix typo in semanage args for minimium policy store, from Petr Lautrbach.
* sepolicy: Only invoke RPM on RPM-enabled Linux distributions, from Sven Vermeulen.
* mcstransd: don't reinvent getpeercon, from Stephen Smalley.
* setfiles/restorecon: fix -r/-R option, from Petr Lautrbach.
diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow
index c9713a27..e23e418b 100755
--- a/policycoreutils/audit2allow/audit2allow
+++ b/policycoreutils/audit2allow/audit2allow
@@ -19,7 +19,8 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-import sys, os
+import sys
+import os
import sepolgen.audit as audit
import sepolgen.policygen as policygen
@@ -31,7 +32,11 @@ import sepolgen.module as module
from sepolgen.sepolgeni18n import _
import selinux.audit2why as audit2why
import locale
-locale.setlocale(locale.LC_ALL, '')
+try:
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
class AuditToPolicy:
VERSION = "%prog .1"
@@ -65,8 +70,8 @@ class AuditToPolicy:
help="generate a module package - conflicts with -o and -m")
parser.add_option("-o", "--output", dest="output",
help="append output to <filename>, conflicts with -M")
- parser.add_option("-D", "--dontaudit", action="store_true",
- dest="dontaudit", default=False,
+ parser.add_option("-D", "--dontaudit", action="store_true",
+ dest="dontaudit", default=False,
help="generate policy with dontaudit rules")
parser.add_option("-R", "--reference", action="store_true", dest="refpolicy",
default=True, help="generate refpolicy style output")
@@ -83,7 +88,7 @@ class AuditToPolicy:
parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
parser.add_option("--debug", dest="debug", action="store_true", default=False,
help="leave generated modules for -M")
- parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
+ parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0]) == "audit2why"),
help="Translates SELinux audit messages into a description of why the access was denied")
options, args = parser.parse_args()
@@ -135,13 +140,13 @@ class AuditToPolicy:
elif self.__options.audit:
try:
messages = audit.get_audit_msgs()
- except OSError, e:
+ except OSError as e:
sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
sys.exit(1)
elif self.__options.boot:
try:
messages = audit.get_audit_boot_msgs()
- except OSError, e:
+ except OSError as e:
sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
sys.exit(1)
else:
@@ -152,7 +157,7 @@ class AuditToPolicy:
if filename is not None:
try:
f = open(filename)
- except IOError, e:
+ except IOError as e:
sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e)))
sys.exit(1)
@@ -214,7 +219,7 @@ class AuditToPolicy:
try:
fd = open(filename, "w")
- except IOError, e:
+ except IOError as e:
sys.stderr.write("could not write output file: %s\n" % str(e))
sys.exit(1)
@@ -225,71 +230,71 @@ class AuditToPolicy:
try:
mc.create_module_package(filename, self.__options.refpolicy)
- except RuntimeError, e:
- print e
+ except RuntimeError as e:
+ print(e)
sys.exit(1)
sys.stdout.write(_("******************** IMPORTANT ***********************\n"))
- sys.stdout.write((_("To make this policy package active, execute:" +\
- "\n\nsemodule -i %s\n\n") % packagename))
+ sys.stdout.write((_("To make this policy package active, execute:" +
+ "\n\nsemodule -i %s\n\n") % packagename))
def __output_audit2why(self):
- import selinux
- import seobject
- for i in self.__parser.avc_msgs:
- rc = i.type
- data = i.data
- if rc >= 0:
- print "%s\n\tWas caused by:" % i.message
- if rc == audit2why.ALLOW:
- print "\t\tUnknown - would be allowed by active policy\n",
- print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
- print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
- continue
- if rc == audit2why.DONTAUDIT:
- print "\t\tUnknown - should be dontaudit'd by active policy\n",
- print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
- print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
- continue
- if rc == audit2why.BOOLEAN:
- if len(data) > 1:
- print "\tOne of the following booleans was set incorrectly."
- for b in data:
- print "\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0])
- print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1])
- else:
- print "\tThe boolean %s was set incorrectly. " % (data[0][0])
- print "\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0])
- print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1])
- continue
-
- if rc == audit2why.TERULE:
- print "\t\tMissing type enforcement (TE) allow rule.\n"
- print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n"
- continue
-
- if rc == audit2why.CONSTRAINT:
- print #!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n"
- print "#Constraint rule:"
- print "\n\t" + data[0]
- for reason in data[1:]:
- print "#\tPossible cause is the source %s and target %s are different.\n" % reason
-
- if rc == audit2why.RBAC:
- print "\t\tMissing role allow rule.\n"
- print "\t\tAdd an allow rule for the role pair.\n"
- continue
-
- audit2why.finish()
- return
+ import selinux
+ import seobject
+ for i in self.__parser.avc_msgs:
+ rc = i.type
+ data = i.data
+ if rc >= 0:
+ print("%s\n\tWas caused by:" % i.message)
+ if rc == audit2why.ALLOW:
+ print("\t\tUnknown - would be allowed by active policy")
+ print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+ print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+ continue
+ if rc == audit2why.DONTAUDIT:
+ print("\t\tUnknown - should be dontaudit'd by active policy")
+ print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+ print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+ continue
+ if rc == audit2why.BOOLEAN:
+ if len(data) > 1:
+ print("\tOne of the following booleans was set incorrectly.")
+ for b in data:
+ print("\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]))
+ print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]))
+ else:
+ print("\tThe boolean %s was set incorrectly. " % (data[0][0]))
+ print("\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]))
+ print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]))
+ continue
+
+ if rc == audit2why.TERULE:
+ print("\t\tMissing type enforcement (TE) allow rule.\n")
+ print("\t\tYou can use audit2allow to generate a loadable module to allow this access.\n")
+ continue
+
+ if rc == audit2why.CONSTRAINT:
+ print() # !!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n"
+ print("#Constraint rule:")
+ print("\n#\t" + data[0])
+ for reason in data[1:]:
+ print("#\tPossible cause is the source %s and target %s are different.\n" % reason)
+
+ if rc == audit2why.RBAC:
+ print("\t\tMissing role allow rule.\n")
+ print("\t\tAdd an allow rule for the role pair.\n")
+ continue
+
+ audit2why.finish()
+ return
def __output(self):
-
+
if self.__options.audit2why:
try:
return self.__output_audit2why()
- except RuntimeError, e:
- print e
+ except RuntimeError as e:
+ print(e)
sys.exit(1)
g = policygen.PolicyGenerator()
@@ -348,11 +353,11 @@ class AuditToPolicy:
self.__output()
except KeyboardInterrupt:
sys.exit(0)
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
sys.exit(1)
- except IOError, e:
- print e
+ except IOError as e:
+ print(e)
sys.exit(1)
if __name__ == "__main__":
diff --git a/policycoreutils/audit2allow/audit2why b/policycoreutils/audit2allow/audit2why
index 323eddd9..b1489eda 100755
--- a/policycoreutils/audit2allow/audit2why
+++ b/policycoreutils/audit2allow/audit2why
@@ -19,7 +19,8 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-import sys, os
+import sys
+import os
import sepolgen.audit as audit
import sepolgen.policygen as policygen
@@ -31,7 +32,11 @@ import sepolgen.module as module
from sepolgen.sepolgeni18n import _
import selinux.audit2why as audit2why
import locale
-locale.setlocale(locale.LC_ALL, '')
+try:
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
class AuditToPolicy:
VERSION = "%prog .1"
@@ -83,7 +88,7 @@ class AuditToPolicy:
parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
parser.add_option("--debug", dest="debug", action="store_true", default=False,
help="leave generated modules for -M")
- parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
+ parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0]) == "audit2why"),
help="Translates SELinux audit messages into a description of why the access was denied")
options, args = parser.parse_args()
@@ -135,13 +140,13 @@ class AuditToPolicy:
elif self.__options.audit:
try:
messages = audit.get_audit_msgs()
- except OSError, e:
+ except OSError as e:
sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
sys.exit(1)
elif self.__options.boot:
try:
messages = audit.get_audit_boot_msgs()
- except OSError, e:
+ except OSError as e:
sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
sys.exit(1)
else:
@@ -152,7 +157,7 @@ class AuditToPolicy:
if filename is not None:
try:
f = open(filename)
- except IOError, e:
+ except IOError as e:
sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e)))
sys.exit(1)
@@ -214,7 +219,7 @@ class AuditToPolicy:
try:
fd = open(filename, "w")
- except IOError, e:
+ except IOError as e:
sys.stderr.write("could not write output file: %s\n" % str(e))
sys.exit(1)
@@ -225,70 +230,70 @@ class AuditToPolicy:
try:
mc.create_module_package(filename, self.__options.refpolicy)
- except RuntimeError, e:
- print e
+ except RuntimeError as e:
+ print(e)
sys.exit(1)
sys.stdout.write(_("******************** IMPORTANT ***********************\n"))
- sys.stdout.write((_("To make this policy package active, execute:" +\
- "\n\nsemodule -i %s\n\n") % packagename))
+ sys.stdout.write((_("To make this policy package active, execute:" +
+ "\n\nsemodule -i %s\n\n") % packagename))
def __output_audit2why(self):
- import selinux
- import seobject
- for i in self.__parser.avc_msgs:
- rc = i.type
- data = i.data
- if rc >= 0:
- print "%s\n\tWas caused by:" % i.message
- if rc == audit2why.ALLOW:
- print "\t\tUnknown - would be allowed by active policy\n",
- print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
- print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
- continue
- if rc == audit2why.DONTAUDIT:
- print "\t\tUnknown - should be dontaudit'd by active policy\n",
- print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
- print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
- continue
- if rc == audit2why.BOOLEAN:
- if len(data) > 1:
- print "\tOne of the following booleans was set incorrectly."
- for b in data:
- print "\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0])
- print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1])
- else:
- print "\tThe boolean %s was set incorrectly. " % (data[0][0])
- print "\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0])
- print "\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1])
- continue
-
- if rc == audit2why.TERULE:
- print "\t\tMissing type enforcement (TE) allow rule.\n"
- print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n"
- continue
-
- if rc == audit2why.CONSTRAINT:
- print #!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n"
- print "#Constraint rule: \n\t" + data[0]
- for reason in data[1:]:
- print "#\tPossible cause is the source %s and target %s are different.\n\b" % reason
-
- if rc == audit2why.RBAC:
- print "\t\tMissing role allow rule.\n"
- print "\t\tAdd an allow rule for the role pair.\n"
- continue
-
- audit2why.finish()
- return
+ import selinux
+ import seobject
+ for i in self.__parser.avc_msgs:
+ rc = i.type
+ data = i.data
+ if rc >= 0:
+ print("%s\n\tWas caused by:" % i.message)
+ if rc == audit2why.ALLOW:
+ print("\t\tUnknown - would be allowed by active policy")
+ print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+ print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+ continue
+ if rc == audit2why.DONTAUDIT:
+ print("\t\tUnknown - should be dontaudit'd by active policy")
+ print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+ print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+ continue
+ if rc == audit2why.BOOLEAN:
+ if len(data) > 1:
+ print("\tOne of the following booleans was set incorrectly.")
+ for b in data:
+ print("\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]))
+ print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]))
+ else:
+ print("\tThe boolean %s was set incorrectly. " % (data[0][0]))
+ print("\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]))
+ print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]))
+ continue
+
+ if rc == audit2why.TERULE:
+ print("\t\tMissing type enforcement (TE) allow rule.\n")
+ print("\t\tYou can use audit2allow to generate a loadable module to allow this access.\n")
+ continue
+
+ if rc == audit2why.CONSTRAINT:
+ print() # !!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.\n"
+ print("#Constraint rule: \n\t" + data[0])
+ for reason in data[1:]:
+ print("#\tPossible cause is the source %s and target %s are different.\n\b" % reason)
+
+ if rc == audit2why.RBAC:
+ print("\t\tMissing role allow rule.\n")
+ print("\t\tAdd an allow rule for the role pair.\n")
+ continue
+
+ audit2why.finish()
+ return
def __output(self):
if self.__options.audit2why:
try:
return self.__output_audit2why()
- except RuntimeError, e:
- print e
+ except RuntimeError as e:
+ print(e)
sys.exit(1)
g = policygen.PolicyGenerator()
@@ -347,11 +352,11 @@ class AuditToPolicy:
self.__output()
except KeyboardInterrupt:
sys.exit(0)
- except ValueError, e:
- print e
+ except ValueError as e:
+ print(e)
sys.exit(1)
- except IOError, e:
- print e
+ except IOError as e:
+ print(e)
sys.exit(1)
if __name__ == "__main__":
diff --git a/policycoreutils/audit2allow/sepolgen-ifgen b/policycoreutils/audit2allow/sepolgen-ifgen
index 83c7ecfa..acf96384 100644
--- a/policycoreutils/audit2allow/sepolgen-ifgen
+++ b/policycoreutils/audit2allow/sepolgen-ifgen
@@ -2,7 +2,7 @@
#
# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
#
-# Copyright (C) 2006 Red Hat
+# Copyright (C) 2006 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
@@ -41,6 +41,7 @@ import sepolgen.interfaces as interfaces
VERSION = "%prog .1"
ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"
+
def parse_options():
from optparse import OptionParser
@@ -54,13 +55,14 @@ def parse_options():
parser.add_option("-v", "--verbose", action="store_true", default=False,
help="print debuging output")
parser.add_option("-d", "--debug", action="store_true", default=False,
- help="extra debugging output")
+ help="extra debugging output")
parser.add_option("--no_attrs", action="store_true", default=False,
help="do not retrieve attribute access from kernel policy")
options, args = parser.parse_args()
-
+
return options
+
def get_policy():
p = selinux.selinux_current_policy_path()
if p and os.path.exists(p):
@@ -74,6 +76,7 @@ def get_policy():
return p
return None
+
def get_attrs(policy_path):
try:
if not policy_path:
@@ -82,14 +85,14 @@ def get_attrs(policy_path):
sys.stderr.write("No installed policy to check\n")
return None
outfile = tempfile.NamedTemporaryFile()
- except IOError, e:
+ except IOError as e:
sys.stderr.write("could not open attribute output file\n")
return None
except OSError:
# SELinux Disabled Machine
return None
- fd = open("/dev/null","w")
+ fd = open("/dev/null", "w")
ret = subprocess.Popen([ATTR_HELPER, policy_path, outfile.name], stdout=fd).wait()
fd.close()
if ret != 0:
@@ -100,18 +103,19 @@ def get_attrs(policy_path):
try:
attrs.from_file(outfile)
except:
- print "error parsing attribute info"
+ print("error parsing attribute info")
return None
return attrs
+
def main():
options = parse_options()
# Open the output first to generate errors before parsing
try:
f = open(options.output, "w")
- except IOError, e:
+ except IOError as e:
sys.stderr.write("could not open output file [%s]\n" % options.output)
return 1
@@ -130,9 +134,9 @@ def main():
# Parse the headers
try:
headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
- except ValueError, e:
- print "error parsing headers"
- print str(e)
+ except ValueError as e:
+ print("error parsing headers")
+ print(str(e))
return 1
if_set = interfaces.InterfaceSet(output=log)
@@ -144,6 +148,6 @@ def main():
return 0
else:
return 1
-
+
if __name__ == "__main__":
sys.exit(main())
diff --git a/policycoreutils/audit2allow/test_audit2allow.py b/policycoreutils/audit2allow/test_audit2allow.py
index 794673e1..765c9ea6 100644
--- a/policycoreutils/audit2allow/test_audit2allow.py
+++ b/policycoreutils/audit2allow/test_audit2allow.py
@@ -1,26 +1,31 @@
-import unittest, os, shutil
+import unittest
+import os
+import shutil
from tempfile import mkdtemp
from subprocess import Popen, PIPE
+
class Audit2allowTests(unittest.TestCase):
+
def assertDenied(self, err):
- self.assert_('Permission denied' in err,
- '"Permission denied" not found in %r' % err)
+ self.assertTrue('Permission denied' in err,
+ '"Permission denied" not found in %r' % err)
+
def assertNotFound(self, err):
- self.assert_('not found' in err,
- '"not found" not found in %r' % err)
+ self.assertTrue('not found' in err,
+ '"not found" not found in %r' % err)
def assertFailure(self, status):
- self.assert_(status != 0,
- '"Succeeded when it should have failed')
+ self.assertTrue(status != 0,
+ '"Succeeded when it should have failed')
def assertSuccess(self, cmd, status, err):
- self.assert_(status == 0,
- '"%s should have succeeded for this test %r' % (cmd, err))
+ self.assertTrue(status == 0,
+ '"%s should have succeeded for this test %r' % (cmd, err))
def test_sepolgen_ifgen(self):
"Verify sepolgen-ifgen works"
- p = Popen(['sudo', 'sepolgen-ifgen'], stdout = PIPE)
+ p = Popen(['sudo', 'sepolgen-ifgen'], stdout=PIPE)
out, err = p.communicate()
if err:
print(out, err)
@@ -28,7 +33,7 @@ class Audit2allowTests(unittest.TestCase):
def test_audit2allow(self):
"Verify audit2allow works"
- p = Popen(['audit2allow',"-i","test.log"], stdout = PIPE)
+ p = Popen(['audit2allow', "-i", "test.log"], stdout=PIPE)
out, err = p.communicate()
if err:
print(out, err)
@@ -36,7 +41,7 @@ class Audit2allowTests(unittest.TestCase):
def test_audit2why(self):
"Verify audit2why works"
- p = Popen(['audit2why',"-i","test.log"], stdout = PIPE)
+ p = Popen(['audit2why', "-i", "test.log"], stdout=PIPE)
out, err = p.communicate()
if err:
print(out, err)
diff --git a/policycoreutils/gui/booleansPage.py b/policycoreutils/gui/booleansPage.py
index eee954d3..507a79dd 100644
--- a/policycoreutils/gui/booleansPage.py
+++ b/policycoreutils/gui/booleansPage.py
@@ -28,18 +28,18 @@ import tempfile
import seobject
import semanagePage
-INSTALLPATH='/usr/share/system-config-selinux'
+INSTALLPATH = '/usr/share/system-config-selinux'
sys.path.append(INSTALLPATH)
import commands
-ENFORCING=0
-PERMISSIVE=1
-DISABLED=2
+ENFORCING = 0
+PERMISSIVE = 1
+DISABLED = 2
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -48,41 +48,47 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
from glob import fnmatch
+
class Modifier:
- def __init__(self,name, on, save):
- self.on=on
- self.name=name
- self.save=save
- def set(self,value):
- self.on=value
- self.save=True
+ def __init__(self, name, on, save):
+ self.on = on
+ self.name = name
+ self.save = save
+
+ def set(self, value):
+ self.on = value
+ self.save = True
def isOn(self):
return self.on
+
class Boolean(Modifier):
- def __init__(self,name, val, save=False):
- Modifier.__init__(self,name, val, save)
+
+ def __init__(self, name, val, save=False):
+ Modifier.__init__(self, name, val, save)
ACTIVE = 0
MODULE = 1
DESC = 2
BOOLEAN = 3
+
class booleansPage:
+
def __init__(self, xml, doDebug=None):
self.xml = xml
self.window = self.xml.get_widget("mainWindow").get_root_window()
self.local = False
- self.types=[]
+ self.types = []
self.selinuxsupport = True
self.typechanged = False
self.doDebug = doDebug
@@ -112,7 +118,7 @@ class booleansPage:
checkbox = gtk.CellRendererToggle()
checkbox.connect("toggled", self.boolean_toggled)
- col = gtk.TreeViewColumn('Active', checkbox, active = ACTIVE)
+ col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
col.set_clickable(True)
col.set_sort_column_id(ACTIVE)
self.booleansView.append_column(col)
@@ -123,7 +129,7 @@ class booleansPage:
self.booleansView.append_column(col)
col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC)
- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
col.set_fixed_width(400)
col.set_sort_column_id(DESC)
col.set_resizable(True)
@@ -134,7 +140,7 @@ class booleansPage:
col.set_resizable(True)
self.booleansView.set_search_equal_func(self.__search)
self.booleansView.append_column(col)
- self.filter=""
+ self.filter = ""
self.load(self.filter)
def error(self, message):
@@ -182,10 +188,10 @@ class booleansPage:
self.error(e.args[0])
def filter_changed(self, *arg):
- filter = arg[0].get_text()
+ filter = arg[0].get_text()
if filter != self.filter:
self.load(filter)
- self.filter=filter
+ self.filter = filter
def use_menus(self):
return False
@@ -193,17 +199,16 @@ class booleansPage:
def get_description(self):
return _("Boolean")
- def match(self,key, filter=""):
+ def match(self, key, filter=""):
try:
- f=filter.lower()
- cat=self.booleans.get_category(key).lower()
- val=self.booleans.get_desc(key).lower()
- k=key.lower()
+ f = filter.lower()
+ cat = self.booleans.get_category(key).lower()
+ val = self.booleans.get_desc(key).lower()
+ k = key.lower()
return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
except:
return False
-
def load(self, filter=None):
self.store.clear()
self.booleans = seobject.booleanRecords()
@@ -211,7 +216,7 @@ class booleansPage:
for name in booleansList:
rec = booleansList[name]
if self.match(name, filter):
- iter=self.store.append()
+ iter = self.store.append()
self.store.set_value(iter, ACTIVE, rec[2] == 1)
self.store.set_value(iter, MODULE, self.booleans.get_category(name))
self.store.set_value(iter, DESC, self.booleans.get_desc(name))
@@ -221,10 +226,10 @@ class booleansPage:
iter = self.store.get_iter(row)
val = self.store.get_value(iter, ACTIVE)
key = self.store.get_value(iter, BOOLEAN)
- self.store.set_value(iter, ACTIVE , not val)
+ self.store.set_value(iter, ACTIVE, not val)
self.wait()
- setsebool="/usr/sbin/setsebool -P %s %d" % (key, not val)
- rc,out = commands.getstatusoutput(setsebool)
+ setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
+ rc, out = commands.getstatusoutput(setsebool)
if rc != 0:
self.error(out)
self.load(self.filter)
@@ -232,7 +237,7 @@ class booleansPage:
def on_revert_clicked(self, button):
self.wait()
- setsebool="semanage boolean --deleteall"
+ setsebool = "semanage boolean --deleteall"
commands.getstatusoutput(setsebool)
self.load(self.filter)
self.ready()
diff --git a/policycoreutils/gui/domainsPage.py b/policycoreutils/gui/domainsPage.py
index 6af1e9af..56c66feb 100644
--- a/policycoreutils/gui/domainsPage.py
+++ b/policycoreutils/gui/domainsPage.py
@@ -25,13 +25,13 @@ import gobject
import sys
import seobject
import selinux
-from semanagePage import *;
+from semanagePage import *
from sepolicy import get_all_entrypoint_domains
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -39,12 +39,14 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class domainsPage(semanagePage):
+
def __init__(self, xml):
semanagePage.__init__(self, xml, "domains", _("Process Domain"))
self.domain_filter = xml.get_widget("domainsFilterEntry")
@@ -54,12 +56,12 @@ class domainsPage(semanagePage):
self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.view.set_model(self.store)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text=0)
col.set_sort_column_id(0)
col.set_resizable(True)
self.view.append_column(col)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text = 1)
+ col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text=1)
col.set_sort_column_id(1)
col.set_resizable(True)
self.view.append_column(col)
@@ -68,12 +70,12 @@ class domainsPage(semanagePage):
self.permissive_button = xml.get_widget("permissiveButton")
self.enforcing_button = xml.get_widget("enforcingButton")
- self.domains=get_all_entrypoint_domains()
+ self.domains = get_all_entrypoint_domains()
self.load()
def get_modules(self):
- modules=[]
- fd=os.popen("semodule -l")
+ modules = []
+ fd = os.popen("semodule -l")
mods = fd.readlines()
fd.close()
for l in mods:
@@ -81,10 +83,10 @@ class domainsPage(semanagePage):
return modules
def load(self, filter=""):
- self.filter=filter
+ self.filter = filter
self.store.clear()
try:
- modules=self.get_modules()
+ modules = self.get_modules()
for domain in self.domains:
if not self.match(domain, filter):
continue
@@ -97,7 +99,7 @@ class domainsPage(semanagePage):
self.store.set_value(iter, 1, "")
except:
pass
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def itemSelected(self, selection):
store, iter = selection.get_selected()
diff --git a/policycoreutils/gui/fcontextPage.py b/policycoreutils/gui/fcontextPage.py
index 131f1c29..c8d6ba85 100644
--- a/policycoreutils/gui/fcontextPage.py
+++ b/policycoreutils/gui/fcontextPage.py
@@ -22,16 +22,18 @@ import os
import gobject
import seobject
import commands
-from semanagePage import *;
+from semanagePage import *
SPEC_COL = 0
TYPE_COL = 1
FTYPE_COL = 2
+
class context:
+
def __init__(self, scontext):
self.scontext = scontext
- con=scontext.split(":")
+ con = scontext.split(":")
self.type = con[0]
if len(con) > 1:
self.mls = con[1]
@@ -44,7 +46,7 @@ class context:
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -53,13 +55,14 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
class fcontextPage(semanagePage):
+
def __init__(self, xml):
semanagePage.__init__(self, xml, "fcontext", _("File Labeling"))
self.fcontextFilter = xml.get_widget("fcontextFilterEntry")
@@ -72,16 +75,16 @@ class fcontextPage(semanagePage):
self.view.set_search_equal_func(self.search)
col = gtk.TreeViewColumn(_("File\nSpecification"), gtk.CellRendererText(), text=SPEC_COL)
- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
- col.set_fixed_width(250)
+ col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ col.set_fixed_width(250)
col.set_sort_column_id(SPEC_COL)
col.set_resizable(True)
self.view.append_column(col)
col = gtk.TreeViewColumn(_("Selinux\nFile Type"), gtk.CellRendererText(), text=TYPE_COL)
- col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
- col.set_fixed_width(250)
+ col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+ col.set_fixed_width(250)
col.set_sort_column_id(TYPE_COL)
col.set_resizable(True)
self.view.append_column(col)
@@ -94,10 +97,10 @@ class fcontextPage(semanagePage):
self.load()
self.fcontextEntry = xml.get_widget("fcontextEntry")
self.fcontextFileTypeCombo = xml.get_widget("fcontextFileTypeCombo")
- liststore=self.fcontextFileTypeCombo.get_model()
+ liststore = self.fcontextFileTypeCombo.get_model()
for k in seobject.file_types:
- if len(k) > 0 and k[0] != '-':
- iter=liststore.append()
+ if len(k) > 0 and k[0] != '-':
+ iter = liststore.append()
liststore.set_value(iter, 0, k)
iter = liststore.get_iter_first()
self.fcontextFileTypeCombo.set_active_iter(iter)
@@ -106,13 +109,13 @@ class fcontextPage(semanagePage):
def match(self, fcon_dict, k, filter):
try:
- f=filter.lower()
+ f = filter.lower()
for con in k:
- k=con.lower()
+ k = con.lower()
if k.find(f) >= 0:
return True
for con in fcon_dict[k]:
- k=con.lower()
+ k = con.lower()
if k.find(f) >= 0:
return True
except:
@@ -120,27 +123,27 @@ class fcontextPage(semanagePage):
return False
def load(self, filter=""):
- self.filter=filter
- self.fcontext=seobject.fcontextRecords()
+ self.filter = filter
+ self.fcontext = seobject.fcontextRecords()
self.store.clear()
- fcon_dict=self.fcontext.get_all(self.local)
+ fcon_dict = self.fcontext.get_all(self.local)
keys = fcon_dict.keys()
keys.sort()
for k in keys:
if not self.match(fcon_dict, k, filter):
continue
- iter=self.store.append()
+ iter = self.store.append()
self.store.set_value(iter, SPEC_COL, k[0])
self.store.set_value(iter, FTYPE_COL, k[1])
if fcon_dict[k]:
- rec="%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3],False))
+ rec = "%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3], False))
else:
- rec="<<None>>"
+ rec = "<<None>>"
self.store.set_value(iter, TYPE_COL, rec)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def filter_changed(self, *arg):
- filter = arg[0].get_text()
+ filter = arg[0].get_text()
if filter != self.filter:
self.load(filter)
@@ -149,13 +152,13 @@ class fcontextPage(semanagePage):
self.fcontextEntry.set_text(store.get_value(iter, SPEC_COL))
self.fcontextEntry.set_sensitive(False)
scontext = store.get_value(iter, TYPE_COL)
- scon=context(scontext)
+ scon = context(scontext)
self.fcontextTypeEntry.set_text(scon.type)
self.fcontextMLSEntry.set_text(scon.mls)
- type=store.get_value(iter, FTYPE_COL)
- liststore=self.fcontextFileTypeCombo.get_model()
+ type = store.get_value(iter, FTYPE_COL)
+ liststore = self.fcontextFileTypeCombo.get_model()
iter = liststore.get_iter_first()
- while iter != None and liststore.get_value(iter,0) != type:
+ while iter != None and liststore.get_value(iter, 0) != type:
iter = liststore.iter_next(iter)
if iter != None:
self.fcontextFileTypeCombo.set_active_iter(iter)
@@ -171,8 +174,8 @@ class fcontextPage(semanagePage):
def delete(self):
store, iter = self.view.get_selection().get_selected()
try:
- fspec=store.get_value(iter, SPEC_COL)
- ftype=store.get_value(iter, FTYPE_COL)
+ fspec = store.get_value(iter, SPEC_COL)
+ ftype = store.get_value(iter, FTYPE_COL)
self.wait()
(rc, out) = commands.getstatusoutput("semanage fcontext -d -f '%s' '%s'" % (ftype, fspec))
self.ready()
@@ -180,16 +183,16 @@ class fcontextPage(semanagePage):
if rc != 0:
return self.error(out)
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
except ValueError, e:
self.error(e.args[0])
def add(self):
- ftype=["", "--", "-d", "-c", "-b", "-s", "-l", "-p" ]
- fspec=self.fcontextEntry.get_text().strip()
- type=self.fcontextTypeEntry.get_text().strip()
- mls=self.fcontextMLSEntry.get_text().strip()
- list_model=self.fcontextFileTypeCombo.get_model()
+ ftype = ["", "--", "-d", "-c", "-b", "-s", "-l", "-p"]
+ fspec = self.fcontextEntry.get_text().strip()
+ type = self.fcontextTypeEntry.get_text().strip()
+ mls = self.fcontextMLSEntry.get_text().strip()
+ list_model = self.fcontextFileTypeCombo.get_model()
active = self.fcontextFileTypeCombo.get_active()
self.wait()
(rc, out) = commands.getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, ftype[active], fspec))
@@ -198,18 +201,18 @@ class fcontextPage(semanagePage):
self.error(out)
return False
- iter=self.store.append()
+ iter = self.store.append()
self.store.set_value(iter, SPEC_COL, fspec)
self.store.set_value(iter, FTYPE_COL, ftype)
self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls))
def modify(self):
- fspec=self.fcontextEntry.get_text().strip()
- type=self.fcontextTypeEntry.get_text().strip()
- mls=self.fcontextMLSEntry.get_text().strip()
- list_model=self.fcontextFileTypeCombo.get_model()
+ fspec = self.fcontextEntry.get_text().strip()
+ type = self.fcontextTypeEntry.get_text().strip()
+ mls = self.fcontextMLSEntry.get_text().strip()
+ list_model = self.fcontextFileTypeCombo.get_model()
iter = self.fcontextFileTypeCombo.get_active_iter()
- ftype=list_model.get_value(iter,0)
+ ftype = list_model.get_value(iter, 0)
self.wait()
(rc, out) = commands.getstatusoutput("semanage fcontext -m -t %s -r %s -f '%s' '%s'" % (type, mls, ftype, fspec))
self.ready()
diff --git a/policycoreutils/gui/html_util.py b/policycoreutils/gui/html_util.py
index 68eed762..5a596bc9 100644
--- a/policycoreutils/gui/html_util.py
+++ b/policycoreutils/gui/html_util.py
@@ -34,7 +34,9 @@ import StringIO
#------------------------------------------------------------------------------
+
class TextWriter(Formatter.DumbWriter):
+
def __init__(self, file=None, maxcol=80, indent_width=4):
Formatter.DumbWriter.__init__(self, file, maxcol)
self.indent_level = 0
@@ -58,7 +60,8 @@ class TextWriter(Formatter.DumbWriter):
self.send_literal_data(' ' * offset + data)
def send_flowing_data(self, data):
- if not data: return
+ if not data:
+ return
atbreak = self.atbreak or data[0] in string.whitespace
col = self.col
maxcol = self.maxcol
@@ -81,6 +84,7 @@ class TextWriter(Formatter.DumbWriter):
self.col = col
self.atbreak = data[-1] in string.whitespace
+
class HTMLParserAnchor(htmllib.HTMLParser):
def __init__(self, formatter, verbose=0):
@@ -96,9 +100,11 @@ class HTMLParserAnchor(htmllib.HTMLParser):
#------------------------------------------------------------------------------
+
def escape_html(s):
- if s is None: return None
- s = s.replace("&", "&amp;") # Must be done first!
+ if s is None:
+ return None
+ s = s.replace("&", "&amp;") # Must be done first!
s = s.replace("<", "&lt;")
s = s.replace(">", "&gt;")
s = s.replace("'", "&apos;")
@@ -107,16 +113,18 @@ def escape_html(s):
def unescape_html(s):
- if s is None: return None
+ if s is None:
+ return None
if '&' not in s:
return s
s = s.replace("&lt;", "<")
s = s.replace("&gt;", ">")
s = s.replace("&apos;", "'")
s = s.replace("&quot;", '"')
- s = s.replace("&amp;", "&") # Must be last
+ s = s.replace("&amp;", "&") # Must be last
return s
+
def html_to_text(html, maxcol=80):
try:
buffer = StringIO.StringIO()
@@ -131,6 +139,7 @@ def html_to_text(html, maxcol=80):
log_program.error('cannot convert html to text: %s' % e)
return None
+
def html_document(*body_components):
'''Wrap the body components in a HTML document structure with a valid header.
Accepts a variable number of arguments of of which canb be:
diff --git a/policycoreutils/gui/loginsPage.py b/policycoreutils/gui/loginsPage.py
index ec29fd9b..982e2528 100644
--- a/policycoreutils/gui/loginsPage.py
+++ b/policycoreutils/gui/loginsPage.py
@@ -24,12 +24,12 @@ import gobject
import sys
import commands
import seobject
-from semanagePage import *;
+from semanagePage import *
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -37,26 +37,28 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class loginsPage(semanagePage):
+
def __init__(self, xml):
self.firstTime = False
semanagePage.__init__(self, xml, "logins", _("User Mapping"))
self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.view.set_model(self.store)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text=0)
col.set_sort_column_id(0)
col.set_resizable(True)
self.view.append_column(col)
- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 1)
+ col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=1)
col.set_resizable(True)
self.view.append_column(col)
- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 2)
+ col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=2)
col.set_resizable(True)
self.view.append_column(col)
self.load()
@@ -64,8 +66,8 @@ class loginsPage(semanagePage):
self.loginsSelinuxUserCombo = xml.get_widget("loginsSelinuxUserCombo")
self.loginsMLSEntry = xml.get_widget("loginsMLSEntry")
- def load(self, filter = ""):
- self.filter=filter
+ def load(self, filter=""):
+ self.filter = filter
self.login = seobject.loginRecords()
dict = self.login.get_all(0)
keys = dict.keys()
@@ -79,7 +81,7 @@ class loginsPage(semanagePage):
self.store.set_value(iter, 0, k)
self.store.set_value(iter, 1, dict[k][0])
self.store.set_value(iter, 2, range)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def __dialogSetup(self):
if self.firstTime == True:
@@ -99,7 +101,7 @@ class loginsPage(semanagePage):
self.loginsSelinuxUserCombo.append_text(k)
iter = liststore.get_iter_first()
- while liststore.get_value(iter,0) != "user_u":
+ while liststore.get_value(iter, 0) != "user_u":
iter = liststore.iter_next(iter)
self.loginsSelinuxUserCombo.set_active_iter(iter)
@@ -113,12 +115,11 @@ class loginsPage(semanagePage):
seuser = store.get_value(iter, 1)
liststore = self.loginsSelinuxUserCombo.get_model()
iter = liststore.get_iter_first()
- while iter != None and liststore.get_value(iter,0) != seuser:
+ while iter != None and liststore.get_value(iter, 0) != seuser:
iter = liststore.iter_next(iter)
if iter != None:
self.loginsSelinuxUserCombo.set_active_iter(iter)
-
def dialogClear(self):
self.__dialogSetup()
self.loginsNameEntry.set_text("")
@@ -128,7 +129,7 @@ class loginsPage(semanagePage):
def delete(self):
store, iter = self.view.get_selection().get_selected()
try:
- login=store.get_value(iter, 0)
+ login = store.get_value(iter, 0)
if login == "root" or login == "__default__":
raise ValueError(_("Login '%s' is required") % login)
@@ -139,18 +140,18 @@ class loginsPage(semanagePage):
self.error(out)
return False
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
except ValueError, e:
self.error(e.args[0])
def add(self):
- target=self.loginsNameEntry.get_text().strip()
- serange=self.loginsMLSEntry.get_text().strip()
+ target = self.loginsNameEntry.get_text().strip()
+ serange = self.loginsMLSEntry.get_text().strip()
if serange == "":
- serange="s0"
- list_model=self.loginsSelinuxUserCombo.get_model()
+ serange = "s0"
+ list_model = self.loginsSelinuxUserCombo.get_model()
iter = self.loginsSelinuxUserCombo.get_active_iter()
- seuser = list_model.get_value(iter,0)
+ seuser = list_model.get_value(iter, 0)
self.wait()
(rc, out) = commands.getstatusoutput("semanage login -a -s %s -r %s %s" % (seuser, serange, target))
self.ready()
@@ -164,13 +165,13 @@ class loginsPage(semanagePage):
self.store.set_value(iter, 2, seobject.translate(serange))
def modify(self):
- target=self.loginsNameEntry.get_text().strip()
- serange=self.loginsMLSEntry.get_text().strip()
+ target = self.loginsNameEntry.get_text().strip()
+ serange = self.loginsMLSEntry.get_text().strip()
if serange == "":
serange = "s0"
list_model = self.loginsSelinuxUserCombo.get_model()
iter = self.loginsSelinuxUserCombo.get_active_iter()
- seuser=list_model.get_value(iter,0)
+ seuser = list_model.get_value(iter, 0)
self.wait()
(rc, out) = commands.getstatusoutput("semanage login -m -s %s -r %s %s" % (seuser, serange, target))
self.ready()
diff --git a/policycoreutils/gui/mappingsPage.py b/policycoreutils/gui/mappingsPage.py
index fd0ea75b..1429bf7d 100644
--- a/policycoreutils/gui/mappingsPage.py
+++ b/policycoreutils/gui/mappingsPage.py
@@ -27,7 +27,7 @@ import seobject
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -35,12 +35,14 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class loginsPage:
+
def __init__(self, xml):
self.xml = xml
self.view = xml.get_widget("mappingsView")
diff --git a/policycoreutils/gui/modulesPage.py b/policycoreutils/gui/modulesPage.py
index 9ff07666..3b83e455 100644
--- a/policycoreutils/gui/modulesPage.py
+++ b/policycoreutils/gui/modulesPage.py
@@ -25,13 +25,13 @@ import gobject
import sys
import seobject
import selinux
-from semanagePage import *;
+from semanagePage import *
from subprocess import Popen, PIPE
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -39,12 +39,14 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class modulesPage(semanagePage):
+
def __init__(self, xml):
semanagePage.__init__(self, xml, "modules", _("Policy Module"))
self.module_filter = xml.get_widget("modulesFilterEntry")
@@ -55,12 +57,12 @@ class modulesPage(semanagePage):
self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.view.set_model(self.store)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text=0)
col.set_sort_column_id(0)
col.set_resizable(True)
self.view.append_column(col)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text = 1)
+ col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text=1)
self.enable_audit_button = xml.get_widget("enableAuditButton")
self.enable_audit_button.connect("clicked", self.enable_audit)
self.new_button = xml.get_widget("newModuleButton")
@@ -68,15 +70,15 @@ class modulesPage(semanagePage):
col.set_sort_column_id(1)
col.set_resizable(True)
self.view.append_column(col)
- self.store.set_sort_func(1,self.sort_int, "")
+ self.store.set_sort_func(1, self.sort_int, "")
status, self.policy_type = selinux.selinux_getpolicytype()
self.load()
def sort_int(self, treemodel, iter1, iter2, user_data):
try:
- p1 = int(treemodel.get_value(iter1,1))
- p2 = int(treemodel.get_value(iter1,1))
+ p1 = int(treemodel.get_value(iter1, 1))
+ p2 = int(treemodel.get_value(iter1, 1))
if p1 > p2:
return 1
if p1 == p2:
@@ -86,7 +88,7 @@ class modulesPage(semanagePage):
return 0
def load(self, filter=""):
- self.filter=filter
+ self.filter = filter
self.store.clear()
try:
fd = Popen("semodule -l", shell=True, stdout=PIPE).stdout
@@ -101,8 +103,7 @@ class modulesPage(semanagePage):
self.store.set_value(iter, 1, ver.strip())
except:
pass
- self.view.get_selection().select_path ((0,))
-
+ self.view.get_selection().select_path((0,))
def new_module(self, args):
try:
@@ -121,7 +122,7 @@ class modulesPage(semanagePage):
self.error(output)
else:
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
except ValueError, e:
self.error(e.args[0])
@@ -131,10 +132,10 @@ class modulesPage(semanagePage):
try:
self.wait()
if self.audit_enabled:
- status, output =commands.getstatusoutput("semodule -DB")
+ status, output = commands.getstatusoutput("semodule -DB")
button.set_label(_("Disable Audit"))
else:
- status, output =commands.getstatusoutput("semodule -B")
+ status, output = commands.getstatusoutput("semodule -B")
button.set_label(_("Enable Audit"))
self.ready()
@@ -147,7 +148,7 @@ class modulesPage(semanagePage):
def disable_audit(self, button):
try:
self.wait()
- status, output =commands.getstatusoutput("semodule -B")
+ status, output = commands.getstatusoutput("semodule -B")
self.ready()
if status != 0:
self.error(output)
@@ -180,7 +181,7 @@ class modulesPage(semanagePage):
def add(self, file):
try:
self.wait()
- status, output =commands.getstatusoutput("semodule -i %s" % file)
+ status, output = commands.getstatusoutput("semodule -i %s" % file)
self.ready()
if status != 0:
self.error(output)
diff --git a/policycoreutils/gui/polgengui.py b/policycoreutils/gui/polgengui.py
index 0f0e564b..0a153c60 100644
--- a/policycoreutils/gui/polgengui.py
+++ b/policycoreutils/gui/polgengui.py
@@ -30,7 +30,7 @@ import gnome
import sys
try:
from sepolicy import generate
-except ValueError,e:
+except ValueError, e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
@@ -39,10 +39,11 @@ import commands
import re
+
def get_all_modules():
try:
all_modules = []
- rc, output=commands.getstatusoutput("semodule -l 2>/dev/null")
+ rc, output = commands.getstatusoutput("semodule -l 2>/dev/null")
if rc == 0:
l = output.split("\n")
for i in l:
@@ -56,7 +57,7 @@ def get_all_modules():
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -65,7 +66,7 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
@@ -78,6 +79,8 @@ sys.path.append('/usr/share/system-config-selinux')
sys.path.append('.')
# From John Hunter http://www.daa.com.au/pipermail/pygtk/2003-February/004454.html
+
+
def foreach(model, path, iter, selected):
selected.append(model.get_value(iter, 0))
@@ -85,13 +88,14 @@ def foreach(model, path, iter, selected):
## Pull in the Glade file
##
if os.access("polgen.glade", os.F_OK):
- xml = gtk.glade.XML ("polgen.glade", domain=PROGNAME)
+ xml = gtk.glade.XML("polgen.glade", domain=PROGNAME)
else:
- xml = gtk.glade.XML ("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME)
+ xml = gtk.glade.XML("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME)
FILE = 1
DIR = 2
+
class childWindow:
START_PAGE = 0
SELECT_TYPE_PAGE = 0
@@ -111,82 +115,82 @@ class childWindow:
def __init__(self):
self.xml = xml
- self.notebook = xml.get_widget ("notebook")
+ self.notebook = xml.get_widget("notebook")
self.label_dict = {}
self.tooltip_dict = {}
- label = xml.get_widget ("select_label")
+ label = xml.get_widget("select_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_user_roles_label")
+ label = xml.get_widget("select_user_roles_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_dir_label")
+ label = xml.get_widget("select_dir_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_domain_admin_label")
+ label = xml.get_widget("select_domain_admin_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_in_label")
+ label = xml.get_widget("select_in_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_out_label")
+ label = xml.get_widget("select_out_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_common_label")
+ label = xml.get_widget("select_common_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_manages_label")
+ label = xml.get_widget("select_manages_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("select_booleans_label")
+ label = xml.get_widget("select_booleans_label")
self.label_dict[label] = label.get_text()
- label = xml.get_widget ("existing_user_treeview")
+ label = xml.get_widget("existing_user_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("transition_treeview")
+ label = xml.get_widget("transition_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_tcp_all_checkbutton")
+ label = xml.get_widget("in_tcp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_tcp_reserved_checkbutton")
+ label = xml.get_widget("in_tcp_reserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_tcp_unreserved_checkbutton")
+ label = xml.get_widget("in_tcp_unreserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_tcp_entry")
+ label = xml.get_widget("in_tcp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_udp_all_checkbutton")
+ label = xml.get_widget("in_udp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_udp_reserved_checkbutton")
+ label = xml.get_widget("in_udp_reserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_udp_unreserved_checkbutton")
+ label = xml.get_widget("in_udp_unreserved_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("in_udp_entry")
+ label = xml.get_widget("in_udp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("out_tcp_entry")
+ label = xml.get_widget("out_tcp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("out_udp_entry")
+ label = xml.get_widget("out_udp_entry")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("out_tcp_all_checkbutton")
+ label = xml.get_widget("out_tcp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("out_udp_all_checkbutton")
+ label = xml.get_widget("out_udp_all_checkbutton")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("boolean_treeview")
+ label = xml.get_widget("boolean_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
- label = xml.get_widget ("write_treeview")
+ label = xml.get_widget("write_treeview")
self.tooltip_dict[label] = label.get_tooltip_text()
try:
@@ -201,7 +205,7 @@ class childWindow:
self.all_users = []
self.error(str(e))
- self.name=""
+ self.name = ""
xml.signal_connect("on_delete_clicked", self.delete)
xml.signal_connect("on_delete_boolean_clicked", self.delete_boolean)
xml.signal_connect("on_exec_select_clicked", self.exec_select)
@@ -210,68 +214,67 @@ class childWindow:
xml.signal_connect("on_add_boolean_clicked", self.add_boolean)
xml.signal_connect("on_add_dir_clicked", self.add_dir)
xml.signal_connect("on_about_clicked", self.on_about_clicked)
- xml.get_widget ("cancel_button").connect("clicked",self.quit)
- self.forward_button = xml.get_widget ("forward_button")
- self.forward_button.connect("clicked",self.forward)
- self.back_button = xml.get_widget ("back_button")
- self.back_button.connect("clicked",self.back)
+ xml.get_widget("cancel_button").connect("clicked", self.quit)
+ self.forward_button = xml.get_widget("forward_button")
+ self.forward_button.connect("clicked", self.forward)
+ self.back_button = xml.get_widget("back_button")
+ self.back_button.connect("clicked", self.back)
- self.boolean_dialog = xml.get_widget ("boolean_dialog")
- self.boolean_name_entry = xml.get_widget ("boolean_name_entry")
- self.boolean_description_entry = xml.get_widget ("boolean_description_entry")
+ self.boolean_dialog = xml.get_widget("boolean_dialog")
+ self.boolean_name_entry = xml.get_widget("boolean_name_entry")
+ self.boolean_description_entry = xml.get_widget("boolean_description_entry")
- self.pages={}
+ self.pages = {}
for i in generate.USERS:
- self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
- self.pages[generate.RUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
- self.pages[generate.LUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
- self.pages[generate.SANDBOX] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
- self.pages[generate.EUSER] = [ self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
+ self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+ self.pages[generate.RUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+ self.pages[generate.LUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+ self.pages[generate.SANDBOX] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+ self.pages[generate.EUSER] = [self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
for i in generate.APPLICATIONS:
- self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
- self.pages[generate.USER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
+ self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+ self.pages[generate.USER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
self.current_page = 0
self.back_button.set_sensitive(0)
self.network_buttons = {}
- self.in_tcp_all_checkbutton = xml.get_widget ("in_tcp_all_checkbutton")
- self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton")
- self.in_tcp_unreserved_checkbutton = xml.get_widget ("in_tcp_unreserved_checkbutton")
+ self.in_tcp_all_checkbutton = xml.get_widget("in_tcp_all_checkbutton")
+ self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
+ self.in_tcp_unreserved_checkbutton = xml.get_widget("in_tcp_unreserved_checkbutton")
self.in_tcp_entry = self.xml.get_widget("in_tcp_entry")
- self.network_buttons[self.in_tcp_all_checkbutton] = [ self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry ]
+ self.network_buttons[self.in_tcp_all_checkbutton] = [self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry]
-
- self.out_tcp_all_checkbutton = xml.get_widget ("out_tcp_all_checkbutton")
- self.out_tcp_reserved_checkbutton = xml.get_widget ("out_tcp_reserved_checkbutton")
- self.out_tcp_unreserved_checkbutton = xml.get_widget ("out_tcp_unreserved_checkbutton")
+ self.out_tcp_all_checkbutton = xml.get_widget("out_tcp_all_checkbutton")
+ self.out_tcp_reserved_checkbutton = xml.get_widget("out_tcp_reserved_checkbutton")
+ self.out_tcp_unreserved_checkbutton = xml.get_widget("out_tcp_unreserved_checkbutton")
self.out_tcp_entry = self.xml.get_widget("out_tcp_entry")
- self.network_buttons[self.out_tcp_all_checkbutton] = [ self.out_tcp_entry ]
+ self.network_buttons[self.out_tcp_all_checkbutton] = [self.out_tcp_entry]
- self.in_udp_all_checkbutton = xml.get_widget ("in_udp_all_checkbutton")
- self.in_udp_reserved_checkbutton = xml.get_widget ("in_udp_reserved_checkbutton")
- self.in_udp_unreserved_checkbutton = xml.get_widget ("in_udp_unreserved_checkbutton")
+ self.in_udp_all_checkbutton = xml.get_widget("in_udp_all_checkbutton")
+ self.in_udp_reserved_checkbutton = xml.get_widget("in_udp_reserved_checkbutton")
+ self.in_udp_unreserved_checkbutton = xml.get_widget("in_udp_unreserved_checkbutton")
self.in_udp_entry = self.xml.get_widget("in_udp_entry")
- self.network_buttons[self.in_udp_all_checkbutton] = [ self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry ]
+ self.network_buttons[self.in_udp_all_checkbutton] = [self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry]
- self.out_udp_all_checkbutton = xml.get_widget ("out_udp_all_checkbutton")
+ self.out_udp_all_checkbutton = xml.get_widget("out_udp_all_checkbutton")
self.out_udp_entry = self.xml.get_widget("out_udp_entry")
- self.network_buttons[self.out_udp_all_checkbutton] = [ self.out_udp_entry ]
+ self.network_buttons[self.out_udp_all_checkbutton] = [self.out_udp_entry]
for b in self.network_buttons.keys():
- b.connect("clicked",self.network_all_clicked)
+ b.connect("clicked", self.network_all_clicked)
self.boolean_treeview = self.xml.get_widget("boolean_treeview")
- self.boolean_store = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING)
+ self.boolean_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.boolean_treeview.set_model(self.boolean_store)
self.boolean_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=0)
self.boolean_treeview.append_column(col)
- col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text = 1)
+ col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=1)
self.boolean_treeview.append_column(col)
self.role_treeview = self.xml.get_widget("role_treeview")
@@ -279,28 +282,28 @@ class childWindow:
self.role_treeview.set_model(self.role_store)
self.role_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.role_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text=0)
self.role_treeview.append_column(col)
self.existing_user_treeview = self.xml.get_widget("existing_user_treeview")
self.existing_user_store = gtk.ListStore(gobject.TYPE_STRING)
self.existing_user_treeview.set_model(self.existing_user_store)
self.existing_user_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text=0)
self.existing_user_treeview.append_column(col)
for i in self.all_roles:
iter = self.role_store.append()
self.role_store.set_value(iter, 0, i[:-2])
- self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton")
+ self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
self.transition_treeview = self.xml.get_widget("transition_treeview")
self.transition_store = gtk.ListStore(gobject.TYPE_STRING)
self.transition_treeview.set_model(self.transition_store)
self.transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
self.transition_treeview.append_column(col)
self.user_transition_treeview = self.xml.get_widget("user_transition_treeview")
@@ -308,7 +311,7 @@ class childWindow:
self.user_transition_treeview.set_model(self.user_transition_store)
self.user_transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.user_transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
self.user_transition_treeview.append_column(col)
for i in self.all_users:
@@ -322,7 +325,7 @@ class childWindow:
self.admin_treeview.set_model(self.admin_store)
self.admin_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.admin_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
self.admin_treeview.append_column(col)
try:
@@ -333,7 +336,7 @@ class childWindow:
for a in sepolicy.interface.get_admin():
iter = self.admin_store.append()
self.admin_store.set_value(iter, 0, a)
- except ValueError,e:
+ except ValueError, e:
self.error(e.message)
def confine_application(self):
@@ -367,19 +370,19 @@ class childWindow:
if self.pages[type][self.current_page] == self.SELECT_DIR_PAGE:
outputdir = self.output_entry.get_text()
if not os.path.isdir(outputdir):
- self.error(_("%s must be a directory") % outputdir )
+ self.error(_("%s must be a directory") % outputdir)
return False
if self.pages[type][self.current_page] == self.FINISH_PAGE:
self.generate_policy()
- self.xml.get_widget ("cancel_button").set_label(gtk.STOCK_CLOSE)
+ self.xml.get_widget("cancel_button").set_label(gtk.STOCK_CLOSE)
else:
self.current_page = self.current_page + 1
self.notebook.set_current_page(self.pages[type][self.current_page])
if self.pages[type][self.current_page] == self.FINISH_PAGE:
self.forward_button.set_label(gtk.STOCK_APPLY)
- def back(self,arg):
+ def back(self, arg):
type = self.get_type()
if self.pages[type][self.current_page] == self.FINISH_PAGE:
self.forward_button.set_label(gtk.STOCK_GO_FORWARD)
@@ -394,7 +397,7 @@ class childWindow:
for b in self.network_buttons[button]:
b.set_sensitive(not active)
- def verify(self, message, title="" ):
+ def verify(self, message, title=""):
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
gtk.BUTTONS_YES_NO,
message)
@@ -461,12 +464,12 @@ class childWindow:
def generate_policy(self, *args):
outputdir = self.output_entry.get_text()
try:
- my_policy=generate.policy(self.get_name(), self.get_type())
+ my_policy = generate.policy(self.get_name(), self.get_type())
- iter= self.boolean_store.get_iter_first()
+ iter = self.boolean_store.get_iter_first()
while(iter):
my_policy.add_boolean(self.boolean_store.get_value(iter, 0), self.boolean_store.get_value(iter, 1))
- iter= self.boolean_store.iter_next(iter)
+ iter = self.boolean_store.iter_next(iter)
if self.get_type() in generate.APPLICATIONS:
my_policy.set_program(self.exec_entry.get_text())
@@ -509,13 +512,13 @@ class childWindow:
my_policy.set_out_tcp(self.out_tcp_all_checkbutton.get_active(), self.out_tcp_entry.get_text())
my_policy.set_out_udp(self.out_udp_all_checkbutton.get_active(), self.out_udp_entry.get_text())
- iter= self.store.get_iter_first()
+ iter = self.store.get_iter_first()
while(iter):
if self.store.get_value(iter, 1) == FILE:
my_policy.add_file(self.store.get_value(iter, 0))
else:
my_policy.add_dir(self.store.get_value(iter, 0))
- iter= self.store.iter_next(iter)
+ iter = self.store.iter_next(iter)
self.info(my_policy.generate(outputdir))
return False
@@ -526,15 +529,15 @@ class childWindow:
store, iter = self.view.get_selection().get_selected()
if iter != None:
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def delete_boolean(self, args):
store, iter = self.boolean_treeview.get_selection().get_selected()
if iter != None:
store.remove(iter)
- self.boolean_treeview.get_selection().select_path ((0,))
+ self.boolean_treeview.get_selection().select_path((0,))
- def add_boolean(self,type):
+ def add_boolean(self, type):
self.boolean_name_entry.set_text("")
self.boolean_description_entry.set_text("")
rc = self.boolean_dialog.run()
@@ -545,7 +548,7 @@ class childWindow:
self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text())
self.boolean_store.set_value(iter, 1, self.boolean_description_entry.get_text())
- def __add(self,type):
+ def __add(self, type):
rc = self.file_dialog.run()
self.file_dialog.hide()
if rc == gtk.RESPONSE_CANCEL:
@@ -592,9 +595,9 @@ class childWindow:
self.__add(DIR)
def on_about_clicked(self, args):
- dlg = xml.get_widget ("about_dialog")
- dlg.run ()
- dlg.hide ()
+ dlg = xml.get_widget("about_dialog")
+ dlg.run()
+ dlg.hide()
def quit(self, args):
gtk.main_quit()
@@ -605,15 +608,15 @@ class childWindow:
self.druid = self.xml.get_widget("druid")
self.type = 0
self.name_entry = self.xml.get_widget("name_entry")
- self.name_entry.connect("insert_text",self.on_name_entry_changed)
- self.name_entry.connect("focus_out_event",self.on_focus_out_event)
+ self.name_entry.connect("insert_text", self.on_name_entry_changed)
+ self.name_entry.connect("focus_out_event", self.on_focus_out_event)
self.exec_entry = self.xml.get_widget("exec_entry")
self.exec_button = self.xml.get_widget("exec_button")
self.init_script_entry = self.xml.get_widget("init_script_entry")
self.init_script_button = self.xml.get_widget("init_script_button")
self.output_entry = self.xml.get_widget("output_entry")
self.output_entry.set_text(os.getcwd())
- self.xml.get_widget("output_button").connect("clicked",self.output_button_clicked)
+ self.xml.get_widget("output_button").connect("clicked", self.output_button_clicked)
self.xwindows_user_radiobutton = self.xml.get_widget("xwindows_user_radiobutton")
self.terminal_user_radiobutton = self.xml.get_widget("terminal_user_radiobutton")
@@ -641,10 +644,10 @@ class childWindow:
self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
self.view.set_model(self.store)
- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
col.set_resizable(True)
self.view.append_column(col)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def output_button_clicked(self, *args):
self.file_dialog.set_title(_("Select directory to generate policy files in"))
@@ -712,7 +715,7 @@ class childWindow:
return True
def on_name_page_next(self, *args):
- name=self.name_entry.get_text()
+ name = self.name_entry.get_text()
if not name.isalnum():
self.error(_("You must add a name made up of letters and numbers and containing no spaces."))
return True
@@ -730,7 +733,7 @@ class childWindow:
if exe == "":
self.error(_("You must enter a executable"))
return True
- policy=generate.policy(name, self.get_type())
+ policy = generate.policy(name, self.get_type())
policy.set_program(exe)
policy.gen_writeable()
policy.gen_symbols()
@@ -762,7 +765,7 @@ class childWindow:
gtk.main()
if __name__ == "__main__":
- signal.signal (signal.SIGINT, signal.SIG_DFL)
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
app = childWindow()
app.stand_alone()
diff --git a/policycoreutils/gui/portsPage.py b/policycoreutils/gui/portsPage.py
index bfb4e36a..8e74ac0d 100644
--- a/policycoreutils/gui/portsPage.py
+++ b/policycoreutils/gui/portsPage.py
@@ -24,7 +24,7 @@ import gobject
import sys
import seobject
import commands
-from semanagePage import *;
+from semanagePage import *
##
## I18N
@@ -41,12 +41,14 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class portsPage(semanagePage):
+
def __init__(self, xml):
semanagePage.__init__(self, xml, "ports", _("Network Port"))
xml.signal_connect("on_group_clicked", self.on_group_clicked)
@@ -69,7 +71,7 @@ class portsPage(semanagePage):
self.load()
def filter_changed(self, *arg):
- filter = arg[0].get_text()
+ filter = arg[0].get_text()
if filter != self.filter:
if self.edit:
self.load(filter)
@@ -77,37 +79,37 @@ class portsPage(semanagePage):
self.group_load(filter)
def init_store(self):
- self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING , gobject.TYPE_STRING)
+ self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.view.set_model(self.store)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
self.view.set_search_equal_func(self.search)
- col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text = TYPE_COL)
+ col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL)
col.set_sort_column_id(TYPE_COL)
col.set_resizable(True)
self.view.append_column(col)
self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text = PROTOCOL_COL)
+ col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL)
col.set_sort_column_id(PROTOCOL_COL)
col.set_resizable(True)
self.view.append_column(col)
- self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text = MLS_COL)
+ self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL)
self.mls_col.set_resizable(True)
self.mls_col.set_sort_column_id(MLS_COL)
self.view.append_column(self.mls_col)
- col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text = PORT_COL)
+ col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL)
col.set_sort_column_id(PORT_COL)
col.set_resizable(True)
self.view.append_column(col)
- self.store.set_sort_func(PORT_COL,self.sort_int, "")
+ self.store.set_sort_func(PORT_COL, self.sort_int, "")
def sort_int(self, treemodel, iter1, iter2, user_data):
try:
- p1 = int(treemodel.get_value(iter1,PORT_COL).split('-')[0])
- p2 = int(treemodel.get_value(iter2,PORT_COL).split('-')[0])
+ p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0])
+ p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0])
if p1 > p2:
return 1
if p1 == p2:
@@ -116,8 +118,8 @@ class portsPage(semanagePage):
except:
return 0
- def load(self,filter = ""):
- self.filter=filter
+ def load(self, filter=""):
+ self.filter = filter
self.port = seobject.portRecords()
dict = self.port.get_all(self.local)
keys = dict.keys()
@@ -135,10 +137,10 @@ class portsPage(semanagePage):
self.store.set_value(iter, TYPE_COL, dict[k][0])
self.store.set_value(iter, PROTOCOL_COL, k[2])
self.store.set_value(iter, MLS_COL, dict[k][1])
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
- def group_load(self, filter = ""):
- self.filter=filter
+ def group_load(self, filter=""):
+ self.filter = filter
self.port = seobject.portRecords()
dict = self.port.get_all_by_type(self.local)
keys = dict.keys()
@@ -146,14 +148,14 @@ class portsPage(semanagePage):
self.store.clear()
for k in keys:
ports_string = ", ".join(dict[k])
- if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter) ):
+ if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)):
continue
iter = self.store.append()
self.store.set_value(iter, TYPE_COL, k[0])
self.store.set_value(iter, PROTOCOL_COL, k[1])
self.store.set_value(iter, PORT_COL, ports_string)
self.store.set_value(iter, MLS_COL, "")
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def propertiesDialog(self):
if self.edit:
@@ -169,7 +171,7 @@ class portsPage(semanagePage):
protocol = store.get_value(iter, PROTOCOL_COL)
liststore = self.ports_protocol_combo.get_model()
iter = liststore.get_iter_first()
- while iter != None and liststore.get_value(iter,0) != protocol:
+ while iter != None and liststore.get_value(iter, 0) != protocol:
iter = liststore.iter_next(iter)
if iter != None:
self.ports_protocol_combo.set_active_iter(iter)
@@ -192,7 +194,7 @@ class portsPage(semanagePage):
if rc != 0:
return self.error(out)
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
except ValueError, e:
self.error(e.args[0])
@@ -204,11 +206,11 @@ class portsPage(semanagePage):
port_number = "1"
for i in port_number.split("-"):
if not i.isdigit():
- self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number )
+ self.error(_("Port number \"%s\" is not valid. 0 < PORT_NUMBER < 65536 ") % port_number)
return False
list_model = self.ports_protocol_combo.get_model()
iter = self.ports_protocol_combo.get_active_iter()
- protocol = list_model.get_value(iter,0)
+ protocol = list_model.get_value(iter, 0)
self.wait()
(rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
self.ready()
@@ -228,7 +230,7 @@ class portsPage(semanagePage):
port_number = self.ports_number_entry.get_text().strip()
list_model = self.ports_protocol_combo.get_model()
iter = self.ports_protocol_combo.get_active_iter()
- protocol = list_model.get_value(iter,0)
+ protocol = list_model.get_value(iter, 0)
self.wait()
(rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
self.ready()
diff --git a/policycoreutils/gui/semanagePage.py b/policycoreutils/gui/semanagePage.py
index 3a0e4789..5d7f2cfc 100644
--- a/policycoreutils/gui/semanagePage.py
+++ b/policycoreutils/gui/semanagePage.py
@@ -27,7 +27,7 @@ import seobject
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -35,16 +35,19 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
def idle_func():
while gtk.events_pending():
gtk.main_iteration()
+
class semanagePage:
+
def __init__(self, xml, name, description):
self.xml = xml
self.window = self.xml.get_widget("mainWindow").get_root_window()
@@ -54,13 +57,13 @@ class semanagePage:
self.local = False
self.view = xml.get_widget("%sView" % name)
self.dialog = xml.get_widget("%sDialog" % name)
- self.filter_entry = xml.get_widget("%sFilterEntry" % name )
+ self.filter_entry = xml.get_widget("%sFilterEntry" % name)
self.filter_entry.connect("focus_out_event", self.filter_changed)
self.filter_entry.connect("activate", self.filter_changed)
self.view.connect("row_activated", self.rowActivated)
self.view.get_selection().connect("changed", self.itemSelected)
- self.description = description;
+ self.description = description
def wait(self):
self.window.set_cursor(self.busy_cursor)
@@ -77,21 +80,21 @@ class semanagePage:
return
def filter_changed(self, *arg):
- filter = arg[0].get_text()
+ filter = arg[0].get_text()
if filter != self.filter:
self.load(filter)
def search(self, model, col, key, i):
sort_col = self.store.get_sort_column_id()[0]
- val = model.get_value(i,sort_col)
+ val = model.get_value(i, sort_col)
if val.lower().startswith(key.lower()):
return False
return True
def match(self, target, filter):
try:
- f=filter.lower()
- t=target.lower()
+ f = filter.lower()
+ t = target.lower()
if t.find(f) >= 0:
return True
except:
@@ -101,7 +104,7 @@ class semanagePage:
def rowActivated(self, view, row, Column):
self.propertiesDialog()
- def verify(self, message, title="" ):
+ def verify(self, message, title=""):
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
gtk.BUTTONS_YES_NO,
message)
@@ -134,11 +137,11 @@ class semanagePage:
self.dialog.set_title(_("Add %s" % self.description))
self.dialog.set_position(gtk.WIN_POS_MOUSE)
- while self.dialog.run() == gtk.RESPONSE_OK:
+ while self.dialog.run() == gtk.RESPONSE_OK:
try:
if self.add() == False:
continue
- break;
+ break
except ValueError, e:
self.error(e.args[0])
self.dialog.hide()
@@ -147,11 +150,11 @@ class semanagePage:
self.dialogInit()
self.dialog.set_title(_("Modify %s" % self.description))
self.dialog.set_position(gtk.WIN_POS_MOUSE)
- while self.dialog.run() == gtk.RESPONSE_OK:
+ while self.dialog.run() == gtk.RESPONSE_OK:
try:
if self.modify() == False:
continue
- break;
+ break
except ValueError, e:
self.error(e.args[0])
self.dialog.hide()
diff --git a/policycoreutils/gui/statusPage.py b/policycoreutils/gui/statusPage.py
index 02685f28..991d8f3e 100644
--- a/policycoreutils/gui/statusPage.py
+++ b/policycoreutils/gui/statusPage.py
@@ -31,7 +31,7 @@ import commands
ENFORCING = 1
PERMISSIVE = 0
DISABLED = -1
-modearray = ( "disabled", "permissive", "enforcing" )
+modearray = ("disabled", "permissive", "enforcing")
SELINUXDIR = "/etc/selinux/"
RELABELFILE = "/.autorelabel"
@@ -39,7 +39,7 @@ RELABELFILE = "/.autorelabel"
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -50,7 +50,9 @@ except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class statusPage:
+
def __init__(self, xml):
self.xml = xml
self.needRelabel = False
@@ -66,15 +68,15 @@ class statusPage:
self.relabel_checkbutton.set_active(self.is_relabel())
self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle)
if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE:
- self.currentOptionMenu.append_text(_("Permissive"))
- self.currentOptionMenu.append_text(_("Enforcing"))
- self.currentOptionMenu.set_active(self.get_current_mode())
- self.currentOptionMenu.connect("changed", self.set_current_mode)
- self.currentOptionMenu.set_sensitive(True)
+ self.currentOptionMenu.append_text(_("Permissive"))
+ self.currentOptionMenu.append_text(_("Enforcing"))
+ self.currentOptionMenu.set_active(self.get_current_mode())
+ self.currentOptionMenu.connect("changed", self.set_current_mode)
+ self.currentOptionMenu.set_sensitive(True)
else:
- self.currentOptionMenu.append_text(_("Disabled"))
- self.currentOptionMenu.set_active(0)
- self.currentOptionMenu.set_sensitive(False)
+ self.currentOptionMenu.append_text(_("Disabled"))
+ self.currentOptionMenu.set_active(0)
+ self.currentOptionMenu.set_sensitive(False)
if self.read_selinux_config() == None:
self.selinuxsupport = False
@@ -102,15 +104,15 @@ class statusPage:
else:
return DISABLED
- def set_current_mode(self,menu):
+ def set_current_mode(self, menu):
selinux.security_setenforce(menu.get_active() == 1)
def is_relabel(self):
return os.access(RELABELFILE, os.F_OK) != 0
- def on_relabel_toggle(self,button):
+ def on_relabel_toggle(self, button):
if button.get_active():
- fd = open(RELABELFILE,"w")
+ fd = open(RELABELFILE, "w")
fd.close()
else:
if os.access(RELABELFILE, os.F_OK) != 0:
@@ -136,7 +138,7 @@ class statusPage:
self.relabel_checkbutton.set_active(True)
- self.write_selinux_config(modearray[enabled], type )
+ self.write_selinux_config(modearray[enabled], type)
self.typeHistory = menu.get_active()
def enabled_changed(self, combo):
@@ -154,11 +156,11 @@ class statusPage:
return None
self.relabel_checkbutton.set_active(True)
- self.write_selinux_config(modearray[enabled], type )
+ self.write_selinux_config(modearray[enabled], type)
self.enabled = enabled
def write_selinux_config(self, enforcing, type):
- path = selinux.selinux_path() + "config"
+ path = selinux.selinux_path() + "config"
backup_path = path + ".bck"
fd = open(path)
lines = fd.readlines()
@@ -183,7 +185,7 @@ class statusPage:
self.initEnabled = False
pass
self.enabled = self.initEnabled
- self.enabledOptionMenu.set_active(self.enabled + 1 )
+ self.enabledOptionMenu.set_active(self.enabled + 1)
self.types = []
@@ -191,12 +193,12 @@ class statusPage:
current = n
for i in os.listdir(SELINUXDIR):
- if os.path.isdir(SELINUXDIR+i) and os.path.isdir(SELINUXDIR+i+"/policy"):
+ if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"):
self.types.append(i)
self.selinuxTypeOptionMenu.append_text(i)
if i == self.initialtype:
current = n
- n = n+1
+ n = n + 1
self.selinuxTypeOptionMenu.set_active(current)
self.typeHistory = current
diff --git a/policycoreutils/gui/system-config-selinux.py b/policycoreutils/gui/system-config-selinux.py
index bc3027eb..7d342d0b 100644
--- a/policycoreutils/gui/system-config-selinux.py
+++ b/policycoreutils/gui/system-config-selinux.py
@@ -28,7 +28,7 @@ try:
except RuntimeError, e:
print "system-config-selinux:", e
print "This is a graphical application and requires DISPLAY to be set."
- sys.exit (1)
+ sys.exit(1)
import gtk.glade
import os
@@ -46,7 +46,7 @@ import selinux
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -55,7 +55,7 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
@@ -67,18 +67,19 @@ version = "1.0"
sys.path.append('/usr/share/system-config-selinux')
-
##
## Pull in the Glade file
##
if os.access("system-config-selinux.glade", os.F_OK):
- xml = gtk.glade.XML ("system-config-selinux.glade", domain=PROGNAME)
+ xml = gtk.glade.XML("system-config-selinux.glade", domain=PROGNAME)
else:
- xml = gtk.glade.XML ("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME)
+ xml = gtk.glade.XML("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME)
+
class childWindow:
+
def __init__(self):
- self.tabs=[]
+ self.tabs = []
self.xml = xml
xml.signal_connect("on_quit_activate", self.destroy)
xml.signal_connect("on_delete_clicked", self.delete)
@@ -93,8 +94,8 @@ class childWindow:
self.add_page(loginsPage.loginsPage(xml))
self.add_page(usersPage.usersPage(xml))
self.add_page(portsPage.portsPage(xml))
- self.add_page(modulesPage.modulesPage(xml)) # modules
- self.add_page(domainsPage.domainsPage(xml)) # domains
+ self.add_page(modulesPage.modulesPage(xml)) # modules
+ self.add_page(domainsPage.domainsPage(xml)) # domains
except ValueError, e:
self.error(e.message)
@@ -121,6 +122,7 @@ class childWindow:
def policy(self, args):
os.spawnl(os.P_NOWAIT, "/usr/share/system-config-selinux/semanagegui.py")
+
def logging(self, args):
os.spawnl(os.P_NOWAIT, "/usr/bin/seaudit")
@@ -137,9 +139,9 @@ class childWindow:
self.tabs[self.notebook.get_current_page()].on_local_clicked(button)
def on_about_activate(self, args):
- dlg = xml.get_widget ("aboutWindow")
- dlg.run ()
- dlg.hide ()
+ dlg = xml.get_widget("aboutWindow")
+ dlg.run()
+ dlg.hide()
def destroy(self, args):
gtk.main_quit()
@@ -158,7 +160,6 @@ class childWindow:
self.notebook.set_current_page(0)
self.use_menus(self.tabs[0].use_menus())
-
def setupScreen(self):
# Bring in widgets from glade file.
self.mainWindow = self.xml.get_widget("mainWindow")
@@ -167,14 +168,14 @@ class childWindow:
self.view.get_selection().connect("changed", self.itemSelected)
self.store = gtk.ListStore(gobject.TYPE_STRING)
self.view.set_model(self.store)
- col = gtk.TreeViewColumn("", gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
col.set_resizable(True)
self.view.append_column(col)
for page in self.tabs:
iter = self.store.append()
self.store.set_value(iter, 0, page.get_description())
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def stand_alone(self):
desktopName = _("Configue SELinux")
@@ -187,7 +188,7 @@ class childWindow:
gtk.main()
if __name__ == "__main__":
- signal.signal (signal.SIGINT, signal.SIG_DFL)
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
app = childWindow()
app.stand_alone()
diff --git a/policycoreutils/gui/usersPage.py b/policycoreutils/gui/usersPage.py
index 93804ac5..abf8d3bf 100644
--- a/policycoreutils/gui/usersPage.py
+++ b/policycoreutils/gui/usersPage.py
@@ -24,12 +24,12 @@ import gobject
import sys
import commands
import seobject
-from semanagePage import *;
+from semanagePage import *
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
@@ -39,7 +39,9 @@ except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
class usersPage(semanagePage):
+
def __init__(self, xml):
semanagePage.__init__(self, xml, "users", _("SELinux User"))
@@ -47,16 +49,16 @@ class usersPage(semanagePage):
self.view.set_model(self.store)
self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
- col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 0)
+ col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=0)
col.set_sort_column_id(0)
col.set_resizable(True)
self.view.append_column(col)
- col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 1)
+ col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=1)
col.set_resizable(True)
self.view.append_column(col)
- col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text = 2)
+ col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text=2)
col.set_resizable(True)
self.view.append_column(col)
@@ -65,8 +67,8 @@ class usersPage(semanagePage):
self.mlsRangeEntry = xml.get_widget("mlsRangeEntry")
self.selinuxRolesEntry = xml.get_widget("selinuxRolesEntry")
- def load(self, filter = ""):
- self.filter=filter
+ def load(self, filter=""):
+ self.filter = filter
self.user = seobject.seluserRecords()
dict = self.user.get_all()
keys = dict.keys()
@@ -81,11 +83,11 @@ class usersPage(semanagePage):
self.store.set_value(iter, 0, k)
self.store.set_value(iter, 1, range)
self.store.set_value(iter, 2, dict[k][3])
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
def delete(self):
if semanagePage.delete(self) == gtk.RESPONSE_NO:
- return None
+ return None
def dialogInit(self):
store, iter = self.view.get_selection().get_selected()
@@ -106,7 +108,7 @@ class usersPage(semanagePage):
roles = self.selinuxRolesEntry.get_text()
self.wait()
- (rc, out) = commands.getstatusoutput("semanage user -a -R '%s' -r %s %s" % (roles, range, user))
+ (rc, out) = commands.getstatusoutput("semanage user -a -R '%s' -r %s %s" % (roles, range, user))
self.ready()
if rc != 0:
self.error(out)
@@ -122,7 +124,7 @@ class usersPage(semanagePage):
roles = self.selinuxRolesEntry.get_text()
self.wait()
- (rc, out) = commands.getstatusoutput("semanage user -m -R '%s' -r %s %s" % (roles, range, user))
+ (rc, out) = commands.getstatusoutput("semanage user -m -R '%s' -r %s %s" % (roles, range, user))
self.ready()
if rc != 0:
@@ -133,17 +135,17 @@ class usersPage(semanagePage):
def delete(self):
store, iter = self.view.get_selection().get_selected()
try:
- user=store.get_value(iter, 0)
+ user = store.get_value(iter, 0)
if user == "root" or user == "user_u":
raise ValueError(_("SELinux user '%s' is required") % user)
self.wait()
- (rc, out) = commands.getstatusoutput("semanage user -d %s" % user)
+ (rc, out) = commands.getstatusoutput("semanage user -d %s" % user)
self.ready()
if rc != 0:
self.error(out)
return False
store.remove(iter)
- self.view.get_selection().select_path ((0,))
+ self.view.get_selection().select_path((0,))
except ValueError, e:
self.error(e.args[0])
diff --git a/policycoreutils/mcstrans/share/util/mlscolor-test b/policycoreutils/mcstrans/share/util/mlscolor-test
index 73243e84..7b8d809b 100644
--- a/policycoreutils/mcstrans/share/util/mlscolor-test
+++ b/policycoreutils/mcstrans/share/util/mlscolor-test
@@ -1,14 +1,15 @@
#!/usr/bin/python -E
-import sys, re
+import sys
+import re
from selinux import *
verbose = 0
-errors=0
+errors = 0
if len(sys.argv) > 1 and sys.argv[1] == "-v":
verbose = 1
-
+
for arg in sys.argv[1:]:
- f=open(arg, 'r')
+ f = open(arg, 'r')
for line in f:
if line.startswith('#'):
continue
@@ -16,7 +17,7 @@ for arg in sys.argv[1:]:
continue
line = line.rstrip('\n')
# print line
- context,expected=line.split("=");
+ context, expected = line.split("=")
rc, raw = selinux_trans_to_raw_context(context)
if rc < 0:
print "Unable to get raw context of '%s'" % (context)
@@ -29,15 +30,14 @@ for arg in sys.argv[1:]:
continue
colors = colors.rstrip()
if colors != expected:
- print "For '%s' got\n\t'%s' expected\n\t'%s'" % (context,colors,expected)
+ print "For '%s' got\n\t'%s' expected\n\t'%s'" % (context, colors, expected)
errors += 1
continue
f.close()
s = "s"
-if errors == 1: s = ""
+if errors == 1:
+ s = ""
print "mlscolor-test done with %d error%s" % (errors, s)
sys.exit(errors)
-
-
diff --git a/policycoreutils/mcstrans/share/util/mlstrans-test b/policycoreutils/mcstrans/share/util/mlstrans-test
index ac86391d..f854f7b3 100644
--- a/policycoreutils/mcstrans/share/util/mlstrans-test
+++ b/policycoreutils/mcstrans/share/util/mlstrans-test
@@ -1,8 +1,11 @@
#!/usr/bin/python -E
-import sys, re
+import sys
+import re
from selinux import *
verbose = 0
-errors=0
+errors = 0
+
+
def untrans(trans, val):
global errors, verbose
(rc, raw) = selinux_trans_to_raw_context(trans)
@@ -12,22 +15,23 @@ def untrans(trans, val):
else:
if verbose:
print "untrans: %s -> %s != %s SUCCESS" % (trans, raw, val)
-
+
+
def trans(raw, val):
global errors, verbose
(rc, trans) = selinux_raw_to_trans_context(raw)
if trans != val:
- print "trans: '%s' -> '%s' != '%s' FAILED" % (raw,trans, val)
+ print "trans: '%s' -> '%s' != '%s' FAILED" % (raw, trans, val)
errors += 1
else:
if verbose:
- print "trans: %s -> %s != %s SUCCESS" % (raw, trans, val)
+ print "trans: %s -> %s != %s SUCCESS" % (raw, trans, val)
if len(sys.argv) > 1 and sys.argv[1] == "-v":
verbose = 1
-
+
for arg in sys.argv[1:]:
- f=open(arg, 'r')
+ f = open(arg, 'r')
for line in f:
if line.startswith('#'):
continue
@@ -36,18 +40,17 @@ for arg in sys.argv[1:]:
line = line.rstrip('\n')
# print line
if (line.find("==") != -1):
- t,r=line.split("==");
+ t, r = line.split("==")
untrans("a:b:c:" + t, "a:b:c:" + r)
trans("a:b:c:" + r, "a:b:c:" + t)
else:
- t,r=line.split("=");
+ t, r = line.split("=")
untrans("a:b:c:" + t, "a:b:c:" + r)
f.close()
s = "s"
-if errors == 1: s = ""
+if errors == 1:
+ s = ""
print "mlstrans-test done with %d error%s" % (errors, s)
sys.exit(errors)
-
-
diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c
index 1882cc82..65a945d3 100644
--- a/policycoreutils/newrole/newrole.c
+++ b/policycoreutils/newrole/newrole.c
@@ -546,18 +546,27 @@ static int drop_capabilities(int full)
if (!uid) return 0;
capng_setpid(getpid());
- capng_clear(CAPNG_SELECT_BOTH);
- if (capng_lock() < 0)
+ capng_clear(CAPNG_SELECT_CAPS);
+
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+ fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
return -1;
+ }
/* Change uid */
if (setresuid(uid, uid, uid)) {
fprintf(stderr, _("Error changing uid, aborting.\n"));
return -1;
}
+
+ if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) {
+ fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
+ return -1;
+ }
+
if (! full)
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_AUDIT_WRITE);
- return capng_apply(CAPNG_SELECT_BOTH);
+ return capng_apply(CAPNG_SELECT_CAPS);
}
#elif defined(NAMESPACE_PRIV)
/**
@@ -575,20 +584,32 @@ static int drop_capabilities(int full)
*/
static int drop_capabilities(int full)
{
+ uid_t uid = getuid();
+ if (!uid) return 0;
+
capng_setpid(getpid());
- capng_clear(CAPNG_SELECT_BOTH);
- if (capng_lock() < 0)
+ capng_clear(CAPNG_SELECT_CAPS);
+
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+ fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
return -1;
+ }
- uid_t uid = getuid();
/* Change uid */
if (setresuid(uid, uid, uid)) {
fprintf(stderr, _("Error changing uid, aborting.\n"));
return -1;
}
+
+ if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) {
+ fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
+ return -1;
+ }
+
if (! full)
- capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_SETPCAP, -1);
- return capng_apply(CAPNG_SELECT_BOTH);
+ capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_AUDIT_WRITE, -1);
+
+ return capng_apply(CAPNG_SELECT_CAPS);
}
#else
@@ -679,7 +700,7 @@ static int relabel_tty(const char *ttyn, security_context_t new_context,
security_context_t * tty_context,
security_context_t * new_tty_context)
{
- int fd;
+ int fd, rc;
int enforcing = security_getenforce();
security_context_t tty_con = NULL;
security_context_t new_tty_con = NULL;
@@ -698,7 +719,13 @@ static int relabel_tty(const char *ttyn, security_context_t new_context,
fprintf(stderr, _("Error! Could not open %s.\n"), ttyn);
return fd;
}
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ /* this craziness is to make sure we cann't block on open and deadlock */
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ if (rc) {
+ fprintf(stderr, _("Error! Could not clear O_NONBLOCK on %s\n"), ttyn);
+ close(fd);
+ return rc;
+ }
if (fgetfilecon(fd, &tty_con) < 0) {
fprintf(stderr, _("%s! Could not get current context "
@@ -1009,9 +1036,9 @@ int main(int argc, char *argv[])
int fd;
pid_t childPid = 0;
char *shell_argv0 = NULL;
+ int rc;
#ifdef USE_PAM
- int rc;
int pam_status; /* pam return code */
pam_handle_t *pam_handle; /* opaque handle used by all PAM functions */
@@ -1225,15 +1252,23 @@ int main(int argc, char *argv[])
fd = open(ttyn, O_RDWR | O_NONBLOCK);
if (fd != 0)
goto err_close_pam;
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ if (rc)
+ goto err_close_pam;
+
fd = open(ttyn, O_RDWR | O_NONBLOCK);
if (fd != 1)
goto err_close_pam;
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ if (rc)
+ goto err_close_pam;
+
fd = open(ttyn, O_RDWR | O_NONBLOCK);
if (fd != 2)
goto err_close_pam;
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+ if (rc)
+ goto err_close_pam;
}
/*
@@ -1267,19 +1302,24 @@ int main(int argc, char *argv[])
}
#endif
- if (send_audit_message(1, old_context, new_context, ttyn))
+ if (send_audit_message(1, old_context, new_context, ttyn)) {
+ fprintf(stderr, _("Failed to send audit message"));
goto err_close_pam_session;
+ }
freecon(old_context); old_context=NULL;
freecon(new_context); new_context=NULL;
#ifdef NAMESPACE_PRIV
- if (transition_to_caller_uid())
+ if (transition_to_caller_uid()) {
+ fprintf(stderr, _("Failed to transition to namespace\n"));
goto err_close_pam_session;
+ }
#endif
- if (drop_capabilities(TRUE))
+ if (drop_capabilities(TRUE)) {
+ fprintf(stderr, _("Failed to drop capabilities %m\n"));
goto err_close_pam_session;
-
+ }
/* Handle environment changes */
if (restore_environment(preserve_environment, old_environ, &pw)) {
fprintf(stderr, _("Unable to restore the environment, "
diff --git a/policycoreutils/sandbox/sandbox b/policycoreutils/sandbox/sandbox
index 3678c5d3..f40de10c 100644
--- a/policycoreutils/sandbox/sandbox
+++ b/policycoreutils/sandbox/sandbox
@@ -20,12 +20,19 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-import os, stat, sys, socket, random, fcntl, shutil, re, subprocess
+import os
+import stat
+import sys
+import socket
+import random
+import fcntl
+import shutil
+import re
+import subprocess
import selinux
import signal
from tempfile import mkdtemp
import pwd
-import commands
import sepolicy
PROGNAME = "policycoreutils"
@@ -36,13 +43,16 @@ gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
- gettext.install(PROGNAME,
- localedir = "/usr/share/locale",
- unicode=False,
- codeset = 'utf-8')
+ gettext.install(PROGNAME,
+ localedir="/usr/share/locale",
+ codeset='utf-8')
except IOError:
- import __builtin__
- __builtin__.__dict__['_'] = unicode
+ try:
+ import builtins
+ builtins.__dict__['_'] = str
+ except ImportError:
+ import __builtin__
+ __builtin__.__dict__['_'] = unicode
DEFAULT_WINDOWSIZE = "1000x700"
DEFAULT_TYPE = "sandbox_t"
@@ -51,123 +61,136 @@ SAVE_FILES = {}
random.seed(None)
+
def sighandler(signum, frame):
- signal.signal(signum, signal.SIG_IGN)
+ signal.signal(signum, signal.SIG_IGN)
os.kill(0, signum)
raise KeyboardInterrupt
+
def setup_sighandlers():
- signal.signal(signal.SIGHUP, sighandler)
+ signal.signal(signal.SIGHUP, sighandler)
signal.signal(signal.SIGQUIT, sighandler)
signal.signal(signal.SIGTERM, sighandler)
+
def error_exit(msg):
sys.stderr.write("%s: " % sys.argv[0])
sys.stderr.write("%s\n" % msg)
sys.stderr.flush()
sys.exit(1)
+
def copyfile(file, srcdir, dest):
- import re
- if file.startswith(srcdir):
- dname = os.path.dirname(file)
- bname = os.path.basename(file)
- if dname == srcdir:
- dest = dest + "/" + bname
- else:
- newdir = re.sub(srcdir, dest, dname)
- if not os.path.exists(newdir):
- os.makedirs(newdir)
- dest = newdir + "/" + bname
-
- try:
- if os.path.isdir(file):
- shutil.copytree(file, dest)
- else:
- shutil.copy2(file, dest)
-
- except shutil.Error, elist:
- for e in elist.message:
- sys.stderr.write(e[2])
-
- SAVE_FILES[file] = (dest, os.path.getmtime(dest))
+ import re
+ if file.startswith(srcdir):
+ dname = os.path.dirname(file)
+ bname = os.path.basename(file)
+ if dname == srcdir:
+ dest = dest + "/" + bname
+ else:
+ newdir = re.sub(srcdir, dest, dname)
+ if not os.path.exists(newdir):
+ os.makedirs(newdir)
+ dest = newdir + "/" + bname
+
+ try:
+ if os.path.isdir(file):
+ shutil.copytree(file, dest)
+ else:
+ shutil.copy2(file, dest)
+
+ except shutil.Error as elist:
+ for e in elist.message:
+ sys.stderr.write(e[2])
+
+ SAVE_FILES[file] = (dest, os.path.getmtime(dest))
+
def savefile(new, orig, X_ind):
- copy = False
- if(X_ind):
- import gtk
- dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
- gtk.BUTTONS_YES_NO,
- _("Do you want to save changes to '%s' (Y/N): ") % orig)
- dlg.set_title(_("Sandbox Message"))
- dlg.set_position(gtk.WIN_POS_MOUSE)
- dlg.show_all()
- rc = dlg.run()
- dlg.destroy()
- if rc == gtk.RESPONSE_YES:
- copy = True
- else:
- ans = raw_input(_("Do you want to save changes to '%s' (y/N): ") % orig)
- if(re.match(_("[yY]"),ans)):
- copy = True
- if(copy):
- shutil.copy2(new,orig)
+ copy = False
+ if(X_ind):
+ import gtk
+ dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
+ gtk.BUTTONS_YES_NO,
+ _("Do you want to save changes to '%s' (Y/N): ") % orig)
+ dlg.set_title(_("Sandbox Message"))
+ dlg.set_position(gtk.WIN_POS_MOUSE)
+ dlg.show_all()
+ rc = dlg.run()
+ dlg.destroy()
+ if rc == gtk.RESPONSE_YES:
+ copy = True
+ else:
+ try:
+ input = raw_input
+ except NameError:
+ pass
+ ans = input(_("Do you want to save changes to '%s' (y/N): ") % orig)
+ if(re.match(_("[yY]"), ans)):
+ copy = True
+ if(copy):
+ shutil.copy2(new, orig)
+
def reserve(level):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind("\0%s" % level)
fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+
def get_range():
- try:
- level =selinux.getcon_raw()[1].split(":")[4]
- lowc,highc = level.split(".")
- low = int(lowc[1:])
- high = int(highc[1:])+1
- if high - low == 0:
- raise IndexError
-
- return low,high
- except IndexError:
- raise ValueError(_("User account must be setup with an MCS Range"))
+ try:
+ level = selinux.getcon_raw()[1].split(":")[4]
+ lowc, highc = level.split(".")
+ low = int(lowc[1:])
+ high = int(highc[1:]) + 1
+ if high - low == 0:
+ raise IndexError
+
+ return low, high
+ except IndexError:
+ raise ValueError(_("User account must be setup with an MCS Range"))
+
def gen_mcs():
- low, high = get_range()
-
- level = None
- ctr = 0
- total = high-low
- total = (total * (total - 1))/2
- while ctr < total:
- ctr += 1
- i1 = random.randrange(low, high)
- i2 = random.randrange(low, high)
- if i1 == i2:
- continue
- if i1 > i2:
- tmp = i1
- i1 = i2
- i2 = tmp
- level = "s0:c%d,c%d" % (i1, i2)
- try:
- reserve(level)
- except socket.error:
- continue
- break
- if level:
- return level
- raise ValueError(_("Failed to find any unused category sets. Consider a larger MCS range for this user."))
+ low, high = get_range()
+
+ level = None
+ ctr = 0
+ total = high - low
+ total = (total * (total - 1)) / 2
+ while ctr < total:
+ ctr += 1
+ i1 = random.randrange(low, high)
+ i2 = random.randrange(low, high)
+ if i1 == i2:
+ continue
+ if i1 > i2:
+ tmp = i1
+ i1 = i2
+ i2 = tmp
+ level = "s0:c%d,c%d" % (i1, i2)
+ try:
+ reserve(level)
+ except socket.error:
+ continue
+ break
+ if level:
+ return level
+ raise ValueError(_("Failed to find any unused category sets. Consider a larger MCS range for this user."))
def fullpath(cmd):
- for i in [ "/", "./", "../" ]:
- if cmd.startswith(i):
- return cmd
- for i in os.environ["PATH"].split(':'):
- f = "%s/%s" % (i, cmd)
- if os.access(f, os.X_OK):
- return f
- return cmd
+ for i in ["/", "./", "../"]:
+ if cmd.startswith(i):
+ return cmd
+ for i in os.environ["PATH"].split(':'):
+ f = "%s/%s" % (i, cmd)
+ if os.access(f, os.X_OK):
+ return f
+ return cmd
+
class Sandbox:
SYSLOG = "/var/log/messages"
@@ -184,77 +207,77 @@ class Sandbox:
self.__tmpdir = None
def __validate_mount(self):
- if self.__options.level:
- if not self.__options.homedir or not self.__options.tmpdir:
- self.usage(_("Homedir and tempdir required for level mounts"))
+ if self.__options.level:
+ if not self.__options.homedir or not self.__options.tmpdir:
+ self.usage(_("Homedir and tempdir required for level mounts"))
- if not os.path.exists(SEUNSHARE):
- raise ValueError(_("""
+ if not os.path.exists(SEUNSHARE):
+ raise ValueError(_("""
%s is required for the action you want to perform.
""") % SEUNSHARE)
def __mount_callback(self, option, opt, value, parser):
- self.__mount = True
+ self.__mount = True
def __x_callback(self, option, opt, value, parser):
- self.__mount = True
- setattr(parser.values, option.dest, True)
- if not os.path.exists(SEUNSHARE):
- raise ValueError(_("""
+ self.__mount = True
+ setattr(parser.values, option.dest, True)
+ if not os.path.exists(SEUNSHARE):
+ raise ValueError(_("""
%s is required for the action you want to perform.
""") % SEUNSHARE)
- if not os.path.exists(SANDBOXSH):
- raise ValueError(_("""
+ if not os.path.exists(SANDBOXSH):
+ raise ValueError(_("""
%s is required for the action you want to perform.
""") % SANDBOXSH)
def __validdir(self, option, opt, value, parser):
- if not os.path.isdir(value):
- raise IOError("Directory "+value+" not found")
- setattr(parser.values, option.dest, value)
- self.__mount = True
+ if not os.path.isdir(value):
+ raise IOError("Directory " + value + " not found")
+ setattr(parser.values, option.dest, value)
+ self.__mount = True
def __include(self, option, opt, value, parser):
- rp = os.path.realpath(os.path.expanduser(value))
- if not os.path.exists(rp):
- raise IOError(value+" not found")
+ rp = os.path.realpath(os.path.expanduser(value))
+ if not os.path.exists(rp):
+ raise IOError(value + " not found")
- if rp not in self.__init_files:
- self.__init_files.append(rp)
+ if rp not in self.__init_files:
+ self.__init_files.append(rp)
def __includefile(self, option, opt, value, parser):
- fd = open(value, "r")
- for i in fd.readlines():
- try:
- self.__include(option, opt, i[:-1], parser)
- except IOError, e:
- sys.stderr.write(str(e))
- except TypeError, e:
- sys.stderr.write(str(e))
- fd.close()
+ fd = open(value, "r")
+ for i in fd.readlines():
+ try:
+ self.__include(option, opt, i[:-1], parser)
+ except IOError as e:
+ sys.stderr.write(str(e))
+ except TypeError as e:
+ sys.stderr.write(str(e))
+ fd.close()
def __copyfiles(self):
- files = self.__init_files + self.__paths
- homedir=pwd.getpwuid(os.getuid()).pw_dir
- for f in files:
- copyfile(f, homedir, self.__homedir)
- copyfile(f, "/tmp", self.__tmpdir)
- copyfile(f, "/var/tmp", self.__tmpdir)
-
- def __setup_sandboxrc(self, wm = "/usr/bin/openbox"):
- execfile =self.__homedir + "/.sandboxrc"
- fd = open(execfile, "w+")
- if self.__options.session:
- fd.write("""#!/bin/sh
+ files = self.__init_files + self.__paths
+ homedir = pwd.getpwuid(os.getuid()).pw_dir
+ for f in files:
+ copyfile(f, homedir, self.__homedir)
+ copyfile(f, "/tmp", self.__tmpdir)
+ copyfile(f, "/var/tmp", self.__tmpdir)
+
+ def __setup_sandboxrc(self, wm="/usr/bin/openbox"):
+ execfile = self.__homedir + "/.sandboxrc"
+ fd = open(execfile, "w+")
+ if self.__options.session:
+ fd.write("""#!/bin/sh
#TITLE: /etc/gdm/Xsession
/etc/gdm/Xsession
""")
- else:
- command = self.__paths[0] + " "
- for p in self.__paths[1:]:
- command += "'%s' " % p
- fd.write("""#! /bin/sh
+ else:
+ command = self.__paths[0] + " "
+ for p in self.__paths[1:]:
+ command += "'%s' " % p
+ fd.write("""#! /bin/sh
#TITLE: %s
/usr/bin/test -r ~/.xmodmap && /usr/bin/xmodmap ~/.xmodmap
%s &
@@ -262,22 +285,22 @@ WM_PID=$!
dbus-launch --exit-with-session %s
kill -TERM $WM_PID 2> /dev/null
""" % (command, wm, command))
- fd.close()
- os.chmod(execfile, 0700)
+ fd.close()
+ os.chmod(execfile, 0o700)
- def usage(self, message = ""):
- error_exit("%s\n%s" % (self.__parser.usage, message))
+ def usage(self, message=""):
+ error_exit("%s\n%s" % (self.__parser.usage, message))
def __parse_options(self):
from optparse import OptionParser
types = ""
try:
- types = _("""
+ types = _("""
Policy defines the following types for use with the -t:
\t%s
""") % "\n\t".join(sepolicy.info(sepolicy.ATTRIBUTE, "sandbox_type")[0]['types'])
except RuntimeError:
- pass
+ pass
usage = _("""
sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] command
@@ -288,34 +311,34 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
parser = OptionParser(usage=usage)
parser.disable_interspersed_args()
- parser.add_option("-i", "--include",
- action="callback", callback=self.__include,
+ parser.add_option("-i", "--include",
+ action="callback", callback=self.__include,
type="string",
help=_("include file in sandbox"))
- parser.add_option("-I", "--includefile", action="callback", callback=self.__includefile,
+ parser.add_option("-I", "--includefile", action="callback", callback=self.__includefile,
type="string",
help=_("read list of files to include in sandbox from INCLUDEFILE"))
parser.add_option("-t", "--type", dest="setype", action="store", default=None,
help=_("run sandbox with SELinux type"))
- parser.add_option("-M", "--mount",
- action="callback", callback=self.__mount_callback,
+ parser.add_option("-M", "--mount",
+ action="callback", callback=self.__mount_callback,
help=_("mount new home and/or tmp directory"))
parser.add_option("-d", "--dpi",
dest="dpi", action="store",
help=_("dots per inch for X display"))
- parser.add_option("-S", "--session", action="store_true", dest="session",
- default=False, help=_("run complete desktop session within sandbox"))
+ parser.add_option("-S", "--session", action="store_true", dest="session",
+ default=False, help=_("run complete desktop session within sandbox"))
- parser.add_option("-s", "--shred", action="store_true", dest="shred",
- default=False, help=_("Shred content before tempory directories are removed"))
+ parser.add_option("-s", "--shred", action="store_true", dest="shred",
+ default=False, help=_("Shred content before tempory directories are removed"))
- parser.add_option("-X", dest="X_ind",
- action="callback", callback=self.__x_callback,
- default=False, help=_("run X application within a sandbox"))
+ parser.add_option("-X", dest="X_ind",
+ action="callback", callback=self.__x_callback,
+ default=False, help=_("run X application within a sandbox"))
- parser.add_option("-H", "--homedir",
+ parser.add_option("-H", "--homedir",
action="callback", callback=self.__validdir,
type="string",
dest="homedir",
@@ -330,156 +353,157 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-
type="string", default=DEFAULT_WINDOWSIZE,
help="size of the sandbox window")
- parser.add_option("-W", "--windowmanager", dest="wm",
+ parser.add_option("-W", "--windowmanager", dest="wm",
type="string",
default="/usr/bin/openbox",
help=_("alternate window manager"))
- parser.add_option("-l", "--level", dest="level",
+ parser.add_option("-l", "--level", dest="level",
help=_("MCS/MLS level for the sandbox"))
parser.add_option("-C", "--capabilities",
- action="store_true", dest="usecaps", default=False,
- help="Allow apps requiring capabilities to run within the sandbox.")
+ action="store_true", dest="usecaps", default=False,
+ help="Allow apps requiring capabilities to run within the sandbox.")
- self.__parser=parser
+ self.__parser = parser
self.__options, cmds = parser.parse_args()
if self.__options.X_ind:
- self.setype = DEFAULT_X_TYPE
+ self.setype = DEFAULT_X_TYPE
else:
- try:
- sepolicy.info(sepolicy.TYPE, "sandbox_t")
- except RuntimeError:
- raise ValueError(_("Sandbox Policy is not currently installed.\nYou need to install the selinux-policy-sandbox package in order to run this command"))
-
+ try:
+ sepolicy.info(sepolicy.TYPE, "sandbox_t")
+ except RuntimeError:
+ raise ValueError(_("Sandbox Policy is not currently installed.\nYou need to install the selinux-policy-sandbox package in order to run this command"))
+
if self.__options.setype:
- self.setype = self.__options.setype
+ self.setype = self.__options.setype
if self.__mount:
- self.__validate_mount()
+ self.__validate_mount()
if self.__options.session:
- if not self.__options.setype:
- self.setype = selinux.getcon()[1].split(":")[2]
- if not self.__options.homedir or not self.__options.tmpdir:
- self.usage(_("You must specify a Homedir and tempdir when setting up a session sandbox"))
- if len(cmds) > 0:
- self.usage(_("Commands are not allowed in a session sandbox"))
- self.__options.X_ind = True
- self.__homedir = self.__options.homedir
- self.__tmpdir = self.__options.tmpdir
+ if not self.__options.setype:
+ self.setype = selinux.getcon()[1].split(":")[2]
+ if not self.__options.homedir or not self.__options.tmpdir:
+ self.usage(_("You must specify a Homedir and tempdir when setting up a session sandbox"))
+ if len(cmds) > 0:
+ self.usage(_("Commands are not allowed in a session sandbox"))
+ self.__options.X_ind = True
+ self.__homedir = self.__options.homedir
+ self.__tmpdir = self.__options.tmpdir
else:
- if self.__options.level:
- self.__homedir = self.__options.homedir
- self.__tmpdir = self.__options.tmpdir
-
- if len(cmds) == 0:
- self.usage(_("Command required"))
- cmds[0] = fullpath(cmds[0])
- if not os.access(cmds[0], os.X_OK):
- self.usage(_("%s is not an executable") % cmds[0] )
-
- self.__cmds = cmds
+ if self.__options.level:
+ self.__homedir = self.__options.homedir
+ self.__tmpdir = self.__options.tmpdir
+
+ if len(cmds) == 0:
+ self.usage(_("Command required"))
+ cmds[0] = fullpath(cmds[0])
+ if not os.access(cmds[0], os.X_OK):
+ self.usage(_("%s is not an executable") % cmds[0])
+
+ self.__cmds = cmds
for f in cmds:
- rp = os.path.realpath(f)
- if os.path.exists(rp):
- self.__paths.append(rp)
- else:
- self.__paths.append(f)
-
+ rp = os.path.realpath(f)
+ if os.path.exists(rp):
+ self.__paths.append(rp)
+ else:
+ self.__paths.append(f)
+
def __gen_context(self):
- if self.__options.level:
- level = self.__options.level
- else:
- level = gen_mcs()
-
- con = selinux.getcon()[1].split(":")
- self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.setype, level)
- self.__filecon = "%s:object_r:sandbox_file_t:%s" % (con[0], level)
+ if self.__options.level:
+ level = self.__options.level
+ else:
+ level = gen_mcs()
+
+ con = selinux.getcon()[1].split(":")
+ self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.setype, level)
+ self.__filecon = "%s:object_r:sandbox_file_t:%s" % (con[0], level)
+
def __setup_dir(self):
- if self.__options.level or self.__options.session:
- return
-
- if self.__options.homedir:
- selinux.chcon(self.__options.homedir, self.__filecon, recursive=True)
- self.__homedir = self.__options.homedir
- else:
- selinux.setfscreatecon(self.__filecon)
- self.__homedir = mkdtemp(dir="/tmp", prefix=".sandbox_home_")
-
- if self.__options.tmpdir:
- selinux.chcon(self.__options.tmpdir, self.__filecon, recursive=True)
- self.__tmpdir = self.__options.tmpdir
- else:
- selinux.setfscreatecon(self.__filecon)
- self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
- selinux.setfscreatecon(None)
- self.__copyfiles()
+ if self.__options.level or self.__options.session:
+ return
+
+ if self.__options.homedir:
+ selinux.chcon(self.__options.homedir, self.__filecon, recursive=True)
+ self.__homedir = self.__options.homedir
+ else:
+ selinux.setfscreatecon(self.__filecon)
+ self.__homedir = mkdtemp(dir="/tmp", prefix=".sandbox_home_")
+
+ if self.__options.tmpdir:
+ selinux.chcon(self.__options.tmpdir, self.__filecon, recursive=True)
+ self.__tmpdir = self.__options.tmpdir
+ else:
+ selinux.setfscreatecon(self.__filecon)
+ self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
+ selinux.setfscreatecon(None)
+ self.__copyfiles()
def __execute(self):
- try:
- cmds = [ SEUNSHARE, "-Z", self.__execcon ]
- if self.__options.usecaps:
- cmds.append('-C')
- if self.__mount:
- cmds += [ "-t", self.__tmpdir, "-h", self.__homedir ]
-
- if self.__options.X_ind:
- if self.__options.dpi:
- dpi = self.__options.dpi
- else:
- import gtk
- dpi = str(gtk.settings_get_default().props.gtk_xft_dpi/1024)
-
- xmodmapfile = self.__homedir + "/.xmodmap"
- xd = open(xmodmapfile,"w")
- subprocess.Popen(["/usr/bin/xmodmap","-pke"],stdout=xd).wait()
- xd.close()
-
- self.__setup_sandboxrc(self.__options.wm)
-
- cmds += [ "--", SANDBOXSH, self.__options.windowsize, dpi ]
- else:
- cmds += [ "--" ] + self.__paths
- return subprocess.Popen(cmds).wait()
-
- selinux.setexeccon(self.__execcon)
- rc = subprocess.Popen(self.__cmds).wait()
- selinux.setexeccon(None)
- return rc
-
- finally:
- for i in self.__paths:
- if i not in SAVE_FILES:
- continue
- (dest, mtime) = SAVE_FILES[i]
- if os.path.getmtime(dest) > mtime:
- savefile(dest, i, self.__options.X_ind)
-
- if self.__homedir and not self.__options.homedir:
- if self.__options.shred:
- self.shred(self.__homedir)
- shutil.rmtree(self.__homedir)
- if self.__tmpdir and not self.__options.tmpdir:
- if self.__options.shred:
- self.shred(self.__homedir)
- shutil.rmtree(self.__tmpdir)
+ try:
+ cmds = [SEUNSHARE, "-Z", self.__execcon]
+ if self.__options.usecaps:
+ cmds.append('-C')
+ if self.__mount:
+ cmds += ["-t", self.__tmpdir, "-h", self.__homedir]
+
+ if self.__options.X_ind:
+ if self.__options.dpi:
+ dpi = self.__options.dpi
+ else:
+ import gtk
+ dpi = str(gtk.settings_get_default().props.gtk_xft_dpi / 1024)
+
+ xmodmapfile = self.__homedir + "/.xmodmap"
+ xd = open(xmodmapfile, "w")
+ subprocess.Popen(["/usr/bin/xmodmap", "-pke"], stdout=xd).wait()
+ xd.close()
+
+ self.__setup_sandboxrc(self.__options.wm)
+
+ cmds += ["--", SANDBOXSH, self.__options.windowsize, dpi]
+ else:
+ cmds += ["--"] + self.__paths
+ return subprocess.Popen(cmds).wait()
+
+ selinux.setexeccon(self.__execcon)
+ rc = subprocess.Popen(self.__cmds).wait()
+ selinux.setexeccon(None)
+ return rc
+
+ finally:
+ for i in self.__paths:
+ if i not in SAVE_FILES:
+ continue
+ (dest, mtime) = SAVE_FILES[i]
+ if os.path.getmtime(dest) > mtime:
+ savefile(dest, i, self.__options.X_ind)
+
+ if self.__homedir and not self.__options.homedir:
+ if self.__options.shred:
+ self.shred(self.__homedir)
+ shutil.rmtree(self.__homedir)
+ if self.__tmpdir and not self.__options.tmpdir:
+ if self.__options.shred:
+ self.shred(self.__homedir)
+ shutil.rmtree(self.__tmpdir)
def shred(self, path):
for root, dirs, files in os.walk(path):
for f in files:
dest = root + "/" + f
- subprocess.Popen(["/usr/bin/shred",dest]).wait()
+ subprocess.Popen(["/usr/bin/shred", dest]).wait()
def main(self):
try:
- self.__parse_options()
- self.__gen_context()
- self.__setup_dir()
- return self.__execute()
+ self.__parse_options()
+ self.__gen_context()
+ self.__setup_dir()
+ return self.__execute()
except KeyboardInterrupt:
sys.exit(0)
@@ -488,19 +512,19 @@ if __name__ == '__main__':
setup_sighandlers()
if selinux.is_selinux_enabled() != 1:
error_exit("Requires an SELinux enabled system")
-
+
try:
- sandbox = Sandbox()
- rc = sandbox.main()
- except OSError, error:
- error_exit(error)
- except ValueError, error:
- error_exit(error.args[0])
- except KeyError, error:
- error_exit(_("Invalid value %s") % error.args[0])
- except IOError, error:
- error_exit(error)
+ sandbox = Sandbox()
+ rc = sandbox.main()
+ except OSError as error:
+ error_exit(error)
+ except ValueError as error:
+ error_exit(error.args[0])
+ except KeyError as error:
+ error_exit(_("Invalid value %s") % error.args[0])
+ except IOError as error:
+ error_exit(error)
except KeyboardInterrupt:
- rc = 0
-
+ rc = 0
+
sys.exit(rc)
diff --git a/policycoreutils/sandbox/start b/policycoreutils/sandbox/start
index 52950d7d..fc406e1e 100644
--- a/policycoreutils/sandbox/start
+++ b/policycoreutils/sandbox/start
@@ -1,9 +1,11 @@
#! /usr/bin/python -Es
-import gtk, commands, sys
-rc = [-1,'']
+import gtk
+import subprocess
+import sys
+rc = [-1, '']
try:
- rc=commands.getstatusoutput(sys.argv[1])
+ rc = subprocess.getstatusoutput(sys.argv[1])
except:
pass
if rc[0] == 0:
- print rc[1]
+ print(rc[1])
diff --git a/policycoreutils/sandbox/test_sandbox.py b/policycoreutils/sandbox/test_sandbox.py
index b3b7f648..6f54d0cb 100644
--- a/policycoreutils/sandbox/test_sandbox.py
+++ b/policycoreutils/sandbox/test_sandbox.py
@@ -1,29 +1,34 @@
-import unittest, os, shutil
+import unittest
+import os
+import shutil
from tempfile import mkdtemp
from subprocess import Popen, PIPE
+
class SandboxTests(unittest.TestCase):
+
def assertDenied(self, err):
- self.assert_('Permission denied' in err,
- '"Permission denied" not found in %r' % err)
+ self.assertTrue(b'Permission denied' in err,
+ '"Permission denied" not found in %r' % err)
+
def assertNotFound(self, err):
- self.assert_('not found' in err,
- '"not found" not found in %r' % err)
+ self.assertTrue(b'not found' in err,
+ '"not found" not found in %r' % err)
def assertFailure(self, status):
- self.assert_(status != 0,
- '"Succeeded when it should have failed')
+ self.assertTrue(status != 0,
+ '"Succeeded when it should have failed')
def assertSuccess(self, status, err):
- self.assert_(status == 0,
- '"Sandbox should have succeeded for this test %r' % err)
+ self.assertTrue(status == 0,
+ '"Sandbox should have succeeded for this test %r' % err)
def test_simple_success(self):
"Verify that we can read file descriptors handed to sandbox"
- p1 = Popen(['cat', '/etc/passwd'], stdout = PIPE)
- p2 = Popen(['sandbox', 'grep', 'root'], stdin = p1.stdout, stdout=PIPE)
+ p1 = Popen(['cat', '/etc/passwd'], stdout=PIPE)
+ p2 = Popen(['sandbox', 'grep', 'root'], stdin=p1.stdout, stdout=PIPE)
out, err = p2.communicate()
- self.assert_('root' in out)
+ self.assertTrue(b'root' in out)
def test_cant_kill(self):
"Verify that we cannot send kill signal in the sandbox"
@@ -37,7 +42,7 @@ class SandboxTests(unittest.TestCase):
p = Popen(['sandbox', 'ping', '-c 1 ', '127.0.0.1'], stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
self.assertDenied(err)
-
+
def test_cant_mkdir(self):
"Verify that we can't mkdir within the sandbox"
p = Popen(['sandbox', 'mkdir', '~/test'], stdout=PIPE, stderr=PIPE)
@@ -55,25 +60,25 @@ class SandboxTests(unittest.TestCase):
p = Popen(['sandbox', 'mail'], stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
self.assertDenied(err)
-
+
def test_cant_sudo(self):
"Verify that we can't run sudo within the sandbox"
p = Popen(['sandbox', 'sudo'], stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
self.assertFailure(p.returncode)
-
+
def test_mount(self):
"Verify that we mount a file system"
p = Popen(['sandbox', '-M', 'id'], stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
-
+
def test_set_level(self):
"Verify that we set level a file system"
p = Popen(['sandbox', '-l', 's0', 'id'], stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
-
+
def test_homedir(self):
"Verify that we set homedir a file system"
homedir = mkdtemp(dir=".", prefix=".sandbox_test")
@@ -81,7 +86,7 @@ class SandboxTests(unittest.TestCase):
out, err = p.communicate()
shutil.rmtree(homedir)
self.assertSuccess(p.returncode, err)
-
+
def test_tmpdir(self):
"Verify that we set tmpdir a file system"
tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_test")
@@ -89,10 +94,10 @@ class SandboxTests(unittest.TestCase):
out, err = p.communicate()
shutil.rmtree(tmpdir)
self.assertSuccess(p.returncode, err)
-
+
if __name__ == "__main__":
import selinux
if selinux.security_getenforce() == 1:
unittest.main()
else:
- print "SELinux must be in enforcing mode for this test"
+ print("SELinux must be in enforcing mode for this test")
diff --git a/policycoreutils/scripts/chcat b/policycoreutils/scripts/chcat
index 9efcb22b..ec527e55 100755
--- a/policycoreutils/scripts/chcat
+++ b/policycoreutils/scripts/chcat
@@ -1,5 +1,5 @@
#! /usr/bin/python -Es
-# Copyright (C) 2005 Red Hat
+# Copyright (C) 2005 Red Hat
# see file 'COPYING' for use and warranty information
#
# chcat is a script that allows you modify the Security label on a file
@@ -18,19 +18,30 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
-import commands, sys, os, pwd, string, getopt, selinux
+#
+import subprocess
+import sys
+import os
+import pwd
+import string
+import getopt
+import selinux
import seobject
import gettext
try:
gettext.install('policycoreutils')
except IOError:
- import __builtin__
- __builtin__.__dict__['_'] = unicode
+ try:
+ import builtins
+ builtins.__dict__['_'] = str
+ except ImportError:
+ import __builtin__
+ __builtin__.__dict__['_'] = unicode
+
def errorExit(error):
sys.stderr.write("%s: " % sys.argv[0])
@@ -38,12 +49,14 @@ def errorExit(error):
sys.stderr.flush()
sys.exit(1)
+
def verify_users(users):
for u in users:
try:
pwd.getpwnam(u)
except KeyError:
- error( "User %s does not exist" % u)
+ error("User %s does not exist" % u)
+
def chcat_user_add(newcat, users):
errors = 0
@@ -70,30 +83,30 @@ def chcat_user_add(newcat, users):
if i not in cats:
cats.append(i)
-
if len(cats) > 0:
new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
else:
new_serange = "%s-%s" % (serange[0], top[0])
-
+
if add_ind:
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
- rc = commands.getstatusoutput(cmd)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
-
-def chcat_add(orig, newcat, objects,login_ind):
+
+
+def chcat_add(orig, newcat, objects, login_ind):
if len(newcat) == 1:
raise ValueError(_("Requires at least one category"))
if login_ind == 1:
return chcat_user_add(newcat, objects)
-
+
errors = 0
sensitivity = newcat[0]
cat = newcat[1]
@@ -101,13 +114,13 @@ def chcat_add(orig, newcat, objects,login_ind):
for f in objects:
(rc, c) = selinux.getfilecon(f)
con = c.split(":")[3:]
- clist = translate(con)
+ clist = translate(con)
if sensitivity != clist[0]:
- print(_("Can not modify sensitivity levels using '+' on %s") % f)
+ print(_("Can not modify sensitivity levels using '+' on %s") % f)
if len(clist) > 1:
if cat in clist[1:]:
- print _("%s is already in %s") % (f, orig)
+ print(_("%s is already in %s") % (f, orig))
continue
clist.append(cat)
cats = clist[1:]
@@ -118,12 +131,13 @@ def chcat_add(orig, newcat, objects,login_ind):
else:
cat_string = cat
cmd = 'chcon -l %s:%s %s' % (sensitivity, cat_string, f)
- rc = commands.getstatusoutput(cmd)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
+
def chcat_user_remove(newcat, users):
errors = 0
logins = seobject.loginRecords()
@@ -153,17 +167,18 @@ def chcat_user_remove(newcat, users):
new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
else:
new_serange = "%s-%s" % (serange[0], top[0])
-
+
if add_ind:
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
- rc = commands.getstatusoutput(cmd)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
-
+
+
def chcat_remove(orig, newcat, objects, login_ind):
if len(newcat) == 1:
raise ValueError(_("Requires at least one category"))
@@ -180,12 +195,12 @@ def chcat_remove(orig, newcat, objects, login_ind):
con = c.split(":")[3:]
clist = translate(con)
if sensitivity != clist[0]:
- print(_("Can not modify sensitivity levels using '+' on %s") % f)
- continue
-
+ print(_("Can not modify sensitivity levels using '+' on %s") % f)
+ continue
+
if len(clist) > 1:
if cat not in clist[1:]:
- print _("%s is not in %s") % (f, orig)
+ print(_("%s is not in %s") % (f, orig))
continue
clist.remove(cat)
if len(clist) > 1:
@@ -195,19 +210,20 @@ def chcat_remove(orig, newcat, objects, login_ind):
else:
cat = ""
else:
- print _("%s is not in %s") % (f, orig)
- continue
-
- if len(cat) == 0:
+ print(_("%s is not in %s") % (f, orig))
+ continue
+
+ if len(cat) == 0:
cmd = 'chcon -l %s %s' % (sensitivity, f)
else:
- cmd = 'chcon -l %s:%s %s' % (sensitivity,cat, f)
- rc = commands.getstatusoutput(cmd)
+ cmd = 'chcon -l %s:%s %s' % (sensitivity, cat, f)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
+
def chcat_user_replace(newcat, users):
errors = 0
logins = seobject.loginRecords()
@@ -221,7 +237,7 @@ def chcat_user_replace(newcat, users):
add_ind = 1
user = seusers["__default__"]
serange = user[1].split("-")
- new_serange = "%s-%s:%s" % (serange[0],newcat[0], string.join(newcat[1:], ","))
+ new_serange = "%s-%s:%s" % (serange[0], newcat[0], string.join(newcat[1:], ","))
if new_serange[-1:] == ":":
new_serange = new_serange[:-1]
@@ -229,12 +245,13 @@ def chcat_user_replace(newcat, users):
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
- rc = commands.getstatusoutput(cmd)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
-
+
+
def chcat_replace(newcat, objects, login_ind):
if login_ind == 1:
return chcat_user_replace(newcat, objects)
@@ -247,22 +264,23 @@ def chcat_replace(newcat, objects, login_ind):
cmd = 'chcon -l %s:%s' % (sensitivity, newcat[1])
for cat in newcat[2:]:
cmd = '%s,%s' % (cmd, cat)
-
+
for f in objects:
cmd = "%s %s" % (cmd, f)
- rc = commands.getstatusoutput(cmd)
+ rc = subprocess.getstatusoutput(cmd)
if rc[0] != 0:
- print rc[1]
+ print(rc[1])
errors += 1
return errors
+
def check_replace(cats):
plus_ind = 0
replace_ind = 0
for c in cats:
- if len(c) > 0 and ( c[0] == "+" or c[0] == "-" ):
+ if len(c) > 0 and (c[0] == "+" or c[0] == "-"):
if replace_ind:
raise ValueError(_("Can not combine +/- with other types of categories"))
plus_ind = 1
@@ -272,12 +290,14 @@ def check_replace(cats):
raise ValueError(_("Can not combine +/- with other types of categories"))
return replace_ind
+
def isSensitivity(sensitivity):
- if sensitivity[0] == "s" and sensitivity[1:].isdigit() and int(sensitivity[1:]) in range(0,16):
+ if sensitivity[0] == "s" and sensitivity[1:].isdigit() and int(sensitivity[1:]) in range(0, 16):
return 1
else:
return 0
-
+
+
def expandCats(cats):
newcats = []
for c in cats:
@@ -295,6 +315,7 @@ def expandCats(cats):
return cats
return newcats
+
def translate(cats):
newcat = []
if len(cats) == 0:
@@ -320,20 +341,22 @@ def translate(cats):
for i in tlist[1:]:
newcat.append(i)
return newcat
-
+
+
def usage():
- print _("Usage %s CATEGORY File ...") % sys.argv[0]
- print _("Usage %s -l CATEGORY user ...") % sys.argv[0]
- print _("Usage %s [[+|-]CATEGORY],...]q File ...") % sys.argv[0]
- print _("Usage %s -l [[+|-]CATEGORY],...]q user ...") % sys.argv[0]
- print _("Usage %s -d File ...") % sys.argv[0]
- print _("Usage %s -l -d user ...") % sys.argv[0]
- print _("Usage %s -L") % sys.argv[0]
- print _("Usage %s -L -l user") % sys.argv[0]
- print _("Use -- to end option list. For example")
- print _("chcat -- -CompanyConfidential /docs/businessplan.odt")
- print _("chcat -l +CompanyConfidential juser")
- sys.exit(1)
+ print(_("Usage %s CATEGORY File ...") % sys.argv[0])
+ print(_("Usage %s -l CATEGORY user ...") % sys.argv[0])
+ print(_("Usage %s [[+|-]CATEGORY],...]q File ...") % sys.argv[0])
+ print(_("Usage %s -l [[+|-]CATEGORY],...]q user ...") % sys.argv[0])
+ print(_("Usage %s -d File ...") % sys.argv[0])
+ print(_("Usage %s -l -d user ...") % sys.argv[0])
+ print(_("Usage %s -L") % sys.argv[0])
+ print(_("Usage %s -L -l user") % sys.argv[0])
+ print(_("Use -- to end option list. For example"))
+ print(_("chcat -- -CompanyConfidential /docs/businessplan.odt"))
+ print(_("chcat -l +CompanyConfidential juser"))
+ sys.exit(1)
+
def listcats():
fd = open(selinux.selinux_translations_path())
@@ -342,10 +365,10 @@ def listcats():
continue
if l.find("=") != -1:
rec = l.split("=")
- print "%-30s %s" % tuple(rec)
+ print("%-30s %s" % tuple(rec))
fd.close()
return 0
-
+
def listusercats(users):
if len(users) == 0:
@@ -356,21 +379,22 @@ def listusercats(users):
cats = seobject.translate(selinux.getseuserbyname(u)[2])
cats = cats.split("-")
if len(cats) > 1 and cats[1] != "s0":
- print "%s: %s" % (u, cats[1])
+ print("%s: %s" % (u, cats[1]))
else:
- print "%s: %s" % (u, cats[0])
-
+ print("%s: %s" % (u, cats[0]))
+
+
def error(msg):
- print "%s: %s" % (sys.argv[0], msg)
+ print("%s: %s" % (sys.argv[0], msg))
sys.exit(1)
-
+
if __name__ == '__main__':
if selinux.is_selinux_mls_enabled() != 1:
error("Requires a mls enabled system")
-
+
if selinux.is_selinux_enabled() != 1:
error("Requires an SELinux enabled system")
-
+
delete_ind = 0
list_ind = 0
login_ind = 0
@@ -382,7 +406,7 @@ if __name__ == '__main__':
'help',
'delete'])
- for o,a in gopts:
+ for o, a in gopts:
if o == "-h" or o == "--help":
usage()
if o == "-d" or o == "--delete":
@@ -395,10 +419,10 @@ if __name__ == '__main__':
if list_ind == 0 and len(cmds) < 1:
usage()
- except getopt.error, error:
+ except getopt.error as error:
errorExit(_("Options Error %s ") % error.msg)
- except ValueError, e:
+ except ValueError as e:
usage()
if delete_ind:
@@ -414,7 +438,7 @@ if __name__ == '__main__':
if len(cmds) < 2:
usage()
-
+
set_ind = 0
cats = cmds[0].split(",")
mod_ind = 0
@@ -428,17 +452,14 @@ if __name__ == '__main__':
l = []
l.append(c[1:])
if len(c) > 0 and c[0] == "+":
- errors += chcat_add(c[1:],translate(l), objects, login_ind)
+ errors += chcat_add(c[1:], translate(l), objects, login_ind)
continue
if len(c) > 0 and c[0] == "-":
- errors += chcat_remove(c[1:],translate(l), objects, login_ind)
+ errors += chcat_remove(c[1:], translate(l), objects, login_ind)
continue
- except ValueError, e:
+ except ValueError as e:
error(e)
- except OSError, e:
+ except OSError as e:
error(e)
-
- sys.exit(errors)
-
-
+ sys.exit(errors)
diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage
index dd630107..80972086 100644
--- a/policycoreutils/semanage/semanage
+++ b/policycoreutils/semanage/semanage
@@ -18,7 +18,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
#
@@ -27,59 +27,74 @@ import argparse
import seobject
import sys
import gettext
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
try:
- gettext.install(PROGNAME,
- localedir="/usr/share/locale",
- unicode=True,
- codeset = 'utf-8')
+ kwargs = {}
+ if sys.version_info < (3,):
+ kwargs['unicode'] = True
+ gettext.install(PROGNAME,
+ localedir="/usr/share/locale",
+ codeset='utf-8',
+ **kwargs)
except IOError:
- import __builtin__
- __builtin__.__dict__['_'] = unicode
+ try:
+ import builtins
+ builtins.__dict__['_'] = str
+ except ImportError:
+ import __builtin__
+ __builtin__.__dict__['_'] = unicode
# define custom usages for selected main actions
usage_login = "semanage login [-h] [-n] [-N] [-s STORE] ["
-usage_login_dict = {' --add':('-s SEUSER','-r RANGE','LOGIN',),' --modify':('-s SEUSER','-r RANGE','LOGIN',),' --delete':('LOGIN',), ' --list':('-C',),' --extract':('',), ' --deleteall':('',)}
+usage_login_dict = {' --add': ('-s SEUSER', '-r RANGE', 'LOGIN',), ' --modify': ('-s SEUSER', '-r RANGE', 'LOGIN',), ' --delete': ('LOGIN',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_fcontext = "semanage fcontext [-h] [-n] [-N] [-s STORE] ["
-usage_fcontext_dict = {' --add':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER', '|','-e EQUAL', ')','FILE_SPEC',')' ,),' --delete':('(','-t TYPE','-f FTYPE','|','-e EQUAL',')','FILE_SPEC', ')',),' --modify':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER','|','-e EQUAL',')','FILE_SPEC )',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_fcontext_dict = {' --add': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC', ')',), ' --delete': ('(', '-t TYPE', '-f FTYPE', '|', '-e EQUAL', ')', 'FILE_SPEC', ')',), ' --modify': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC )',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_user = "semanage user [-h] [-n] [-N] [-s STORE] ["
-usage_user_dict = {' --add':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name'')'),' --delete':('selinux_name',),' --modify':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_user_dict = {' --add': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name'')'), ' --delete': ('selinux_name',), ' --modify': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_port = "semanage port [-h] [-n] [-N] [-s STORE] ["
-usage_port_dict = {' --add':('-t TYPE','-p PROTOCOL','-r RANGE','(','port_name','|','port_range',')'),' --modify':('-t TYPE','-p PROTOCOL','-r RANGE','(','port_name','|','port_range',')'), ' --delete':('-p PROTOCOL','(','port_name','|','port_range',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_port_dict = {' --add': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --modify': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --delete': ('-p PROTOCOL', '(', 'port_name', '|', 'port_range', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_node = "semanage node [-h] [-n] [-N] [-s STORE] ["
-usage_node_dict = {' --add':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'),' --modify':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'), ' --delete':('-M NETMASK','-p PROTOCOL','node'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_node_dict = {' --add': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --modify': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --delete': ('-M NETMASK', '-p PROTOCOL', 'node'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_interface = "semanage interface [-h] [-n] [-N] [-s STORE] ["
-usage_interface_dict = {' --add':('-t TYPE','-r RANGE','interface'),' --modify':('-t TYPE','-r RANGE','interface'), ' --delete':('interface',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_interface_dict = {' --add': ('-t TYPE', '-r RANGE', 'interface'), ' --modify': ('-t TYPE', '-r RANGE', 'interface'), ' --delete': ('interface',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
usage_boolean = "semanage boolean [-h] [-n] [-N] [-s STORE] ["
-usage_boolean_dict = {' --modify':('(','--on','|','--off',')','boolean'), ' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_boolean_dict = {' --modify': ('(', '--on', '|', '--off', ')', 'boolean'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
import sepolicy
+
+
class CheckRole(argparse.Action):
+
def __call__(self, parser, namespace, value, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
- newval = []
+ newval = []
roles = sepolicy.get_all_roles()
for v in value.split():
- if v not in roles:
- raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles)))
- newval.append(v)
+ if v not in roles:
+ raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles)))
+ newval.append(v)
setattr(namespace, self.dest, newval)
store = ''
+
+
class SetStore(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
global store
- store=values
+ store = values
setattr(namespace, self.dest, values)
+
class seParser(argparse.ArgumentParser):
+
def error(self, message):
if len(sys.argv) == 2:
self.print_help()
@@ -87,7 +102,9 @@ class seParser(argparse.ArgumentParser):
self.print_usage()
self.exit(2, ('%s: error: %s\n') % (self.prog, message))
+
class SetExportFile(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
if values:
if values is not "-":
@@ -98,74 +115,89 @@ class SetExportFile(argparse.Action):
sys.exit(1)
setattr(namespace, self.dest, values)
+
class SetImportFile(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
if values and values is not "-":
- try:
- sys.stdin = open(values, 'r')
- except IOError,e:
- sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
- sys.exit(1)
+ try:
+ sys.stdin = open(values, 'r')
+ except IOError as e:
+ sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
+ sys.exit(1)
setattr(namespace, self.dest, values)
# functions for OBJECT initialization
+
+
def login_ini():
OBJECT = seobject.loginRecords(store)
return OBJECT
+
def user_ini():
OBJECT = seobject.seluserRecords(store)
return OBJECT
+
def port_ini():
OBJECT = seobject.portRecords(store)
return OBJECT
+
def module_ini():
OBJECT = seobject.moduleRecords(store)
return OBJECT
+
def interface_ini():
OBJECT = seobject.interfaceRecords(store)
return OBJECT
+
def node_ini():
OBJECT = seobject.nodeRecords(store)
return OBJECT
+
def fcontext_ini():
OBJECT = seobject.fcontextRecords(store)
return OBJECT
+
def boolean_ini():
OBJECT = seobject.booleanRecords(store)
return OBJECT
+
def permissive_ini():
OBJECT = seobject.permissiveRecords(store)
return OBJECT
+
def dontaudit_ini():
OBJECT = seobject.dontauditClass(store)
return OBJECT
# define dictonary for seobject OBEJCTS
-object_dict = {'login':login_ini, 'user':user_ini, 'port':port_ini, 'module':module_ini, 'interface':interface_ini, 'node':node_ini, 'fcontext':fcontext_ini, 'boolean':boolean_ini,'permissive':permissive_ini, 'dontaudit':dontaudit_ini}
+object_dict = {'login': login_ini, 'user': user_ini, 'port': port_ini, 'module': module_ini, 'interface': interface_ini, 'node': node_ini, 'fcontext': fcontext_ini, 'boolean': boolean_ini, 'permissive': permissive_ini, 'dontaudit': dontaudit_ini}
+
-def generate_custom_usage(usage_text,usage_dict):
+def generate_custom_usage(usage_text, usage_dict):
# generate custom usage from given text and dictonary
sorted_keys = []
for i in usage_dict.keys():
sorted_keys.append(i)
sorted_keys.sort()
for k in sorted_keys:
- usage_text += "%s %s |" % (k,(" ".join(usage_dict[k])))
+ usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
usage_text = usage_text[:-1] + "]"
usage_text = _(usage_text)
return usage_text
-def handle_opts(args,dict,target_key):
+
+def handle_opts(args, dict, target_key):
# handle conflict and required options for given dictonary
# {action:[conflict_opts,require_opts]}
@@ -173,24 +205,25 @@ def handle_opts(args,dict,target_key):
for k in args.__dict__.keys():
try:
if k in dict[target_key][0] and args.__dict__[k]:
- print("%s option can not be used with --%s" % (target_key,k))
+ print("%s option can not be used with --%s" % (target_key, k))
sys.exit(2)
except KeyError:
continue
for k in args.__dict__.keys():
try:
- if k in dict[target_key][1] and not args.__dict__[k]:
- print("%s option is needed for %s" % (k,target_key))
- sys.exit(2)
+ if k in dict[target_key][1] and not args.__dict__[k]:
+ print("%s option is needed for %s" % (k, target_key))
+ sys.exit(2)
except KeyError:
continue
+
def handleLogin(args):
# {action:[conflict_opts,require_opts]}
- login_args = {'list':[('login','seuser'),('')],'add':[('locallist'),('seuser','login')],'modify':[('locallist'),('login')], 'delete':[('locallist'),('login')],'extract':[('locallist','login','seuser'),('')],'deleteall':[('locallist'),('')]}
+ login_args = {'list': [('login', 'seuser'), ('')], 'add': [('locallist'), ('seuser', 'login')], 'modify': [('locallist'), ('login')], 'delete': [('locallist'), ('login')], 'extract': [('locallist', 'login', 'seuser'), ('')], 'deleteall': [('locallist'), ('')]}
- handle_opts(args,login_args,args.action)
+ handle_opts(args, login_args, args.action)
OBJECT = object_dict['login']()
OBJECT.set_reload(args.noreload)
@@ -207,62 +240,82 @@ def handleLogin(args):
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "login %s" % (str(i))
+ print("login %s" % (str(i)))
+
def parser_add_store(parser, name):
parser.add_argument('-S', '--store', action=SetStore, help=_("Select an alternate SELinux Policy Store to manage"))
+
def parser_add_priority(parser, name):
parser.add_argument('-P', '--priority', type=int, default=400, help=_("Select a priority for module operations"))
+
def parser_add_noheading(parser, name):
- parser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing %s object types") % name )
+ parser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing %s object types") % name)
+
def parser_add_noreload(parser, name):
parser.add_argument('-N', '--noreload', action='store_false', default=True, help=_('Do not reload policy after commit'))
+
def parser_add_locallist(parser, name):
- parser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List %s local customizations") % name )
+ parser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List %s local customizations") % name)
+
def parser_add_add(parser, name):
- parser.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the %s object type") % name )
+ parser.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the %s object type") % name)
+
def parser_add_type(parser, name):
parser.add_argument('-t', '--type', help=_('SELinux Type for the object'))
+
+
def parser_add_level(parser, name):
parser.add_argument('-L', '--level', default='s0', help=_('Default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)'))
+
+
def parser_add_range(parser, name):
parser.add_argument('-r', '--range', default="s0",
- help=_('''
+ help=_('''
MLS/MCS Security Range (MLS/MCS Systems only)
SELinux Range for SELinux login mapping
defaults to the SELinux user record range.
SELinux Range for SELinux user defaults to s0.
'''))
+
+
def parser_add_proto(parser, name):
parser.add_argument('-p', '--proto', help=_('''
Protocol for the specified port (tcp|udp) or internet protocol
version for the specified node (ipv4|ipv6).
'''))
+
def parser_add_modify(parser, name):
- parser.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the %s object type") % name )
+ parser.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the %s object type") % name)
+
def parser_add_list(parser, name):
- parser.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the %s object type") % name )
+ parser.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the %s object type") % name)
+
def parser_add_delete(parser, name):
- parser.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the %s object type") % name )
+ parser.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the %s object type") % name)
+
def parser_add_extract(parser, name):
parser.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_("Extract customizable commands, for use within a transaction"))
+
def parser_add_deleteall(parser, name):
- parser.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all %s objects local customizations') % name )
+ parser.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all %s objects local customizations') % name)
+
def parser_add_seuser(parser, name):
parser.add_argument('-s', '--seuser', default="", help=_("SELinux user name"))
+
def setupLoginParser(subparsers):
generated_usage = generate_custom_usage(usage_login, usage_login_dict)
loginParser = subparsers.add_parser('login', usage=generated_usage, help=_("Manage login mappings between linux users and SELinux confined users"))
@@ -286,13 +339,14 @@ def setupLoginParser(subparsers):
loginParser.set_defaults(func=handleLogin)
+
def handleFcontext(args):
- fcontext_args = {'list':[('equal','ftype','seuser','type'),('')],'add':[('locallist'),('type','file_spec')],'modify':[('locallist'),('type','file_spec')], 'delete':[('locallist'), ('file_spec')],'extract':[('locallist','equal','ftype','seuser','type'),('')],'deleteall':[('locallist'),('')]}
+ fcontext_args = {'list': [('equal', 'ftype', 'seuser', 'type'), ('')], 'add': [('locallist'), ('type', 'file_spec')], 'modify': [('locallist'), ('type', 'file_spec')], 'delete': [('locallist'), ('file_spec')], 'extract': [('locallist', 'equal', 'ftype', 'seuser', 'type'), ('')], 'deleteall': [('locallist'), ('')]}
# we can not use mutually for equal because we can define some actions together with equal
- fcontext_equal_args = {'equal':[('list','locallist','type','ftype','seuser','deleteall','extract'),()]}
+ fcontext_equal_args = {'equal': [('list', 'locallist', 'type', 'ftype', 'seuser', 'deleteall', 'extract'), ()]}
if args.action is None:
- print("usage: "+"%s" % generate_custom_usage(usage_fcontext, usage_fcontext_dict))
+ print("usage: " + "%s" % generate_custom_usage(usage_fcontext, usage_fcontext_dict))
sys.exit(2)
elif args.action and args.equal:
handle_opts(args, fcontext_equal_args, "equal")
@@ -316,14 +370,15 @@ def handleFcontext(args):
if args.equal:
OBJECT.delete(args.file_spec, args.equal)
else:
- OBJECT.delete(args.file_spec,args.ftype)
+ OBJECT.delete(args.file_spec, args.ftype)
if args.action is "list":
OBJECT.list(args.noheading, args.locallist)
if args.action is "deleteall":
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "fcontext %s" % str(i)
+ print("fcontext %s" % str(i))
+
def setupFcontextParser(subparsers):
ftype_help = '''
@@ -336,7 +391,7 @@ file type options can be passed:
If you do not specify a file type, the file type will default to "all files".
'''
generate_usage = generate_custom_usage(usage_fcontext, usage_fcontext_dict)
- fcontextParser = subparsers.add_parser('fcontext',usage=generate_usage, help=_("Manage file context mapping definitions"))
+ fcontextParser = subparsers.add_parser('fcontext', usage=generate_usage, help=_("Manage file context mapping definitions"))
parser_add_locallist(fcontextParser, "fcontext")
parser_add_noheading(fcontextParser, "fcontext")
parser_add_noreload(fcontextParser, "fcontext")
@@ -354,25 +409,26 @@ If you do not specify a file type, the file type will default to "all files".
label. This is used with fcontext. Requires source and target
path arguments. The context labeling for the target subtree is
made equivalent to that defined for the source.'''))
- fcontextParser.add_argument('-f', '--ftype', default="", choices=["a","f","d","c","b","s","l","p"], help=_(ftype_help))
+ fcontextParser.add_argument('-f', '--ftype', default="", choices=["a", "f", "d", "c", "b", "s", "l", "p"], help=_(ftype_help))
parser_add_seuser(fcontextParser, "fcontext")
parser_add_type(fcontextParser, "fcontext")
parser_add_range(fcontextParser, "fcontext")
fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('file_spec'))
fcontextParser.set_defaults(func=handleFcontext)
+
def handleUser(args):
- user_args = {'list':[('selinux_name','seuser','roles'),('')],'add':[('locallist'),('roles','selinux_name')],'modify':[('locallist'),('selinux_name')], 'delete':[('locallist'),('selinux_name')],'extract':[('locallist','selinux_name','seuser','role'),('')],'deleteall':[('locallist'),('')]}
+ user_args = {'list': [('selinux_name', 'seuser', 'roles'), ('')], 'add': [('locallist'), ('roles', 'selinux_name')], 'modify': [('locallist'), ('selinux_name')], 'delete': [('locallist'), ('selinux_name')], 'extract': [('locallist', 'selinux_name', 'seuser', 'role'), ('')], 'deleteall': [('locallist'), ('')]}
- handle_opts(args,user_args,args.action)
+ handle_opts(args, user_args, args.action)
OBJECT = object_dict['user']()
OBJECT.set_reload(args.noreload)
if args.action is "add":
- OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix)
+ OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix)
if args.action is "modify":
- OBJECT.modify(args.selinux_name, args.roles, args.level, args.range, args.prefix)
+ OBJECT.modify(args.selinux_name, args.roles, args.level, args.range, args.prefix)
if args.action is "delete":
OBJECT.delete(args.selinux_name)
if args.action is "list":
@@ -381,11 +437,12 @@ def handleUser(args):
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "user %s" % str(i)
+ print("user %s" % str(i))
+
def setupUserParser(subparsers):
generated_usage = generate_custom_usage(usage_user, usage_user_dict)
- userParser = subparsers.add_parser('user', usage=generated_usage,help=_('Manage SELinux confined users (Roles and levels for an SELinux user)'))
+ userParser = subparsers.add_parser('user', usage=generated_usage, help=_('Manage SELinux confined users (Roles and levels for an SELinux user)'))
parser_add_locallist(userParser, "user")
parser_add_noheading(userParser, "user")
parser_add_noreload(userParser, "user")
@@ -406,14 +463,15 @@ def setupUserParser(subparsers):
help=_('''
SELinux Roles. You must enclose multiple roles within quotes, separate by spaces. Or specify -R multiple times.
'''))
- userParser.add_argument('-P', '--prefix', default="user", help=argparse.SUPPRESS)
+ userParser.add_argument('-P', '--prefix', default="user", help=argparse.SUPPRESS)
userParser.add_argument('selinux_name', nargs='?', default=None, help=_('selinux_name'))
userParser.set_defaults(func=handleUser)
+
def handlePort(args):
- port_args = {'list':[('port','type','proto'),('')],'add':[('locallist'),('type','port','proto')],'modify':[('localist'),('port','proto')], 'delete':[('locallist'),('port','proto')],'extract':[('locallist','port','type','proto'),('')],'deleteall':[('locallist'),('')]}
+ port_args = {'list': [('port', 'type', 'proto'), ('')], 'add': [('locallist'), ('type', 'port', 'proto')], 'modify': [('localist'), ('port', 'proto')], 'delete': [('locallist'), ('port', 'proto')], 'extract': [('locallist', 'port', 'type', 'proto'), ('')], 'deleteall': [('locallist'), ('')]}
- handle_opts(args,port_args,args.action)
+ handle_opts(args, port_args, args.action)
OBJECT = object_dict['port']()
OBJECT.set_reload(args.noreload)
@@ -430,7 +488,8 @@ def handlePort(args):
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "port %s" % str(i)
+ print("port %s" % str(i))
+
def setupPortParser(subparsers):
generated_usage = generate_custom_usage(usage_port, usage_port_dict)
@@ -453,10 +512,11 @@ def setupPortParser(subparsers):
portParser.add_argument('port', nargs='?', default=None, help=_('port | port_range'))
portParser.set_defaults(func=handlePort)
+
def handleInterface(args):
- interface_args = {'list':[('interface'),('')],'add':[('locallist'),('type','interface')],'modify':[('locallist'),('type','interface')], 'delete':[('locallist'),('interface')],'extract':[('locallist','interface','type'),('')],'deleteall':[('locallist'),('')]}
+ interface_args = {'list': [('interface'), ('')], 'add': [('locallist'), ('type', 'interface')], 'modify': [('locallist'), ('type', 'interface')], 'delete': [('locallist'), ('interface')], 'extract': [('locallist', 'interface', 'type'), ('')], 'deleteall': [('locallist'), ('')]}
- handle_opts(args,interface_args,args.action)
+ handle_opts(args, interface_args, args.action)
OBJECT = object_dict['interface']()
OBJECT.set_reload(args.noreload)
@@ -473,7 +533,8 @@ def handleInterface(args):
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "interface %s" % str(i)
+ print("interface %s" % str(i))
+
def setupInterfaceParser(subparsers):
generated_usage = generate_custom_usage(usage_interface, usage_interface_dict)
@@ -495,6 +556,7 @@ def setupInterfaceParser(subparsers):
interfaceParser.add_argument('interface', nargs='?', default=None, help=_('interface_spec'))
interfaceParser.set_defaults(func=handleInterface)
+
def handleModule(args):
OBJECT = seobject.moduleRecords(store)
OBJECT.set_reload(args.noreload)
@@ -512,7 +574,8 @@ def handleModule(args):
OBJECT.list(args.noheading, args.locallist)
if args.action is "extract":
for i in OBJECT.customized():
- print "module %s" % str(i)
+ print("module %s" % str(i))
+
def setupModuleParser(subparsers):
moduleParser = subparsers.add_parser('module', help=_('Manage SELinux policy modules'))
@@ -533,9 +596,10 @@ def setupModuleParser(subparsers):
moduleParser.add_argument('module_name', nargs='?', default=None, help=_('Name of the module to act on'))
moduleParser.set_defaults(func=handleModule)
+
def handleNode(args):
- node_args = {'list':[('node','type','proto','netmask'),('')],'add':[('locallist'),('type','node','proto','netmask')],'modify':[('locallist'),('node','netmask','proto')], 'delete':[('locallist'),('node','netmask','prototype')],'extract':[('locallist','node','type','proto','netmask'),('')],'deleteall':[('locallist'),('')]}
- handle_opts(args,node_args,args.action)
+ node_args = {'list': [('node', 'type', 'proto', 'netmask'), ('')], 'add': [('locallist'), ('type', 'node', 'proto', 'netmask')], 'modify': [('locallist'), ('node', 'netmask', 'proto')], 'delete': [('locallist'), ('node', 'netmask', 'prototype')], 'extract': [('locallist', 'node', 'type', 'proto', 'netmask'), ('')], 'deleteall': [('locallist'), ('')]}
+ handle_opts(args, node_args, args.action)
OBJECT = object_dict['node']()
OBJECT.set_reload(args.noreload)
@@ -552,7 +616,8 @@ def handleNode(args):
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "node %s" % str(i)
+ print("node %s" % str(i))
+
def setupNodeParser(subparsers):
generated_usage = generate_custom_usage(usage_node, usage_node_dict)
@@ -570,45 +635,47 @@ def setupNodeParser(subparsers):
parser_add_extract(node_action, "node")
parser_add_deleteall(node_action, "node")
- nodeParser.add_argument('-M', '--netmask', help=_('Network Mask'))
+ nodeParser.add_argument('-M', '--netmask', help=_('Network Mask'))
parser_add_type(nodeParser, "node")
parser_add_range(nodeParser, "node")
parser_add_proto(nodeParser, "node")
nodeParser.add_argument('node', nargs='?', default=None, help=_('node'))
nodeParser.set_defaults(func=handleNode)
+
def handleBoolean(args):
- boolean_args = {'list':[('state','boolean'),('')],'modify':[('localist'),('')], 'extract':[('locallist','state','boolean'),('')],'deleteall':[('locallist'),('')],'state':[('locallist','list','extract','deleteall'),('modify')]}
+ boolean_args = {'list': [('state', 'boolean'), ('')], 'modify': [('localist'), ('')], 'extract': [('locallist', 'state', 'boolean'), ('')], 'deleteall': [('locallist'), ('')], 'state': [('locallist', 'list', 'extract', 'deleteall'), ('modify')]}
if args.action is None:
- print("Usage: "+"%s" % generate_custom_usage(usage_boolean, usage_boolean_dict))
+ print("Usage: " + "%s" % generate_custom_usage(usage_boolean, usage_boolean_dict))
sys.exit(2)
# TODO: should be added to handle_opts logic
elif args.action is "modify" and not args.boolean:
- print "boolean name required "
+ print("boolean name required ")
sys.exit(1)
elif args.action is "modify" and args.boolean and not args.state:
- print "state option is needed"
+ print("state option is needed")
sys.exit(1)
else:
- handle_opts(args,boolean_args,args.action)
+ handle_opts(args, boolean_args, args.action)
OBJECT = object_dict['boolean']()
OBJECT.set_reload(args.noreload)
if args.action is "modify":
if args.boolean:
- OBJECT.modify(args.boolean, args.state, False)
+ OBJECT.modify(args.boolean, args.state, False)
if args.action is "list":
OBJECT.list(args.noheading, args.locallist)
if args.action is "deleteall":
OBJECT.deleteall()
if args.action is "extract":
for i in OBJECT.customized():
- print "boolean %s" % str(i)
+ print("boolean %s" % str(i))
+
def setupBooleanParser(subparsers):
generated_usage = generate_custom_usage(usage_boolean, usage_boolean_dict)
- booleanParser = subparsers.add_parser('boolean',usage=generated_usage, help=_('Manage booleans to selectively enable functionality'))
+ booleanParser = subparsers.add_parser('boolean', usage=generated_usage, help=_('Manage booleans to selectively enable functionality'))
parser_add_locallist(booleanParser, "boolean")
parser_add_noheading(booleanParser, "boolean")
parser_add_noreload(booleanParser, "boolean")
@@ -628,6 +695,7 @@ def setupBooleanParser(subparsers):
booleanParser.set_defaults(func=handleBoolean)
+
def handlePermissive(args):
OBJECT = object_dict['permissive']()
OBJECT.set_reload(args.noreload)
@@ -639,6 +707,7 @@ def handlePermissive(args):
if args.action is "delete":
OBJECT.delete(args.type)
+
def setupPermissiveParser(subparsers):
permissiveParser = subparsers.add_parser('permissive', help=_('Manage process type enforcement mode'))
@@ -655,11 +724,13 @@ def setupPermissiveParser(subparsers):
permissiveParser.add_argument('type', nargs='?', default=None, help=_('type'))
permissiveParser.set_defaults(func=handlePermissive)
+
def handleDontaudit(args):
OBJECT = object_dict['dontaudit']()
OBJECT.set_reload(args.noreload)
OBJECT.toggle(args.action)
+
def setupDontauditParser(subparsers):
dontauditParser = subparsers.add_parser('dontaudit', help=_('Disable/Enable dontaudit rules in policy'))
parser_add_noreload(dontauditParser, "dontaudit")
@@ -667,17 +738,19 @@ def setupDontauditParser(subparsers):
dontauditParser.add_argument('action', choices=["on", "off"])
dontauditParser.set_defaults(func=handleDontaudit)
+
def handleExport(args):
- manageditems=[ "boolean", "login", "interface", "user", "port", "node", "fcontext", "module"]
+ manageditems = ["boolean", "login", "interface", "user", "port", "node", "fcontext", "module"]
for i in manageditems:
- print "%s -D" % i
+ print("%s -D" % i)
for i in manageditems:
OBJECT = object_dict[i]()
for c in OBJECT.customized():
- print "%s %s" % (i, str(c))
+ print("%s %s" % (i, str(c)))
sys.exit(0)
+
def setupExportParser(subparsers):
exportParser = subparsers.add_parser('export', help=_('Output local customizations'))
parser_add_store(exportParser, "export")
@@ -685,6 +758,8 @@ def setupExportParser(subparsers):
exportParser.set_defaults(func=handleExport)
import re
+
+
def mkargv(line):
dquote = "\""
squote = "\'"
@@ -698,10 +773,10 @@ def mkargv(line):
i = i + 1
continue
if cnt == 1:
- quote = [ l[i].strip(dquote) ]
+ quote = [l[i].strip(dquote)]
i = i + 1
- while i < len(l) and dquote not in l[i]:
+ while i < len(l) and dquote not in l[i]:
quote.append(l[i])
i = i + 1
quote.append(l[i].strip(dquote))
@@ -715,9 +790,9 @@ def mkargv(line):
i = i + 1
continue
if cnt == 1:
- quote = [ l[i].strip(squote) ]
+ quote = [l[i].strip(squote)]
i = i + 1
- while i < len(l) and squote not in l[i]:
+ while i < len(l) and squote not in l[i]:
quote.append(l[i])
i = i + 1
@@ -731,22 +806,23 @@ def mkargv(line):
return ret
+
def handleImport(args):
trans = seobject.semanageRecords(store)
trans.start()
for l in sys.stdin.readlines():
if len(l.strip()) == 0:
- continue
+ continue
try:
commandParser = createCommandParser()
args = commandParser.parse_args(mkargv(l))
args.func(args)
- except ValueError,e:
+ except ValueError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
- except IOError,e:
+ except IOError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except KeyboardInterrupt:
@@ -755,6 +831,7 @@ def handleImport(args):
trans.set_reload(args.noreload)
trans.finish()
+
def setupImportParser(subparsers):
importParser = subparsers.add_parser('import', help=_('Output local customizations'))
parser_add_noreload(importParser, "import")
@@ -762,10 +839,11 @@ def setupImportParser(subparsers):
importParser.add_argument('-f', '--input_file', dest='input_file', action=SetImportFile, help=_('Input file'))
importParser.set_defaults(func=handleImport)
+
def createCommandParser():
commandParser = seParser(prog='semanage',
- formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- description='''semanage is used to configure certain elements
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ description='''semanage is used to configure certain elements
of SELinux policy with-out requiring modification
to or recompilation from policy source.''')
@@ -786,9 +864,10 @@ def createCommandParser():
return commandParser
+
def make_io_args(args):
# import/export backward compability
- args_origin = ["-S", "-o", "-i", "targeted", "minumum", "mls"]
+ args_origin = ["-S", "-o", "-i", "targeted", "minimum", "mls"]
args_file = []
args_ie = []
args_subcommand = []
@@ -805,40 +884,42 @@ def make_io_args(args):
continue
args_ie.append(i)
- return args_subcommand+args_ie+args_file
+ return args_subcommand + args_ie + args_file
+
def make_args(sys_args):
args = []
if "-o" in sys_args[1:] or "-i" in sys_args[1:]:
- args=make_io_args(sys_args[1:])
+ args = make_io_args(sys_args[1:])
else:
- args=sys_args[1:]
+ args = sys_args[1:]
return args
+
def do_parser():
try:
commandParser = createCommandParser()
args = commandParser.parse_args(make_args(sys.argv))
args.func(args)
sys.exit(0)
- except IOError,e:
+ except IOError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except KeyboardInterrupt:
sys.exit(0)
- except ValueError, e:
+ except ValueError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
sys.exit(1)
- except KeyError, e:
+ except KeyError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
sys.exit(1)
- except OSError, e:
+ except OSError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[1]))
sys.exit(1)
- except RuntimeError, e:
+ except RuntimeError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
sys.exit(1)
if __name__ == '__main__':
- do_parser()
+ do_parser()
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index 568ebfde..d29dba53 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -16,13 +16,22 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
+#
-import pwd, grp, string, selinux, tempfile, os, re, sys, stat, shutil
-from semanage import *;
+import pwd
+import grp
+import string
+import selinux
+import tempfile
+import os
+import re
+import sys
+import stat
+import shutil
+from semanage import *
PROGNAME = "policycoreutils"
import sepolicy
from sepolicy import boolean_desc, boolean_category, gen_bool_dict
@@ -34,2183 +43,2213 @@ gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
import gettext
-translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True)
-_=translation.ugettext
+translation = gettext.translation(PROGNAME, localedir="/usr/share/locale", fallback=True)
+_ = translation.ugettext
import syslog
file_types = {}
-file_types[""] = SEMANAGE_FCONTEXT_ALL;
-file_types["all files"] = SEMANAGE_FCONTEXT_ALL;
-file_types["a"] = SEMANAGE_FCONTEXT_ALL;
-file_types["regular file"] = SEMANAGE_FCONTEXT_REG;
-file_types["--"] = SEMANAGE_FCONTEXT_REG;
-file_types["f"] = SEMANAGE_FCONTEXT_REG;
-file_types["-d"] = SEMANAGE_FCONTEXT_DIR;
-file_types["directory"] = SEMANAGE_FCONTEXT_DIR;
-file_types["d"] = SEMANAGE_FCONTEXT_DIR;
-file_types["-c"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["character device"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["c"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["b"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["-s"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["socket"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["s"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["-l"] = SEMANAGE_FCONTEXT_LINK;
-file_types["l"] = SEMANAGE_FCONTEXT_LINK;
-file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK;
-file_types["p"] = SEMANAGE_FCONTEXT_PIPE;
-file_types["-p"] = SEMANAGE_FCONTEXT_PIPE;
-file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE;
-
-file_type_str_to_option = { "all files": "a",
- "regular file":"f",
- "directory":"d",
- "character device":"c",
- "block device":"b",
- "socket file":"s",
- "symbolic link":"l",
- "named pipe":"p" }
+file_types[""] = SEMANAGE_FCONTEXT_ALL
+file_types["all files"] = SEMANAGE_FCONTEXT_ALL
+file_types["a"] = SEMANAGE_FCONTEXT_ALL
+file_types["regular file"] = SEMANAGE_FCONTEXT_REG
+file_types["--"] = SEMANAGE_FCONTEXT_REG
+file_types["f"] = SEMANAGE_FCONTEXT_REG
+file_types["-d"] = SEMANAGE_FCONTEXT_DIR
+file_types["directory"] = SEMANAGE_FCONTEXT_DIR
+file_types["d"] = SEMANAGE_FCONTEXT_DIR
+file_types["-c"] = SEMANAGE_FCONTEXT_CHAR
+file_types["character device"] = SEMANAGE_FCONTEXT_CHAR
+file_types["c"] = SEMANAGE_FCONTEXT_CHAR
+file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["b"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["-s"] = SEMANAGE_FCONTEXT_SOCK
+file_types["socket"] = SEMANAGE_FCONTEXT_SOCK
+file_types["s"] = SEMANAGE_FCONTEXT_SOCK
+file_types["-l"] = SEMANAGE_FCONTEXT_LINK
+file_types["l"] = SEMANAGE_FCONTEXT_LINK
+file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK
+file_types["p"] = SEMANAGE_FCONTEXT_PIPE
+file_types["-p"] = SEMANAGE_FCONTEXT_PIPE
+file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE
+
+file_type_str_to_option = {"all files": "a",
+ "regular file": "f",
+ "directory": "d",
+ "character device": "c",
+ "block device": "b",
+ "socket file": "s",
+ "symbolic link": "l",
+ "named pipe": "p"}
try:
- import audit
- class logger:
- def __init__(self):
- self.audit_fd = audit.audit_open()
- self.log_list = []
- def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-
- sep = "-"
- if sename != oldsename:
- msg += sep + "sename"; sep = ","
- if serole != oldserole:
- msg += sep + "role"; sep = ","
- if serange != oldserange:
- msg += sep + "range"; sep = ","
-
- self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
-
- def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
- self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
-
- def commit(self,success):
- for l in self.log_list:
- audit.audit_log_semanage_message(*(l + [success]))
- self.log_list = []
+ import audit
+
+ class logger:
+
+ def __init__(self):
+ self.audit_fd = audit.audit_open()
+ self.log_list = []
+
+ def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+
+ sep = "-"
+ if sename != oldsename:
+ msg += sep + "sename"
+ sep = ","
+ if serole != oldserole:
+ msg += sep + "role"
+ sep = ","
+ if serange != oldserange:
+ msg += sep + "range"
+ sep = ","
+
+ self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+
+ def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+ self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+
+ def commit(self, success):
+ for l in self.log_list:
+ audit.audit_log_semanage_message(*(l + [success]))
+ self.log_list = []
except:
- class logger:
- def __init__(self):
- self.log_list=[]
-
- def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
- message = " %s name=%s" % (msg, name)
- if sename != "":
- message += " sename=" + sename
- if oldsename != "":
- message += " oldsename=" + oldsename
- if serole != "":
- message += " role=" + serole
- if oldserole != "":
- message += " old_role=" + oldserole
- if serange != "" and serange != None:
- message += " MLSRange=" + serange
- if oldserange != "" and oldserange != None:
- message += " old_MLSRange=" + oldserange
- self.log_list.append(message)
-
- def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
- self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
-
- def commit(self,success):
- if success == 1:
- message = "Successful: "
- else:
- message = "Failed: "
- for l in self.log_list:
- syslog.syslog(syslog.LOG_INFO, message + l)
+ class logger:
+
+ def __init__(self):
+ self.log_list = []
+
+ def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+ message = " %s name=%s" % (msg, name)
+ if sename != "":
+ message += " sename=" + sename
+ if oldsename != "":
+ message += " oldsename=" + oldsename
+ if serole != "":
+ message += " role=" + serole
+ if oldserole != "":
+ message += " old_role=" + oldserole
+ if serange != "" and serange != None:
+ message += " MLSRange=" + serange
+ if oldserange != "" and oldserange != None:
+ message += " old_MLSRange=" + oldserange
+ self.log_list.append(message)
+
+ def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+ self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
+
+ def commit(self, success):
+ if success == 1:
+ message = "Successful: "
+ else:
+ message = "Failed: "
+ for l in self.log_list:
+ syslog.syslog(syslog.LOG_INFO, message + l)
+
class nulllogger:
- def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
- pass
- def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
- pass
+ def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+ pass
+
+ def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+ pass
+
+ def commit(self, success):
+ pass
- def commit(self,success):
- pass
def validate_level(raw):
- sensitivity = "s[0-9]*"
- category = "c[0-9]*"
- cat_range = category + "(\." + category +")?"
- categories = cat_range + "(\," + cat_range + ")*"
- reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
- return re.search("^" + reg +"$", raw)
-
-def translate(raw, prepend = 1):
- filler = "a:b:c:"
- if prepend == 1:
- context = "%s%s" % (filler, raw)
- else:
- context = raw
- (rc, trans) = selinux.selinux_raw_to_trans_context(context)
- if rc != 0:
- return raw
- if prepend:
- trans = trans[len(filler):]
- if trans == "":
- return raw
- else:
- return trans
-
-def untranslate(trans, prepend = 1):
- filler = "a:b:c:"
- if prepend == 1:
- context = "%s%s" % (filler, trans)
- else:
- context = trans
-
- (rc, raw) = selinux.selinux_trans_to_raw_context(context)
- if rc != 0:
- return trans
- if prepend:
- raw = raw[len(filler):]
- if raw == "":
- return trans
- else:
- return raw
+ sensitivity = "s[0-9]*"
+ category = "c[0-9]*"
+ cat_range = category + "(\." + category + ")?"
+ categories = cat_range + "(\," + cat_range + ")*"
+ reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
+ return re.search("^" + reg + "$", raw)
+
+
+def translate(raw, prepend=1):
+ filler = "a:b:c:"
+ if prepend == 1:
+ context = "%s%s" % (filler, raw)
+ else:
+ context = raw
+ (rc, trans) = selinux.selinux_raw_to_trans_context(context)
+ if rc != 0:
+ return raw
+ if prepend:
+ trans = trans[len(filler):]
+ if trans == "":
+ return raw
+ else:
+ return trans
+
+
+def untranslate(trans, prepend=1):
+ filler = "a:b:c:"
+ if prepend == 1:
+ context = "%s%s" % (filler, trans)
+ else:
+ context = trans
+
+ (rc, raw) = selinux.selinux_trans_to_raw_context(context)
+ if rc != 0:
+ return trans
+ if prepend:
+ raw = raw[len(filler):]
+ if raw == "":
+ return trans
+ else:
+ return raw
+
class semanageRecords:
- transaction = False
- handle = None
- store = None
- def __init__(self, store):
- global handle
- self.load = True
- self.sh = self.get_handle(store)
-
- rc, localstore = selinux.selinux_getpolicytype()
- if store == "" or store == localstore:
- self.mylog = logger()
- else:
- self.mylog = nulllogger()
-
- def set_reload(self, load):
- self.load = load
-
- def get_handle(self, store):
- global is_mls_enabled
-
- if semanageRecords.handle:
- return semanageRecords.handle
-
- handle = semanage_handle_create()
- if not handle:
- raise ValueError(_("Could not create semanage handle"))
-
- if not semanageRecords.transaction and store != "":
- semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
- semanageRecords.store = store
-
- if not semanage_is_managed(handle):
- semanage_handle_destroy(handle)
- raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
-
- rc = semanage_access_check(handle)
- if rc < SEMANAGE_CAN_READ:
- semanage_handle_destroy(handle)
- raise ValueError(_("Cannot read policy store."))
-
- rc = semanage_connect(handle)
- if rc < 0:
- semanage_handle_destroy(handle)
- raise ValueError(_("Could not establish semanage connection"))
-
- is_mls_enabled = semanage_mls_enabled(handle)
- if is_mls_enabled < 0:
- semanage_handle_destroy(handle)
- raise ValueError(_("Could not test MLS enabled status"))
-
- semanageRecords.handle = handle
- return semanageRecords.handle
-
- def deleteall(self):
- raise ValueError(_("Not yet implemented"))
-
- def start(self):
- if semanageRecords.transaction:
- raise ValueError(_("Semanage transaction already in progress"))
- self.begin()
- semanageRecords.transaction = True
-
- def begin(self):
- if semanageRecords.transaction:
- return
- rc = semanage_begin_transaction(self.sh)
- if rc < 0:
- raise ValueError(_("Could not start semanage transaction"))
- def customized(self):
- raise ValueError(_("Not yet implemented"))
-
- def commit(self):
- if semanageRecords.transaction:
- return
-
- semanage_set_reload(self.sh, self.load)
- rc = semanage_commit(self.sh)
- if rc < 0:
- self.mylog.commit(0)
- raise ValueError(_("Could not commit semanage transaction"))
- self.mylog.commit(1)
-
- def finish(self):
- if not semanageRecords.transaction:
- raise ValueError(_("Semanage transaction not in progress"))
- semanageRecords.transaction = False
- self.commit()
+ transaction = False
+ handle = None
+ store = None
+
+ def __init__(self, store):
+ global handle
+ self.load = True
+ self.sh = self.get_handle(store)
+
+ rc, localstore = selinux.selinux_getpolicytype()
+ if store == "" or store == localstore:
+ self.mylog = logger()
+ else:
+ self.mylog = nulllogger()
+
+ def set_reload(self, load):
+ self.load = load
+
+ def get_handle(self, store):
+ global is_mls_enabled
+
+ if semanageRecords.handle:
+ return semanageRecords.handle
+
+ handle = semanage_handle_create()
+ if not handle:
+ raise ValueError(_("Could not create semanage handle"))
+
+ if not semanageRecords.transaction and store != "":
+ semanage_select_store(handle, store, SEMANAGE_CON_DIRECT)
+ semanageRecords.store = store
+
+ if not semanage_is_managed(handle):
+ semanage_handle_destroy(handle)
+ raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
+
+ rc = semanage_access_check(handle)
+ if rc < SEMANAGE_CAN_READ:
+ semanage_handle_destroy(handle)
+ raise ValueError(_("Cannot read policy store."))
+
+ rc = semanage_connect(handle)
+ if rc < 0:
+ semanage_handle_destroy(handle)
+ raise ValueError(_("Could not establish semanage connection"))
+
+ is_mls_enabled = semanage_mls_enabled(handle)
+ if is_mls_enabled < 0:
+ semanage_handle_destroy(handle)
+ raise ValueError(_("Could not test MLS enabled status"))
+
+ semanageRecords.handle = handle
+ return semanageRecords.handle
+
+ def deleteall(self):
+ raise ValueError(_("Not yet implemented"))
+
+ def start(self):
+ if semanageRecords.transaction:
+ raise ValueError(_("Semanage transaction already in progress"))
+ self.begin()
+ semanageRecords.transaction = True
+
+ def begin(self):
+ if semanageRecords.transaction:
+ return
+ rc = semanage_begin_transaction(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not start semanage transaction"))
+
+ def customized(self):
+ raise ValueError(_("Not yet implemented"))
+
+ def commit(self):
+ if semanageRecords.transaction:
+ return
+
+ semanage_set_reload(self.sh, self.load)
+ rc = semanage_commit(self.sh)
+ if rc < 0:
+ self.mylog.commit(0)
+ raise ValueError(_("Could not commit semanage transaction"))
+ self.mylog.commit(1)
+
+ def finish(self):
+ if not semanageRecords.transaction:
+ raise ValueError(_("Semanage transaction not in progress"))
+ semanageRecords.transaction = False
+ self.commit()
-class moduleRecords(semanageRecords):
- def __init__(self, store):
- semanageRecords.__init__(self, store)
-
- def get_all(self):
- l = []
- (rc, mlist, number) = semanage_module_list_all(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list SELinux modules"))
-
- for i in range(number):
- mod = semanage_module_list_nth(mlist, i)
-
- rc, name = semanage_module_info_get_name(self.sh, mod)
- if rc < 0:
- raise ValueError(_("Could not get module name"))
-
- rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
- if rc < 0:
- raise ValueError(_("Could not get module enabled"))
-
- rc, priority = semanage_module_info_get_priority(self.sh, mod)
- if rc < 0:
- raise ValueError(_("Could not get module priority"))
-
- rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
- if rc < 0:
- raise ValueError(_("Could not get module lang_ext"))
-
- l.append((name, enabled, priority, lang_ext))
-
- # sort the list so they are in name order, but with higher priorities coming first
- l.sort(key = lambda t: t[3], reverse=True)
- l.sort(key = lambda t: t[0])
- return l
-
- def customized(self):
- all = self.get_all()
- if len(all) == 0:
- return
- return map(lambda x: "-d %s" % x[0], filter(lambda t: t[1] == 0, all))
-
- def list(self, heading = 1, locallist = 0):
- all = self.get_all()
- if len(all) == 0:
- return
-
- if heading:
- print "\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))
- for t in all:
- if t[1] == 0:
- disabled = _("Disabled")
- else:
- if locallist:
- continue
- disabled = ""
- print "%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)
-
- def add(self, file, priority):
- if not os.path.exists(file):
- raise ValueError(_("Module does not exists %s ") % file)
-
- rc = semanage_set_default_priority(self.sh, priority)
- if rc < 0:
- raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
-
- rc = semanage_module_install_file(self.sh, file);
- if rc >= 0:
- self.commit()
-
- def set_enabled(self, module, enable):
- for m in module.split():
- rc, key = semanage_module_key_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create module key"))
-
- rc = semanage_module_key_set_name(self.sh, key, m)
- if rc < 0:
- raise ValueError(_("Could not set module key name"))
-
- rc = semanage_module_set_enabled(self.sh, key, enable)
- if rc < 0:
- if enable:
- raise ValueError(_("Could not enable module %s") % m)
- else:
- raise ValueError(_("Could not disable module %s") % m)
- self.commit()
-
- def modify(self, file):
- rc = semanage_module_update_file(self.sh, file);
- if rc >= 0:
- self.commit()
-
- def delete(self, module, priority):
- rc = semanage_set_default_priority(self.sh, priority)
- if rc < 0:
- raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
-
- for m in module.split():
- rc = semanage_module_remove(self.sh, m)
- if rc < 0 and rc != -2:
- raise ValueError(_("Could not remove module %s (remove failed)") % m)
-
- self.commit()
-
- def deleteall(self):
- l = map(lambda x: x[0], filter(lambda t: t[1] == 0, self.get_all()))
- for m in l:
- self.enable(m)
-class dontauditClass(semanageRecords):
- def __init__(self, store):
- semanageRecords.__init__(self, store)
-
- def toggle(self, dontaudit):
- if dontaudit not in [ "on", "off" ]:
- raise ValueError(_("dontaudit requires either 'on' or 'off'"))
- self.begin()
- rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
- self.commit()
-
-class permissiveRecords(semanageRecords):
- def __init__(self, store):
- semanageRecords.__init__(self, store)
-
- def get_all(self):
- l = []
- (rc, mlist, number) = semanage_module_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list SELinux modules"))
-
- for i in range(number):
- mod = semanage_module_list_nth(mlist, i)
- name = semanage_module_get_name(mod)
- if name and name.startswith("permissive_"):
- l.append(name.split("permissive_")[1])
- return l
-
- def list(self, heading = 1, locallist = 0):
- all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE)))
- if len(all) == 0:
- return
-
- if heading:
- print "\n%-25s\n" % (_("Builtin Permissive Types"))
- customized = self.get_all()
- for t in all:
- if t not in customized:
- print t
-
- if len(customized) == 0:
- return
-
- if heading:
- print "\n%-25s\n" % (_("Customized Permissive Types"))
- for t in customized:
- print t
-
- def add(self, type):
- import glob
- try:
- import sepolgen.module as module
- except ImportError:
- raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro."))
-
- name = "permissive_%s" % type
- modtxt = "(typepermissive %s)" % type
-
- rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil");
- if rc >= 0:
- self.commit()
-
- if rc < 0:
- raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
-
- def delete(self, name):
- for n in name.split():
- rc = semanage_module_remove(self.sh, "permissive_%s" % n)
- if rc < 0:
- raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
-
- self.commit()
-
- def deleteall(self):
- l = self.get_all()
- if len(l) > 0:
- all = " ".join(l)
- self.delete(all)
+class moduleRecords(semanageRecords):
-class loginRecords(semanageRecords):
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
- self.oldsename = None
- self.oldserange = None
- self.sename = None
- self.serange = None
-
- def __add(self, name, sename, serange):
- rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
- if sename == "":
- sename = "user_u"
-
- userrec = seluserRecords()
- range, (rc, oldserole) = userrec.get(self.oldsename)
- range, (rc, serole) = userrec.get(sename)
-
- if is_mls_enabled == 1:
- if serange != "":
- serange = untranslate(serange)
- else:
- serange = range
-
- (rc, k) = semanage_seuser_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
-
- (rc, exists) = semanage_seuser_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
- if exists:
- raise ValueError(_("Login mapping for %s is already defined") % name)
- if name[0] == '%':
- try:
- grp.getgrnam(name[1:])
- except:
- raise ValueError(_("Linux Group %s does not exist") % name[1:])
+ def __init__(self, store):
+ semanageRecords.__init__(self, store)
+
+ def get_all(self):
+ l = []
+ (rc, mlist, number) = semanage_module_list_all(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list SELinux modules"))
+
+ for i in range(number):
+ mod = semanage_module_list_nth(mlist, i)
+
+ rc, name = semanage_module_info_get_name(self.sh, mod)
+ if rc < 0:
+ raise ValueError(_("Could not get module name"))
+
+ rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
+ if rc < 0:
+ raise ValueError(_("Could not get module enabled"))
+
+ rc, priority = semanage_module_info_get_priority(self.sh, mod)
+ if rc < 0:
+ raise ValueError(_("Could not get module priority"))
+
+ rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
+ if rc < 0:
+ raise ValueError(_("Could not get module lang_ext"))
+
+ l.append((name, enabled, priority, lang_ext))
+
+ # sort the list so they are in name order, but with higher priorities coming first
+ l.sort(key=lambda t: t[3], reverse=True)
+ l.sort(key=lambda t: t[0])
+ return l
+
+ def customized(self):
+ all = self.get_all()
+ if len(all) == 0:
+ return
+ return map(lambda x: "-d %s" % x[0], filter(lambda t: t[1] == 0, all))
+
+ def list(self, heading=1, locallist=0):
+ all = self.get_all()
+ if len(all) == 0:
+ return
+
+ if heading:
+ print "\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))
+ for t in all:
+ if t[1] == 0:
+ disabled = _("Disabled")
+ else:
+ if locallist:
+ continue
+ disabled = ""
+ print "%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)
+
+ def add(self, file, priority):
+ if not os.path.exists(file):
+ raise ValueError(_("Module does not exists %s ") % file)
+
+ rc = semanage_set_default_priority(self.sh, priority)
+ if rc < 0:
+ raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
+
+ rc = semanage_module_install_file(self.sh, file)
+ if rc >= 0:
+ self.commit()
+
+ def set_enabled(self, module, enable):
+ for m in module.split():
+ rc, key = semanage_module_key_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create module key"))
+
+ rc = semanage_module_key_set_name(self.sh, key, m)
+ if rc < 0:
+ raise ValueError(_("Could not set module key name"))
+
+ rc = semanage_module_set_enabled(self.sh, key, enable)
+ if rc < 0:
+ if enable:
+ raise ValueError(_("Could not enable module %s") % m)
else:
- try:
- pwd.getpwnam(name)
- except:
- raise ValueError(_("Linux User %s does not exist") % name)
+ raise ValueError(_("Could not disable module %s") % m)
+ self.commit()
- (rc, u) = semanage_seuser_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create login mapping for %s") % name)
+ def modify(self, file):
+ rc = semanage_module_update_file(self.sh, file)
+ if rc >= 0:
+ self.commit()
- rc = semanage_seuser_set_name(self.sh, u, name)
- if rc < 0:
- raise ValueError(_("Could not set name for %s") % name)
+ def delete(self, module, priority):
+ rc = semanage_set_default_priority(self.sh, priority)
+ if rc < 0:
+ raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
- if (is_mls_enabled == 1) and (serange != ""):
- rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
- if rc < 0:
- raise ValueError(_("Could not set MLS range for %s") % name)
+ for m in module.split():
+ rc = semanage_module_remove(self.sh, m)
+ if rc < 0 and rc != -2:
+ raise ValueError(_("Could not remove module %s (remove failed)") % m)
- rc = semanage_seuser_set_sename(self.sh, u, sename)
- if rc < 0:
- raise ValueError(_("Could not set SELinux user for %s") % name)
+ self.commit()
- rc = semanage_seuser_modify_local(self.sh, k, u)
- if rc < 0:
- raise ValueError(_("Could not add login mapping for %s") % name)
-
- semanage_seuser_key_free(k)
- semanage_seuser_free(u)
- self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
-
- def add(self, name, sename, serange):
- try:
- self.begin()
- self.__add(name, sename, serange)
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def __modify(self, name, sename = "", serange = ""):
- rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
- if sename == "" and serange == "":
- raise ValueError(_("Requires seuser or serange"))
-
- userrec = seluserRecords()
- range, (rc, oldserole) = userrec.get(self.oldsename)
-
- if sename != "":
- range, (rc, serole) = userrec.get(sename)
- else:
- serole=oldserole
-
- if serange != "":
- self.serange=serange
- else:
- self.serange=range
-
- (rc, k) = semanage_seuser_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
-
- (rc, exists) = semanage_seuser_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
- if not exists:
- raise ValueError(_("Login mapping for %s is not defined") % name)
-
- (rc, u) = semanage_seuser_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query seuser for %s") % name)
-
- self.oldserange = semanage_seuser_get_mlsrange(u)
- self.oldsename = semanage_seuser_get_sename(u)
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
-
- if sename != "":
- semanage_seuser_set_sename(self.sh, u, sename)
- else:
- self.sename = self.oldsename
-
- rc = semanage_seuser_modify_local(self.sh, k, u)
- if rc < 0:
- raise ValueError(_("Could not modify login mapping for %s") % name)
-
- semanage_seuser_key_free(k)
- semanage_seuser_free(u)
- self.mylog.log("login", name,sename=self.sename,serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
-
- def modify(self, name, sename = "", serange = ""):
- try:
- self.begin()
- self.__modify(name, sename, serange)
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def __delete(self, name):
- rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
- userrec = seluserRecords()
- range, (rc, oldserole) = userrec.get(self.oldsename)
-
- (rc, k) = semanage_seuser_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
-
- (rc, exists) = semanage_seuser_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
- if not exists:
- raise ValueError(_("Login mapping for %s is not defined") % name)
-
- (rc, exists) = semanage_seuser_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if login mapping for %s is defined") % name)
- if not exists:
- raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
-
- rc = semanage_seuser_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete login mapping for %s") % name)
-
- semanage_seuser_key_free(k)
-
- rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
- range, (rc, serole) = userrec.get(self.sename)
-
- self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
-
- def delete(self, name):
- try:
- self.begin()
- self.__delete(name)
- self.commit()
-
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def deleteall(self):
- (rc, ulist) = semanage_seuser_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list login mappings"))
-
- try:
- self.begin()
- for u in ulist:
- self.__delete(semanage_seuser_get_name(u))
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def get_all_logins(self):
- ddict = {}
- self.logins_path = selinux.selinux_policy_root() + "/logins"
- for path,dirs,files in os.walk(self.logins_path):
- if path == self.logins_path:
- for name in files:
- try:
- fd = open(path + "/" + name)
- rec = fd.read().rstrip().split(":")
- fd.close()
- ddict[name] = (rec[1], rec[2], rec[0])
- except IndexError:
- pass
- return ddict
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.ulist) = semanage_seuser_list_local(self.sh)
- else:
- (rc, self.ulist) = semanage_seuser_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list login mappings"))
-
- for u in self.ulist:
- name = semanage_seuser_get_name(u)
- ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
- return ddict
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
- return l
-
- def list(self,heading = 1, locallist = 0):
- ddict = self.get_all(locallist)
- ldict = self.get_all_logins()
- lkeys = ldict.keys()
- keys = ddict.keys()
- if len(keys) == 0 and len(lkeys) == 0:
- return
- keys.sort()
- lkeys.sort()
-
- if is_mls_enabled == 1:
- if heading:
- print "\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))
- for k in keys:
- u = ddict[k]
- print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
- if len(lkeys):
- print "\nLocal customization in %s" % self.logins_path
-
- for k in lkeys:
- u = ldict[k]
- print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
- else:
- if heading:
- print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
- for k in keys:
- print "%-25s %-25s" % (k, ddict[k][0])
+ def deleteall(self):
+ l = map(lambda x: x[0], filter(lambda t: t[1] == 0, self.get_all()))
+ for m in l:
+ self.set_enabled(m, True)
-class seluserRecords(semanageRecords):
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
- def get(self, name):
- (rc, k) = semanage_user_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
- (rc, exists) = semanage_user_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if SELinux user %s is defined") % name)
- (rc, u) = semanage_user_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query user for %s") % name)
- serange = semanage_user_get_mlsrange(u)
- serole = semanage_user_get_roles(self.sh,u)
- semanage_user_key_free(k)
- semanage_user_free(u)
- return serange, serole
-
- def __add(self, name, roles, selevel, serange, prefix):
- if is_mls_enabled == 1:
- if serange == "":
- serange = "s0"
- else:
- serange = untranslate(serange)
-
- if selevel == "":
- selevel = "s0"
- else:
- selevel = untranslate(selevel)
-
- if len(roles) < 1:
- raise ValueError(_("You must add at least one role for %s") % name)
-
- (rc, k) = semanage_user_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
+class dontauditClass(semanageRecords):
- (rc, exists) = semanage_user_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if SELinux user %s is defined") % name)
- if exists:
- raise ValueError(_("SELinux user %s is already defined") % name)
+ def __init__(self, store):
+ semanageRecords.__init__(self, store)
- (rc, u) = semanage_user_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create SELinux user for %s") % name)
+ def toggle(self, dontaudit):
+ if dontaudit not in ["on", "off"]:
+ raise ValueError(_("dontaudit requires either 'on' or 'off'"))
+ self.begin()
+ rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
+ self.commit()
- rc = semanage_user_set_name(self.sh, u, name)
- if rc < 0:
- raise ValueError(_("Could not set name for %s") % name)
-
- for r in roles:
- rc = semanage_user_add_role(self.sh, u, r)
- if rc < 0:
- raise ValueError(_("Could not add role %s for %s") % (r, name))
-
- if is_mls_enabled == 1:
- rc = semanage_user_set_mlsrange(self.sh, u, serange)
- if rc < 0:
- raise ValueError(_("Could not set MLS range for %s") % name)
-
- rc = semanage_user_set_mlslevel(self.sh, u, selevel)
- if rc < 0:
- raise ValueError(_("Could not set MLS level for %s") % name)
- rc = semanage_user_set_prefix(self.sh, u, prefix)
- if rc < 0:
- raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
- (rc, key) = semanage_user_key_extract(self.sh,u)
- if rc < 0:
- raise ValueError(_("Could not extract key for %s") % name)
- rc = semanage_user_modify_local(self.sh, k, u)
- if rc < 0:
- raise ValueError(_("Could not add SELinux user %s") % name)
-
- semanage_user_key_free(k)
- semanage_user_free(u)
- self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
-
- def add(self, name, roles, selevel, serange, prefix):
- serole = " ".join(roles)
- try:
- self.begin()
- self.__add( name, roles, selevel, serange, prefix)
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
- oldserole = ""
- oldserange = ""
- newroles = string.join(roles, ' ');
- if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
- if is_mls_enabled == 1:
- raise ValueError(_("Requires prefix, roles, level or range"))
- else:
- raise ValueError(_("Requires prefix or roles"))
-
- (rc, k) = semanage_user_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
+class permissiveRecords(semanageRecords):
- (rc, exists) = semanage_user_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if SELinux user %s is defined") % name)
- if not exists:
- raise ValueError(_("SELinux user %s is not defined") % name)
+ def __init__(self, store):
+ semanageRecords.__init__(self, store)
+
+ def get_all(self):
+ l = []
+ (rc, mlist, number) = semanage_module_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list SELinux modules"))
+
+ for i in range(number):
+ mod = semanage_module_list_nth(mlist, i)
+ name = semanage_module_get_name(mod)
+ if name and name.startswith("permissive_"):
+ l.append(name.split("permissive_")[1])
+ return l
+
+ def list(self, heading=1, locallist=0):
+ all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE)))
+ if len(all) == 0:
+ return
+
+ if heading:
+ print "\n%-25s\n" % (_("Builtin Permissive Types"))
+ customized = self.get_all()
+ for t in all:
+ if t not in customized:
+ print t
+
+ if len(customized) == 0:
+ return
+
+ if heading:
+ print "\n%-25s\n" % (_("Customized Permissive Types"))
+ for t in customized:
+ print t
+
+ def add(self, type):
+ import glob
+ try:
+ import sepolgen.module as module
+ except ImportError:
+ raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro."))
+
+ name = "permissive_%s" % type
+ modtxt = "(typepermissive %s)" % type
+
+ rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil")
+ if rc >= 0:
+ self.commit()
+
+ if rc < 0:
+ raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
+
+ def delete(self, name):
+ for n in name.split():
+ rc = semanage_module_remove(self.sh, "permissive_%s" % n)
+ if rc < 0:
+ raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
+
+ self.commit()
+
+ def deleteall(self):
+ l = self.get_all()
+ if len(l) > 0:
+ all = " ".join(l)
+ self.delete(all)
+
+
+class loginRecords(semanageRecords):
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+ self.oldsename = None
+ self.oldserange = None
+ self.sename = None
+ self.serange = None
+
+ def __add(self, name, sename, serange):
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+ if sename == "":
+ sename = "user_u"
+
+ userrec = seluserRecords()
+ range, (rc, oldserole) = userrec.get(self.oldsename)
+ range, (rc, serole) = userrec.get(sename)
+
+ if is_mls_enabled == 1:
+ if serange != "":
+ serange = untranslate(serange)
+ else:
+ serange = range
+
+ (rc, k) = semanage_seuser_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_seuser_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+ if exists:
+ raise ValueError(_("Login mapping for %s is already defined") % name)
+ if name[0] == '%':
+ try:
+ grp.getgrnam(name[1:])
+ except:
+ raise ValueError(_("Linux Group %s does not exist") % name[1:])
+ else:
+ try:
+ pwd.getpwnam(name)
+ except:
+ raise ValueError(_("Linux User %s does not exist") % name)
+
+ (rc, u) = semanage_seuser_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create login mapping for %s") % name)
+
+ rc = semanage_seuser_set_name(self.sh, u, name)
+ if rc < 0:
+ raise ValueError(_("Could not set name for %s") % name)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
+ if rc < 0:
+ raise ValueError(_("Could not set MLS range for %s") % name)
+
+ rc = semanage_seuser_set_sename(self.sh, u, sename)
+ if rc < 0:
+ raise ValueError(_("Could not set SELinux user for %s") % name)
+
+ rc = semanage_seuser_modify_local(self.sh, k, u)
+ if rc < 0:
+ raise ValueError(_("Could not add login mapping for %s") % name)
+
+ semanage_seuser_key_free(k)
+ semanage_seuser_free(u)
+ self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
+
+ def add(self, name, sename, serange):
+ try:
+ self.begin()
+ self.__add(name, sename, serange)
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def __modify(self, name, sename="", serange=""):
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+ if sename == "" and serange == "":
+ raise ValueError(_("Requires seuser or serange"))
+
+ userrec = seluserRecords()
+ range, (rc, oldserole) = userrec.get(self.oldsename)
+
+ if sename != "":
+ range, (rc, serole) = userrec.get(sename)
+ else:
+ serole = oldserole
+
+ if serange != "":
+ self.serange = serange
+ else:
+ self.serange = range
+
+ (rc, k) = semanage_seuser_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_seuser_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Login mapping for %s is not defined") % name)
+
+ (rc, u) = semanage_seuser_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query seuser for %s") % name)
+
+ self.oldserange = semanage_seuser_get_mlsrange(u)
+ self.oldsename = semanage_seuser_get_sename(u)
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
+
+ if sename != "":
+ semanage_seuser_set_sename(self.sh, u, sename)
+ self.sename = sename
+ else:
+ self.sename = self.oldsename
+
+ rc = semanage_seuser_modify_local(self.sh, k, u)
+ if rc < 0:
+ raise ValueError(_("Could not modify login mapping for %s") % name)
+
+ semanage_seuser_key_free(k)
+ semanage_seuser_free(u)
+ self.mylog.log("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
+
+ def modify(self, name, sename="", serange=""):
+ try:
+ self.begin()
+ self.__modify(name, sename, serange)
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def __delete(self, name):
+ rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+ userrec = seluserRecords()
+ range, (rc, oldserole) = userrec.get(self.oldsename)
+
+ (rc, k) = semanage_seuser_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_seuser_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Login mapping for %s is not defined") % name)
+
+ (rc, exists) = semanage_seuser_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
+
+ rc = semanage_seuser_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete login mapping for %s") % name)
+
+ semanage_seuser_key_free(k)
+
+ rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
+ range, (rc, serole) = userrec.get(self.sename)
+
+ self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
+
+ def delete(self, name):
+ try:
+ self.begin()
+ self.__delete(name)
+ self.commit()
+
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def deleteall(self):
+ (rc, ulist) = semanage_seuser_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list login mappings"))
+
+ try:
+ self.begin()
+ for u in ulist:
+ self.__delete(semanage_seuser_get_name(u))
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def get_all_logins(self):
+ ddict = {}
+ self.logins_path = selinux.selinux_policy_root() + "/logins"
+ for path, dirs, files in os.walk(self.logins_path):
+ if path == self.logins_path:
+ for name in files:
+ try:
+ fd = open(path + "/" + name)
+ rec = fd.read().rstrip().split(":")
+ fd.close()
+ ddict[name] = (rec[1], rec[2], rec[0])
+ except IndexError:
+ pass
+ return ddict
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.ulist) = semanage_seuser_list_local(self.sh)
+ else:
+ (rc, self.ulist) = semanage_seuser_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list login mappings"))
+
+ for u in self.ulist:
+ name = semanage_seuser_get_name(u)
+ ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
+ return ddict
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ ddict = self.get_all(locallist)
+ ldict = self.get_all_logins()
+ lkeys = ldict.keys()
+ keys = ddict.keys()
+ if len(keys) == 0 and len(lkeys) == 0:
+ return
+ keys.sort()
+ lkeys.sort()
+
+ if is_mls_enabled == 1:
+ if heading:
+ print "\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))
+ for k in keys:
+ u = ddict[k]
+ print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
+ if len(lkeys):
+ print "\nLocal customization in %s" % self.logins_path
+
+ for k in lkeys:
+ u = ldict[k]
+ print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
+ else:
+ if heading:
+ print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
+ for k in keys:
+ print "%-25s %-25s" % (k, ddict[k][0])
+
+
+class seluserRecords(semanageRecords):
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+
+ def get(self, name):
+ (rc, k) = semanage_user_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+ (rc, exists) = semanage_user_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+ (rc, u) = semanage_user_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query user for %s") % name)
+ serange = semanage_user_get_mlsrange(u)
+ serole = semanage_user_get_roles(self.sh, u)
+ semanage_user_key_free(k)
+ semanage_user_free(u)
+ return serange, serole
+
+ def __add(self, name, roles, selevel, serange, prefix):
+ if is_mls_enabled == 1:
+ if serange == "":
+ serange = "s0"
+ else:
+ serange = untranslate(serange)
+
+ if selevel == "":
+ selevel = "s0"
+ else:
+ selevel = untranslate(selevel)
+
+ if len(roles) < 1:
+ raise ValueError(_("You must add at least one role for %s") % name)
+
+ (rc, k) = semanage_user_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_user_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+ if exists:
+ raise ValueError(_("SELinux user %s is already defined") % name)
+
+ (rc, u) = semanage_user_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create SELinux user for %s") % name)
+
+ rc = semanage_user_set_name(self.sh, u, name)
+ if rc < 0:
+ raise ValueError(_("Could not set name for %s") % name)
+
+ for r in roles:
+ rc = semanage_user_add_role(self.sh, u, r)
+ if rc < 0:
+ raise ValueError(_("Could not add role %s for %s") % (r, name))
+
+ if is_mls_enabled == 1:
+ rc = semanage_user_set_mlsrange(self.sh, u, serange)
+ if rc < 0:
+ raise ValueError(_("Could not set MLS range for %s") % name)
+
+ rc = semanage_user_set_mlslevel(self.sh, u, selevel)
+ if rc < 0:
+ raise ValueError(_("Could not set MLS level for %s") % name)
+ rc = semanage_user_set_prefix(self.sh, u, prefix)
+ if rc < 0:
+ raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
+ (rc, key) = semanage_user_key_extract(self.sh, u)
+ if rc < 0:
+ raise ValueError(_("Could not extract key for %s") % name)
+
+ rc = semanage_user_modify_local(self.sh, k, u)
+ if rc < 0:
+ raise ValueError(_("Could not add SELinux user %s") % name)
+
+ semanage_user_key_free(k)
+ semanage_user_free(u)
+ self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
+
+ def add(self, name, roles, selevel, serange, prefix):
+ serole = " ".join(roles)
+ try:
+ self.begin()
+ self.__add(name, roles, selevel, serange, prefix)
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def __modify(self, name, roles=[], selevel="", serange="", prefix=""):
+ oldserole = ""
+ oldserange = ""
+ newroles = string.join(roles, ' ')
+ if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
+ if is_mls_enabled == 1:
+ raise ValueError(_("Requires prefix, roles, level or range"))
+ else:
+ raise ValueError(_("Requires prefix or roles"))
+
+ (rc, k) = semanage_user_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_user_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+ if not exists:
+ raise ValueError(_("SELinux user %s is not defined") % name)
+
+ (rc, u) = semanage_user_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query user for %s") % name)
+
+ oldserange = semanage_user_get_mlsrange(u)
+ (rc, rlist) = semanage_user_get_roles(self.sh, u)
+ if rc >= 0:
+ oldserole = string.join(rlist, ' ')
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
+ if (is_mls_enabled == 1) and (selevel != ""):
+ semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
+
+ if prefix != "":
+ semanage_user_set_prefix(self.sh, u, prefix)
+
+ if len(roles) != 0:
+ for r in rlist:
+ if r not in roles:
+ semanage_user_del_role(u, r)
+ for r in roles:
+ if r not in rlist:
+ semanage_user_add_role(self.sh, u, r)
+
+ rc = semanage_user_modify_local(self.sh, k, u)
+ if rc < 0:
+ raise ValueError(_("Could not modify SELinux user %s") % name)
+
+ semanage_user_key_free(k)
+ semanage_user_free(u)
+
+ role = ",".join(newroles.split())
+ oldserole = ",".join(oldserole.split())
+ self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
+
+ def modify(self, name, roles=[], selevel="", serange="", prefix=""):
+ try:
+ self.begin()
+ self.__modify(name, roles, selevel, serange, prefix)
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def __delete(self, name):
+ (rc, k) = semanage_user_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+
+ (rc, exists) = semanage_user_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+ if not exists:
+ raise ValueError(_("SELinux user %s is not defined") % name)
+
+ (rc, exists) = semanage_user_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+ if not exists:
+ raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
+
+ (rc, u) = semanage_user_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query user for %s") % name)
+ oldserange = semanage_user_get_mlsrange(u)
+ (rc, rlist) = semanage_user_get_roles(self.sh, u)
+ oldserole = ",".join(rlist)
+
+ rc = semanage_user_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete SELinux user %s") % name)
+
+ semanage_user_key_free(k)
+ semanage_user_free(u)
+
+ self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
+
+ def delete(self, name):
+ try:
+ self.begin()
+ self.__delete(name)
+ self.commit()
+
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def deleteall(self):
+ (rc, ulist) = semanage_user_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list login mappings"))
+
+ try:
+ self.begin()
+ for u in ulist:
+ self.__delete(semanage_user_get_name(u))
+ self.commit()
+ except ValueError, error:
+ self.mylog.commit(0)
+ raise error
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.ulist) = semanage_user_list_local(self.sh)
+ else:
+ (rc, self.ulist) = semanage_user_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list SELinux users"))
+
+ for u in self.ulist:
+ name = semanage_user_get_name(u)
+ (rc, rlist) = semanage_user_get_roles(self.sh, u)
+ if rc < 0:
+ raise ValueError(_("Could not list roles for user %s") % name)
+
+ roles = string.join(rlist, ' ')
+ ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
+
+ return ddict
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ ddict = self.get_all(locallist)
+ keys = ddict.keys()
+ if len(keys) == 0:
+ return
+ keys.sort()
+
+ if is_mls_enabled == 1:
+ if heading:
+ print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
+ print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
+ for k in keys:
+ print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
+ else:
+ if heading:
+ print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
+ for k in keys:
+ print "%-15s %s" % (k, ddict[k][3])
- (rc, u) = semanage_user_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query user for %s") % name)
-
- oldserange = semanage_user_get_mlsrange(u)
- (rc, rlist) = semanage_user_get_roles(self.sh, u)
- if rc >= 0:
- oldserole = string.join(rlist, ' ');
-
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
- if (is_mls_enabled == 1) and (selevel != ""):
- semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
-
- if prefix != "":
- semanage_user_set_prefix(self.sh, u, prefix)
-
- if len(roles) != 0:
- for r in rlist:
- if r not in roles:
- semanage_user_del_role(u, r)
- for r in roles:
- if r not in rlist:
- semanage_user_add_role(self.sh, u, r)
-
- rc = semanage_user_modify_local(self.sh, k, u)
- if rc < 0:
- raise ValueError(_("Could not modify SELinux user %s") % name)
-
- semanage_user_key_free(k)
- semanage_user_free(u)
-
- role=",".join(newroles.split())
- oldserole=",".join(oldserole.split())
- self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
-
-
- def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
- try:
- self.begin()
- self.__modify(name, roles, selevel, serange, prefix)
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def __delete(self, name):
- (rc, k) = semanage_user_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
-
- (rc, exists) = semanage_user_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if SELinux user %s is defined") % name)
- if not exists:
- raise ValueError(_("SELinux user %s is not defined") % name)
-
- (rc, exists) = semanage_user_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if SELinux user %s is defined") % name)
- if not exists:
- raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
-
- (rc, u) = semanage_user_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query user for %s") % name)
- oldserange = semanage_user_get_mlsrange(u)
- (rc, rlist) = semanage_user_get_roles(self.sh, u)
- oldserole = ",".join(rlist)
-
- rc = semanage_user_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete SELinux user %s") % name)
-
- semanage_user_key_free(k)
- semanage_user_free(u)
-
- self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
-
- def delete(self, name):
- try:
- self.begin()
- self.__delete(name)
- self.commit()
-
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def deleteall(self):
- (rc, ulist) = semanage_user_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list login mappings"))
-
- try:
- self.begin()
- for u in ulist:
- self.__delete(semanage_user_get_name(u))
- self.commit()
- except ValueError, error:
- self.mylog.commit(0)
- raise error
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.ulist) = semanage_user_list_local(self.sh)
- else:
- (rc, self.ulist) = semanage_user_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list SELinux users"))
-
- for u in self.ulist:
- name = semanage_user_get_name(u)
- (rc, rlist) = semanage_user_get_roles(self.sh, u)
- if rc < 0:
- raise ValueError(_("Could not list roles for user %s") % name)
-
- roles = string.join(rlist, ' ');
- ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
-
- return ddict
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
- return l
-
- def list(self, heading = 1, locallist = 0):
- ddict = self.get_all(locallist)
- keys = ddict.keys()
- if len(keys) == 0:
- return
- keys.sort()
-
- if is_mls_enabled == 1:
- if heading:
- print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
- print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
- for k in keys:
- print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
- else:
- if heading:
- print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
- for k in keys:
- print "%-15s %s" % (k, ddict[k][3])
class portRecords(semanageRecords):
- try:
- valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"]
- except RuntimeError:
- valid_types = []
-
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
-
- def __genkey(self, port, proto):
- if proto == "tcp":
- proto_d = SEMANAGE_PROTO_TCP
- else:
- if proto == "udp":
- proto_d = SEMANAGE_PROTO_UDP
- else:
- raise ValueError(_("Protocol udp or tcp is required"))
- if port == "":
- raise ValueError(_("Port is required"))
-
- ports = port.split("-")
- if len(ports) == 1:
- high = low = int(ports[0])
- else:
- low = int(ports[0])
- high = int(ports[1])
-
- if high > 65535:
- raise ValueError(_("Invalid Port"))
-
- (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
- return ( k, proto_d, low, high )
-
- def __add(self, port, proto, serange, type):
- if is_mls_enabled == 1:
- if serange == "":
- serange = "s0"
- else:
- serange = untranslate(serange)
-
- if type == "":
- raise ValueError(_("Type is required"))
-
- if type not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a port type") % type)
-
- ( k, proto_d, low, high ) = self.__genkey(port, proto)
-
- (rc, exists) = semanage_port_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
- if exists:
- raise ValueError(_("Port %s/%s already defined") % (proto, port))
-
- (rc, p) = semanage_port_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create port for %s/%s") % (proto, port))
-
- semanage_port_set_proto(p, proto_d)
- semanage_port_set_range(p, low, high)
- (rc, con) = semanage_context_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create context for %s/%s") % (proto, port))
-
- rc = semanage_context_set_user(self.sh, con, "system_u")
- if rc < 0:
- raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
-
- rc = semanage_context_set_role(self.sh, con, "object_r")
- if rc < 0:
- raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
-
- rc = semanage_context_set_type(self.sh, con, type)
- if rc < 0:
- raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
-
- if (is_mls_enabled == 1) and (serange != ""):
- rc = semanage_context_set_mls(self.sh, con, serange)
- if rc < 0:
- raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
-
- rc = semanage_port_set_con(self.sh, p, con)
- if rc < 0:
- raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
-
- rc = semanage_port_modify_local(self.sh, k, p)
- if rc < 0:
- raise ValueError(_("Could not add port %s/%s") % (proto, port))
-
- semanage_context_free(con)
- semanage_port_key_free(k)
- semanage_port_free(p)
-
- def add(self, port, proto, serange, type):
- self.begin()
- self.__add(port, proto, serange, type)
- self.commit()
-
- def __modify(self, port, proto, serange, setype):
- if serange == "" and setype == "":
- if is_mls_enabled == 1:
- raise ValueError(_("Requires setype or serange"))
- else:
- raise ValueError(_("Requires setype"))
-
- if setype and setype not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a port type") % setype)
-
- ( k, proto_d, low, high ) = self.__genkey(port, proto)
-
- (rc, exists) = semanage_port_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
- if not exists:
- raise ValueError(_("Port %s/%s is not defined") % (proto,port))
-
- (rc, p) = semanage_port_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query port %s/%s") % (proto, port))
-
- con = semanage_port_get_con(p)
-
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_context_set_mls(self.sh, con, untranslate(serange))
- if setype != "":
- semanage_context_set_type(self.sh, con, setype)
-
- rc = semanage_port_modify_local(self.sh, k, p)
- if rc < 0:
- raise ValueError(_("Could not modify port %s/%s") % (proto, port))
-
- semanage_port_key_free(k)
- semanage_port_free(p)
-
- def modify(self, port, proto, serange, setype):
- self.begin()
- self.__modify(port, proto, serange, setype)
- self.commit()
-
- def deleteall(self):
- (rc, plist) = semanage_port_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list the ports"))
-
- self.begin()
-
- for port in plist:
- proto = semanage_port_get_proto(port)
- proto_str = semanage_port_get_proto_str(proto)
- low = semanage_port_get_low(port)
- high = semanage_port_get_high(port)
- port_str = "%s-%s" % (low, high)
- ( k, proto_d, low, high ) = self.__genkey(port_str , proto_str)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % port_str)
-
- rc = semanage_port_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete the port %s") % port_str)
- semanage_port_key_free(k)
-
- self.commit()
-
- def __delete(self, port, proto):
- ( k, proto_d, low, high ) = self.__genkey(port, proto)
- (rc, exists) = semanage_port_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
- if not exists:
- raise ValueError(_("Port %s/%s is not defined") % (proto, port))
-
- (rc, exists) = semanage_port_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
- if not exists:
- raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
-
- rc = semanage_port_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete port %s/%s") % (proto, port))
-
- semanage_port_key_free(k)
-
- def delete(self, port, proto):
- self.begin()
- self.__delete(port, proto)
- self.commit()
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.plist) = semanage_port_list_local(self.sh)
- else:
- (rc, self.plist) = semanage_port_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list ports"))
-
- for port in self.plist:
- con = semanage_port_get_con(port)
- ctype = semanage_context_get_type(con)
- if ctype == "reserved_port_t":
- continue
- level = semanage_context_get_mls(con)
- proto = semanage_port_get_proto(port)
- proto_str = semanage_port_get_proto_str(proto)
- low = semanage_port_get_low(port)
- high = semanage_port_get_high(port)
- ddict[(low, high, proto_str)] = (ctype, level)
- return ddict
-
- def get_all_by_type(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.plist) = semanage_port_list_local(self.sh)
- else:
- (rc, self.plist) = semanage_port_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list ports"))
-
- for port in self.plist:
- con = semanage_port_get_con(port)
- ctype = semanage_context_get_type(con)
- if ctype == "reserved_port_t":
- continue
- proto = semanage_port_get_proto(port)
- proto_str = semanage_port_get_proto_str(proto)
- low = semanage_port_get_low(port)
- high = semanage_port_get_high(port)
- if (ctype, proto_str) not in ddict.keys():
- ddict[(ctype,proto_str)] = []
- if low == high:
- ddict[(ctype,proto_str)].append("%d" % low)
- else:
- ddict[(ctype,proto_str)].append("%d-%d" % (low, high))
- return ddict
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- if k[0] == k[1]:
- l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
- else:
- l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
- return l
-
- def list(self, heading = 1, locallist = 0):
- ddict = self.get_all_by_type(locallist)
- keys = ddict.keys()
- if len(keys) == 0:
- return
- keys.sort()
-
- if heading:
- print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
- for i in keys:
- rec = "%-30s %-8s " % i
- rec += "%s" % ddict[i][0]
- for p in ddict[i][1:]:
- rec += ", %s" % p
- print rec
+ try:
+ valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "port_type")[0]["types"]
+ except RuntimeError:
+ valid_types = []
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+
+ def __genkey(self, port, proto):
+ if proto == "tcp":
+ proto_d = SEMANAGE_PROTO_TCP
+ else:
+ if proto == "udp":
+ proto_d = SEMANAGE_PROTO_UDP
+ else:
+ raise ValueError(_("Protocol udp or tcp is required"))
+ if port == "":
+ raise ValueError(_("Port is required"))
+
+ ports = port.split("-")
+ if len(ports) == 1:
+ high = low = int(ports[0])
+ else:
+ low = int(ports[0])
+ high = int(ports[1])
+
+ if high > 65535:
+ raise ValueError(_("Invalid Port"))
+
+ (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
+ return (k, proto_d, low, high)
+
+ def __add(self, port, proto, serange, type):
+ if is_mls_enabled == 1:
+ if serange == "":
+ serange = "s0"
+ else:
+ serange = untranslate(serange)
+
+ if type == "":
+ raise ValueError(_("Type is required"))
+
+ if type not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a port type") % type)
+
+ (k, proto_d, low, high) = self.__genkey(port, proto)
+
+ (rc, exists) = semanage_port_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+ if exists:
+ raise ValueError(_("Port %s/%s already defined") % (proto, port))
+
+ (rc, p) = semanage_port_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create port for %s/%s") % (proto, port))
+
+ semanage_port_set_proto(p, proto_d)
+ semanage_port_set_range(p, low, high)
+ (rc, con) = semanage_context_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create context for %s/%s") % (proto, port))
+
+ rc = semanage_context_set_user(self.sh, con, "system_u")
+ if rc < 0:
+ raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
+
+ rc = semanage_context_set_role(self.sh, con, "object_r")
+ if rc < 0:
+ raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
+
+ rc = semanage_context_set_type(self.sh, con, type)
+ if rc < 0:
+ raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ rc = semanage_context_set_mls(self.sh, con, serange)
+ if rc < 0:
+ raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
+
+ rc = semanage_port_set_con(self.sh, p, con)
+ if rc < 0:
+ raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
+
+ rc = semanage_port_modify_local(self.sh, k, p)
+ if rc < 0:
+ raise ValueError(_("Could not add port %s/%s") % (proto, port))
+
+ semanage_context_free(con)
+ semanage_port_key_free(k)
+ semanage_port_free(p)
+
+ def add(self, port, proto, serange, type):
+ self.begin()
+ self.__add(port, proto, serange, type)
+ self.commit()
+
+ def __modify(self, port, proto, serange, setype):
+ if serange == "" and setype == "":
+ if is_mls_enabled == 1:
+ raise ValueError(_("Requires setype or serange"))
+ else:
+ raise ValueError(_("Requires setype"))
+
+ if setype and setype not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a port type") % setype)
+
+ (k, proto_d, low, high) = self.__genkey(port, proto)
+
+ (rc, exists) = semanage_port_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+ if not exists:
+ raise ValueError(_("Port %s/%s is not defined") % (proto, port))
+
+ (rc, p) = semanage_port_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query port %s/%s") % (proto, port))
+
+ con = semanage_port_get_con(p)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_context_set_mls(self.sh, con, untranslate(serange))
+ if setype != "":
+ semanage_context_set_type(self.sh, con, setype)
+
+ rc = semanage_port_modify_local(self.sh, k, p)
+ if rc < 0:
+ raise ValueError(_("Could not modify port %s/%s") % (proto, port))
+
+ semanage_port_key_free(k)
+ semanage_port_free(p)
+
+ def modify(self, port, proto, serange, setype):
+ self.begin()
+ self.__modify(port, proto, serange, setype)
+ self.commit()
+
+ def deleteall(self):
+ (rc, plist) = semanage_port_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list the ports"))
+
+ self.begin()
+
+ for port in plist:
+ proto = semanage_port_get_proto(port)
+ proto_str = semanage_port_get_proto_str(proto)
+ low = semanage_port_get_low(port)
+ high = semanage_port_get_high(port)
+ port_str = "%s-%s" % (low, high)
+ (k, proto_d, low, high) = self.__genkey(port_str, proto_str)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % port_str)
+
+ rc = semanage_port_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete the port %s") % port_str)
+ semanage_port_key_free(k)
+
+ self.commit()
+
+ def __delete(self, port, proto):
+ (k, proto_d, low, high) = self.__genkey(port, proto)
+ (rc, exists) = semanage_port_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+ if not exists:
+ raise ValueError(_("Port %s/%s is not defined") % (proto, port))
+
+ (rc, exists) = semanage_port_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+ if not exists:
+ raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
+
+ rc = semanage_port_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete port %s/%s") % (proto, port))
+
+ semanage_port_key_free(k)
+
+ def delete(self, port, proto):
+ self.begin()
+ self.__delete(port, proto)
+ self.commit()
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.plist) = semanage_port_list_local(self.sh)
+ else:
+ (rc, self.plist) = semanage_port_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list ports"))
+
+ for port in self.plist:
+ con = semanage_port_get_con(port)
+ ctype = semanage_context_get_type(con)
+ if ctype == "reserved_port_t":
+ continue
+ level = semanage_context_get_mls(con)
+ proto = semanage_port_get_proto(port)
+ proto_str = semanage_port_get_proto_str(proto)
+ low = semanage_port_get_low(port)
+ high = semanage_port_get_high(port)
+ ddict[(low, high, proto_str)] = (ctype, level)
+ return ddict
+
+ def get_all_by_type(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.plist) = semanage_port_list_local(self.sh)
+ else:
+ (rc, self.plist) = semanage_port_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list ports"))
+
+ for port in self.plist:
+ con = semanage_port_get_con(port)
+ ctype = semanage_context_get_type(con)
+ if ctype == "reserved_port_t":
+ continue
+ proto = semanage_port_get_proto(port)
+ proto_str = semanage_port_get_proto_str(proto)
+ low = semanage_port_get_low(port)
+ high = semanage_port_get_high(port)
+ if (ctype, proto_str) not in ddict.keys():
+ ddict[(ctype, proto_str)] = []
+ if low == high:
+ ddict[(ctype, proto_str)].append("%d" % low)
+ else:
+ ddict[(ctype, proto_str)].append("%d-%d" % (low, high))
+ return ddict
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ if k[0] == k[1]:
+ l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
+ else:
+ l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ ddict = self.get_all_by_type(locallist)
+ keys = ddict.keys()
+ if len(keys) == 0:
+ return
+ keys.sort()
+
+ if heading:
+ print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
+ for i in keys:
+ rec = "%-30s %-8s " % i
+ rec += "%s" % ddict[i][0]
+ for p in ddict[i][1:]:
+ rec += ", %s" % p
+ print rec
+
class nodeRecords(semanageRecords):
- try:
- valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"node_type")[0]["types"]
- except RuntimeError:
- valid_types = []
-
- def __init__(self, store = ""):
- semanageRecords.__init__(self,store)
- self.protocol = ["ipv4", "ipv6"]
-
- def validate(self, addr, mask, protocol):
- newaddr=addr
- newmask=mask
- newprotocol=""
-
- if addr == "":
- raise ValueError(_("Node Address is required"))
-
- # verify valid comination
- if len(mask) == 0 or mask[0] == "/":
- i = IP(addr + mask)
- newaddr = i.strNormal(0)
- newmask = str(i.netmask())
- if newmask == "0.0.0.0" and i.version() == 6:
- newmask = "::"
-
- protocol = "ipv%d" % i.version()
-
- try:
- newprotocol = self.protocol.index(protocol)
- except:
- raise ValueError(_("Unknown or missing protocol"))
-
- return newaddr, newmask, newprotocol
-
- def __add(self, addr, mask, proto, serange, ctype):
- addr, mask, proto = self.validate(addr, mask, proto)
-
- if is_mls_enabled == 1:
- if serange == "":
- serange = "s0"
- else:
- serange = untranslate(serange)
-
- if ctype == "":
- raise ValueError(_("SELinux node type is required"))
-
- if ctype not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
-
- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % addr)
- if rc < 0:
- raise ValueError(_("Could not check if addr %s is defined") % addr)
-
- (rc, exists) = semanage_node_exists(self.sh, k)
- if exists:
- raise ValueError(_("Addr %s already defined") % addr)
-
- (rc, node) = semanage_node_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create addr for %s") % addr)
- semanage_node_set_proto(node, proto)
-
- rc = semanage_node_set_addr(self.sh, node, proto, addr)
- (rc, con) = semanage_context_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create context for %s") % addr)
-
- rc = semanage_node_set_mask(self.sh, node, proto, mask)
- if rc < 0:
- raise ValueError(_("Could not set mask for %s") % addr)
-
- rc = semanage_context_set_user(self.sh, con, "system_u")
- if rc < 0:
- raise ValueError(_("Could not set user in addr context for %s") % addr)
-
- rc = semanage_context_set_role(self.sh, con, "object_r")
- if rc < 0:
- raise ValueError(_("Could not set role in addr context for %s") % addr)
-
- rc = semanage_context_set_type(self.sh, con, ctype)
- if rc < 0:
- raise ValueError(_("Could not set type in addr context for %s") % addr)
-
- if (is_mls_enabled == 1) and (serange != ""):
- rc = semanage_context_set_mls(self.sh, con, serange)
- if rc < 0:
- raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
-
- rc = semanage_node_set_con(self.sh, node, con)
- if rc < 0:
- raise ValueError(_("Could not set addr context for %s") % addr)
-
- rc = semanage_node_modify_local(self.sh, k, node)
- if rc < 0:
- raise ValueError(_("Could not add addr %s") % addr)
-
- semanage_context_free(con)
- semanage_node_key_free(k)
- semanage_node_free(node)
-
- def add(self, addr, mask, proto, serange, ctype):
- self.begin()
- self.__add(addr, mask, proto, serange, ctype)
- self.commit()
-
- def __modify(self, addr, mask, proto, serange, setype):
- addr, mask, proto = self.validate(addr, mask, proto)
-
- if serange == "" and setype == "":
- raise ValueError(_("Requires setype or serange"))
-
- if setype and setype not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a node type") % setype)
-
- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % addr)
-
- (rc, exists) = semanage_node_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if addr %s is defined") % addr)
- if not exists:
- raise ValueError(_("Addr %s is not defined") % addr)
-
- (rc, node) = semanage_node_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query addr %s") % addr)
-
- con = semanage_node_get_con(node)
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_context_set_mls(self.sh, con, untranslate(serange))
- if setype != "":
- semanage_context_set_type(self.sh, con, setype)
-
- rc = semanage_node_modify_local(self.sh, k, node)
- if rc < 0:
- raise ValueError(_("Could not modify addr %s") % addr)
-
- semanage_node_key_free(k)
- semanage_node_free(node)
-
- def modify(self, addr, mask, proto, serange, setype):
- self.begin()
- self.__modify(addr, mask, proto, serange, setype)
- self.commit()
-
- def __delete(self, addr, mask, proto):
-
- addr, mask, proto = self.validate(addr, mask, proto)
-
- (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % addr)
-
- (rc, exists) = semanage_node_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if addr %s is defined") % addr)
- if not exists:
- raise ValueError(_("Addr %s is not defined") % addr)
-
- (rc, exists) = semanage_node_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if addr %s is defined") % addr)
- if not exists:
- raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
-
- rc = semanage_node_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete addr %s") % addr)
-
- semanage_node_key_free(k)
-
- def delete(self, addr, mask, proto):
- self.begin()
- self.__delete(addr, mask, proto)
- self.commit()
-
- def deleteall(self):
- (rc, nlist) = semanage_node_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not deleteall node mappings"))
-
- self.begin()
- for node in nlist:
- self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
- self.commit()
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist :
- (rc, self.ilist) = semanage_node_list_local(self.sh)
- else:
- (rc, self.ilist) = semanage_node_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list addrs"))
-
- for node in self.ilist:
- con = semanage_node_get_con(node)
- addr = semanage_node_get_addr(self.sh, node)
- mask = semanage_node_get_mask(self.sh, node)
- proto = self.protocol[semanage_node_get_proto(node)]
- ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
-
- return ddict
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0]))
- return l
-
- def list(self, heading = 1, locallist = 0):
- ddict = self.get_all(locallist)
- keys = ddict.keys()
- if len(keys) == 0:
- return
- keys.sort()
-
- if heading:
- print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
- if is_mls_enabled:
- for k in keys:
- val = ''
- for fields in k:
- val = val + '\t' + str(fields)
- print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
- else:
- for k in keys:
- print "%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2])
+ try:
+ valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "node_type")[0]["types"]
+ except RuntimeError:
+ valid_types = []
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+ self.protocol = ["ipv4", "ipv6"]
+
+ def validate(self, addr, mask, protocol):
+ newaddr = addr
+ newmask = mask
+ newprotocol = ""
+
+ if addr == "":
+ raise ValueError(_("Node Address is required"))
+
+ # verify valid comination
+ if len(mask) == 0 or mask[0] == "/":
+ i = IP(addr + mask)
+ newaddr = i.strNormal(0)
+ newmask = str(i.netmask())
+ if newmask == "0.0.0.0" and i.version() == 6:
+ newmask = "::"
+
+ protocol = "ipv%d" % i.version()
+
+ try:
+ newprotocol = self.protocol.index(protocol)
+ except:
+ raise ValueError(_("Unknown or missing protocol"))
+
+ return newaddr, newmask, newprotocol
+
+ def __add(self, addr, mask, proto, serange, ctype):
+ addr, mask, proto = self.validate(addr, mask, proto)
+
+ if is_mls_enabled == 1:
+ if serange == "":
+ serange = "s0"
+ else:
+ serange = untranslate(serange)
+
+ if ctype == "":
+ raise ValueError(_("SELinux node type is required"))
+
+ if ctype not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
+
+ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % addr)
+ if rc < 0:
+ raise ValueError(_("Could not check if addr %s is defined") % addr)
+
+ (rc, exists) = semanage_node_exists(self.sh, k)
+ if exists:
+ raise ValueError(_("Addr %s already defined") % addr)
+
+ (rc, node) = semanage_node_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create addr for %s") % addr)
+ semanage_node_set_proto(node, proto)
+
+ rc = semanage_node_set_addr(self.sh, node, proto, addr)
+ (rc, con) = semanage_context_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create context for %s") % addr)
+
+ rc = semanage_node_set_mask(self.sh, node, proto, mask)
+ if rc < 0:
+ raise ValueError(_("Could not set mask for %s") % addr)
+
+ rc = semanage_context_set_user(self.sh, con, "system_u")
+ if rc < 0:
+ raise ValueError(_("Could not set user in addr context for %s") % addr)
+
+ rc = semanage_context_set_role(self.sh, con, "object_r")
+ if rc < 0:
+ raise ValueError(_("Could not set role in addr context for %s") % addr)
+
+ rc = semanage_context_set_type(self.sh, con, ctype)
+ if rc < 0:
+ raise ValueError(_("Could not set type in addr context for %s") % addr)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ rc = semanage_context_set_mls(self.sh, con, serange)
+ if rc < 0:
+ raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
+
+ rc = semanage_node_set_con(self.sh, node, con)
+ if rc < 0:
+ raise ValueError(_("Could not set addr context for %s") % addr)
+
+ rc = semanage_node_modify_local(self.sh, k, node)
+ if rc < 0:
+ raise ValueError(_("Could not add addr %s") % addr)
+
+ semanage_context_free(con)
+ semanage_node_key_free(k)
+ semanage_node_free(node)
+
+ def add(self, addr, mask, proto, serange, ctype):
+ self.begin()
+ self.__add(addr, mask, proto, serange, ctype)
+ self.commit()
+
+ def __modify(self, addr, mask, proto, serange, setype):
+ addr, mask, proto = self.validate(addr, mask, proto)
+
+ if serange == "" and setype == "":
+ raise ValueError(_("Requires setype or serange"))
+
+ if setype and setype not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a node type") % setype)
+
+ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % addr)
+
+ (rc, exists) = semanage_node_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if addr %s is defined") % addr)
+ if not exists:
+ raise ValueError(_("Addr %s is not defined") % addr)
+
+ (rc, node) = semanage_node_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query addr %s") % addr)
+
+ con = semanage_node_get_con(node)
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_context_set_mls(self.sh, con, untranslate(serange))
+ if setype != "":
+ semanage_context_set_type(self.sh, con, setype)
+
+ rc = semanage_node_modify_local(self.sh, k, node)
+ if rc < 0:
+ raise ValueError(_("Could not modify addr %s") % addr)
+
+ semanage_node_key_free(k)
+ semanage_node_free(node)
+
+ def modify(self, addr, mask, proto, serange, setype):
+ self.begin()
+ self.__modify(addr, mask, proto, serange, setype)
+ self.commit()
+
+ def __delete(self, addr, mask, proto):
+
+ addr, mask, proto = self.validate(addr, mask, proto)
+
+ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % addr)
+
+ (rc, exists) = semanage_node_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if addr %s is defined") % addr)
+ if not exists:
+ raise ValueError(_("Addr %s is not defined") % addr)
+
+ (rc, exists) = semanage_node_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if addr %s is defined") % addr)
+ if not exists:
+ raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
+
+ rc = semanage_node_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete addr %s") % addr)
+
+ semanage_node_key_free(k)
+
+ def delete(self, addr, mask, proto):
+ self.begin()
+ self.__delete(addr, mask, proto)
+ self.commit()
+
+ def deleteall(self):
+ (rc, nlist) = semanage_node_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not deleteall node mappings"))
+
+ self.begin()
+ for node in nlist:
+ self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
+ self.commit()
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.ilist) = semanage_node_list_local(self.sh)
+ else:
+ (rc, self.ilist) = semanage_node_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list addrs"))
+
+ for node in self.ilist:
+ con = semanage_node_get_con(node)
+ addr = semanage_node_get_addr(self.sh, node)
+ mask = semanage_node_get_mask(self.sh, node)
+ proto = self.protocol[semanage_node_get_proto(node)]
+ ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+
+ return ddict
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0]))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ ddict = self.get_all(locallist)
+ keys = ddict.keys()
+ if len(keys) == 0:
+ return
+ keys.sort()
+
+ if heading:
+ print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
+ if is_mls_enabled:
+ for k in keys:
+ val = ''
+ for fields in k:
+ val = val + '\t' + str(fields)
+ print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))
+ else:
+ for k in keys:
+ print "%-18s %-18s %-5s %s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2])
class interfaceRecords(semanageRecords):
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
-
- def __add(self, interface, serange, ctype):
- if is_mls_enabled == 1:
- if serange == "":
- serange = "s0"
- else:
- serange = untranslate(serange)
-
- if ctype == "":
- raise ValueError(_("SELinux Type is required"))
-
- (rc, k) = semanage_iface_key_create(self.sh, interface)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % interface)
-
- (rc, exists) = semanage_iface_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if interface %s is defined") % interface)
- if exists:
- raise ValueError(_("Interface %s already defined") % interface)
-
- (rc, iface) = semanage_iface_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create interface for %s") % interface)
-
- rc = semanage_iface_set_name(self.sh, iface, interface)
- (rc, con) = semanage_context_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create context for %s") % interface)
-
- rc = semanage_context_set_user(self.sh, con, "system_u")
- if rc < 0:
- raise ValueError(_("Could not set user in interface context for %s") % interface)
-
- rc = semanage_context_set_role(self.sh, con, "object_r")
- if rc < 0:
- raise ValueError(_("Could not set role in interface context for %s") % interface)
-
- rc = semanage_context_set_type(self.sh, con, ctype)
- if rc < 0:
- raise ValueError(_("Could not set type in interface context for %s") % interface)
-
- if (is_mls_enabled == 1) and (serange != ""):
- rc = semanage_context_set_mls(self.sh, con, serange)
- if rc < 0:
- raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
-
- rc = semanage_iface_set_ifcon(self.sh, iface, con)
- if rc < 0:
- raise ValueError(_("Could not set interface context for %s") % interface)
-
- rc = semanage_iface_set_msgcon(self.sh, iface, con)
- if rc < 0:
- raise ValueError(_("Could not set message context for %s") % interface)
-
- rc = semanage_iface_modify_local(self.sh, k, iface)
- if rc < 0:
- raise ValueError(_("Could not add interface %s") % interface)
-
- semanage_context_free(con)
- semanage_iface_key_free(k)
- semanage_iface_free(iface)
-
- def add(self, interface, serange, ctype):
- self.begin()
- self.__add(interface, serange, ctype)
- self.commit()
-
- def __modify(self, interface, serange, setype):
- if serange == "" and setype == "":
- raise ValueError(_("Requires setype or serange"))
-
- (rc, k) = semanage_iface_key_create(self.sh, interface)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % interface)
-
- (rc, exists) = semanage_iface_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if interface %s is defined") % interface)
- if not exists:
- raise ValueError(_("Interface %s is not defined") % interface)
-
- (rc, iface) = semanage_iface_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query interface %s") % interface)
-
- con = semanage_iface_get_ifcon(iface)
-
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_context_set_mls(self.sh, con, untranslate(serange))
- if setype != "":
- semanage_context_set_type(self.sh, con, setype)
-
- rc = semanage_iface_modify_local(self.sh, k, iface)
- if rc < 0:
- raise ValueError(_("Could not modify interface %s") % interface)
-
- semanage_iface_key_free(k)
- semanage_iface_free(iface)
-
- def modify(self, interface, serange, setype):
- self.begin()
- self.__modify(interface, serange, setype)
- self.commit()
-
- def __delete(self, interface):
- (rc, k) = semanage_iface_key_create(self.sh, interface)
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % interface)
-
- (rc, exists) = semanage_iface_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if interface %s is defined") % interface)
- if not exists:
- raise ValueError(_("Interface %s is not defined") % interface)
-
- (rc, exists) = semanage_iface_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if interface %s is defined") % interface)
- if not exists:
- raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
-
- rc = semanage_iface_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete interface %s") % interface)
-
- semanage_iface_key_free(k)
-
- def delete(self, interface):
- self.begin()
- self.__delete(interface)
- self.commit()
-
- def deleteall(self):
- (rc, ulist) = semanage_iface_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not delete all interface mappings"))
-
- self.begin()
- for i in ulist:
- self.__delete(semanage_iface_get_name(i))
- self.commit()
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.ilist) = semanage_iface_list_local(self.sh)
- else:
- (rc, self.ilist) = semanage_iface_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list interfaces"))
-
- for interface in self.ilist:
- con = semanage_iface_get_ifcon(interface)
- ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
-
- return ddict
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- l.append("-a -t %s %s" % (ddict[k][2], k))
- return l
-
- def list(self, heading = 1, locallist = 0):
- ddict = self.get_all(locallist)
- keys = ddict.keys()
- if len(keys) == 0:
- return
- keys.sort()
-
- if heading:
- print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
- if is_mls_enabled:
- for k in keys:
- print "%-30s %s:%s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
- else:
- for k in keys:
- print "%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2])
-
-class fcontextRecords(semanageRecords):
- try:
- valid_types = sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"]
- valid_types += sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"]
- valid_types.append("<<none>>")
- except RuntimeError:
- valid_types = []
-
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
- self.equiv = {}
- self.equiv_dist = {}
- self.equal_ind = False
- try:
- fd = open(selinux.selinux_file_context_subs_path(), "r")
- for i in fd.readlines():
- i = i.strip()
- if len(i) == 0:
- continue
- if i.startswith("#"):
- continue
- target, substitute = i.split()
- self.equiv[target] = substitute
- fd.close()
- except IOError:
- pass
- try:
- fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
- for i in fd.readlines():
- i = i.strip()
- if len(i) == 0:
- continue
- if i.startswith("#"):
- continue
- target, substitute = i.split()
- self.equiv_dist[target] = substitute
- fd.close()
- except IOError:
- pass
-
- def commit(self):
- if self.equal_ind:
- subs_file = selinux.selinux_file_context_subs_path()
- tmpfile = "%s.tmp" % subs_file
- fd = open(tmpfile, "w")
- for target in self.equiv.keys():
- fd.write("%s %s\n" % (target, self.equiv[target]))
- fd.close()
- try:
- os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
- except:
- pass
- os.rename(tmpfile,subs_file)
- self.equal_ind = False
- semanageRecords.commit(self)
-
- def add_equal(self, target, substitute):
- self.begin()
- if target != "/" and target[-1] == "/":
- raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target )
-
- if substitute != "/" and substitute[-1] == "/":
- raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute )
-
- if target in self.equiv.keys():
- raise ValueError(_("Equivalence class for %s already exists") % target)
- self.validate(target)
-
- for fdict in (self.equiv, self.equiv_dist):
- for i in fdict:
- if i.startswith(target + "/"):
- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
- self.equiv[target] = substitute
- self.equal_ind = True
- self.commit()
-
- def modify_equal(self, target, substitute):
- self.begin()
- if target not in self.equiv.keys():
- raise ValueError(_("Equivalence class for %s does not exists") % target)
- self.equiv[target] = substitute
- self.equal_ind = True
- self.commit()
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+
+ def __add(self, interface, serange, ctype):
+ if is_mls_enabled == 1:
+ if serange == "":
+ serange = "s0"
+ else:
+ serange = untranslate(serange)
+
+ if ctype == "":
+ raise ValueError(_("SELinux Type is required"))
+
+ (rc, k) = semanage_iface_key_create(self.sh, interface)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % interface)
+
+ (rc, exists) = semanage_iface_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if interface %s is defined") % interface)
+ if exists:
+ raise ValueError(_("Interface %s already defined") % interface)
+
+ (rc, iface) = semanage_iface_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create interface for %s") % interface)
+
+ rc = semanage_iface_set_name(self.sh, iface, interface)
+ (rc, con) = semanage_context_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create context for %s") % interface)
+
+ rc = semanage_context_set_user(self.sh, con, "system_u")
+ if rc < 0:
+ raise ValueError(_("Could not set user in interface context for %s") % interface)
+
+ rc = semanage_context_set_role(self.sh, con, "object_r")
+ if rc < 0:
+ raise ValueError(_("Could not set role in interface context for %s") % interface)
+
+ rc = semanage_context_set_type(self.sh, con, ctype)
+ if rc < 0:
+ raise ValueError(_("Could not set type in interface context for %s") % interface)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ rc = semanage_context_set_mls(self.sh, con, serange)
+ if rc < 0:
+ raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
+
+ rc = semanage_iface_set_ifcon(self.sh, iface, con)
+ if rc < 0:
+ raise ValueError(_("Could not set interface context for %s") % interface)
+
+ rc = semanage_iface_set_msgcon(self.sh, iface, con)
+ if rc < 0:
+ raise ValueError(_("Could not set message context for %s") % interface)
+
+ rc = semanage_iface_modify_local(self.sh, k, iface)
+ if rc < 0:
+ raise ValueError(_("Could not add interface %s") % interface)
+
+ semanage_context_free(con)
+ semanage_iface_key_free(k)
+ semanage_iface_free(iface)
+
+ def add(self, interface, serange, ctype):
+ self.begin()
+ self.__add(interface, serange, ctype)
+ self.commit()
+
+ def __modify(self, interface, serange, setype):
+ if serange == "" and setype == "":
+ raise ValueError(_("Requires setype or serange"))
+
+ (rc, k) = semanage_iface_key_create(self.sh, interface)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % interface)
+
+ (rc, exists) = semanage_iface_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if interface %s is defined") % interface)
+ if not exists:
+ raise ValueError(_("Interface %s is not defined") % interface)
+
+ (rc, iface) = semanage_iface_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query interface %s") % interface)
+
+ con = semanage_iface_get_ifcon(iface)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_context_set_mls(self.sh, con, untranslate(serange))
+ if setype != "":
+ semanage_context_set_type(self.sh, con, setype)
+
+ rc = semanage_iface_modify_local(self.sh, k, iface)
+ if rc < 0:
+ raise ValueError(_("Could not modify interface %s") % interface)
+
+ semanage_iface_key_free(k)
+ semanage_iface_free(iface)
+
+ def modify(self, interface, serange, setype):
+ self.begin()
+ self.__modify(interface, serange, setype)
+ self.commit()
+
+ def __delete(self, interface):
+ (rc, k) = semanage_iface_key_create(self.sh, interface)
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % interface)
+
+ (rc, exists) = semanage_iface_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if interface %s is defined") % interface)
+ if not exists:
+ raise ValueError(_("Interface %s is not defined") % interface)
+
+ (rc, exists) = semanage_iface_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if interface %s is defined") % interface)
+ if not exists:
+ raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
+
+ rc = semanage_iface_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete interface %s") % interface)
+
+ semanage_iface_key_free(k)
+
+ def delete(self, interface):
+ self.begin()
+ self.__delete(interface)
+ self.commit()
+
+ def deleteall(self):
+ (rc, ulist) = semanage_iface_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not delete all interface mappings"))
+
+ self.begin()
+ for i in ulist:
+ self.__delete(semanage_iface_get_name(i))
+ self.commit()
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.ilist) = semanage_iface_list_local(self.sh)
+ else:
+ (rc, self.ilist) = semanage_iface_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list interfaces"))
+
+ for interface in self.ilist:
+ con = semanage_iface_get_ifcon(interface)
+ ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+
+ return ddict
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -t %s %s" % (ddict[k][2], k))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ ddict = self.get_all(locallist)
+ keys = ddict.keys()
+ if len(keys) == 0:
+ return
+ keys.sort()
+
+ if heading:
+ print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
+ if is_mls_enabled:
+ for k in keys:
+ print "%-30s %s:%s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))
+ else:
+ for k in keys:
+ print "%-30s %s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2])
- def createcon(self, target, seuser = "system_u"):
- (rc, con) = semanage_context_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create context for %s") % target)
- if seuser == "":
- seuser = "system_u"
- rc = semanage_context_set_user(self.sh, con, seuser)
- if rc < 0:
- raise ValueError(_("Could not set user in file context for %s") % target)
-
- rc = semanage_context_set_role(self.sh, con, "object_r")
+class fcontextRecords(semanageRecords):
+ try:
+ valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "file_type")[0]["types"]
+ valid_types += sepolicy.info(sepolicy.ATTRIBUTE, "device_node")[0]["types"]
+ valid_types.append("<<none>>")
+ except RuntimeError:
+ valid_types = []
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+ self.equiv = {}
+ self.equiv_dist = {}
+ self.equal_ind = False
+ try:
+ fd = open(selinux.selinux_file_context_subs_path(), "r")
+ for i in fd.readlines():
+ i = i.strip()
+ if len(i) == 0:
+ continue
+ if i.startswith("#"):
+ continue
+ target, substitute = i.split()
+ self.equiv[target] = substitute
+ fd.close()
+ except IOError:
+ pass
+ try:
+ fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
+ for i in fd.readlines():
+ i = i.strip()
+ if len(i) == 0:
+ continue
+ if i.startswith("#"):
+ continue
+ target, substitute = i.split()
+ self.equiv_dist[target] = substitute
+ fd.close()
+ except IOError:
+ pass
+
+ def commit(self):
+ if self.equal_ind:
+ subs_file = selinux.selinux_file_context_subs_path()
+ tmpfile = "%s.tmp" % subs_file
+ fd = open(tmpfile, "w")
+ for target in self.equiv.keys():
+ fd.write("%s %s\n" % (target, self.equiv[target]))
+ fd.close()
+ try:
+ os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
+ except:
+ pass
+ os.rename(tmpfile, subs_file)
+ self.equal_ind = False
+ semanageRecords.commit(self)
+
+ def add_equal(self, target, substitute):
+ self.begin()
+ if target != "/" and target[-1] == "/":
+ raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target)
+
+ if substitute != "/" and substitute[-1] == "/":
+ raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute)
+
+ if target in self.equiv.keys():
+ raise ValueError(_("Equivalence class for %s already exists") % target)
+ self.validate(target)
+
+ for fdict in (self.equiv, self.equiv_dist):
+ for i in fdict:
+ if i.startswith(target + "/"):
+ raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
+
+ self.equiv[target] = substitute
+ self.equal_ind = True
+ self.commit()
+
+ def modify_equal(self, target, substitute):
+ self.begin()
+ if target not in self.equiv.keys():
+ raise ValueError(_("Equivalence class for %s does not exists") % target)
+ self.equiv[target] = substitute
+ self.equal_ind = True
+ self.commit()
+
+ def createcon(self, target, seuser="system_u"):
+ (rc, con) = semanage_context_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create context for %s") % target)
+ if seuser == "":
+ seuser = "system_u"
+
+ rc = semanage_context_set_user(self.sh, con, seuser)
+ if rc < 0:
+ raise ValueError(_("Could not set user in file context for %s") % target)
+
+ rc = semanage_context_set_role(self.sh, con, "object_r")
+ if rc < 0:
+ raise ValueError(_("Could not set role in file context for %s") % target)
+
+ if is_mls_enabled == 1:
+ rc = semanage_context_set_mls(self.sh, con, "s0")
+ if rc < 0:
+ raise ValueError(_("Could not set mls fields in file context for %s") % target)
+
+ return con
+
+ def validate(self, target):
+ if target == "" or target.find("\n") >= 0:
+ raise ValueError(_("Invalid file specification"))
+ if target.find(" ") != -1:
+ raise ValueError(_("File specification can not include spaces"))
+ for fdict in (self.equiv, self.equiv_dist):
+ for i in fdict:
+ if target.startswith(i + "/"):
+ t = re.sub(i, fdict[i], target)
+ raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
+
+ def __add(self, target, type, ftype="", serange="", seuser="system_u"):
+ self.validate(target)
+
+ if is_mls_enabled == 1:
+ serange = untranslate(serange)
+
+ if type == "":
+ raise ValueError(_("SELinux Type is required"))
+
+ if type not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
+
+ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+ if rc < 0:
+ raise ValueError(_("Could not create key for %s") % target)
+
+ (rc, exists) = semanage_fcontext_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if file context for %s is defined") % target)
+
+ if not exists:
+ (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if file context for %s is defined") % target)
+
+ if exists:
+ raise ValueError(_("File context for %s already defined") % target)
+
+ (rc, fcontext) = semanage_fcontext_create(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not create file context for %s") % target)
+
+ rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
+ if type != "<<none>>":
+ con = self.createcon(target, seuser)
+
+ rc = semanage_context_set_type(self.sh, con, type)
+ if rc < 0:
+ raise ValueError(_("Could not set type in file context for %s") % target)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ rc = semanage_context_set_mls(self.sh, con, serange)
if rc < 0:
- raise ValueError(_("Could not set role in file context for %s") % target)
-
- if is_mls_enabled == 1:
- rc = semanage_context_set_mls(self.sh, con, "s0")
- if rc < 0:
- raise ValueError(_("Could not set mls fields in file context for %s") % target)
-
- return con
-
- def validate(self, target):
- if target == "" or target.find("\n") >= 0:
- raise ValueError(_("Invalid file specification"))
- if target.find(" ") != -1:
- raise ValueError(_("File specification can not include spaces"))
- for fdict in (self.equiv, self.equiv_dist):
- for i in fdict:
- if target.startswith(i+"/"):
- t = re.sub(i, fdict[i], target)
- raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
-
-
- def __add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
- self.validate(target)
-
- if is_mls_enabled == 1:
- serange = untranslate(serange)
-
- if type == "":
- raise ValueError(_("SELinux Type is required"))
-
- if type not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
-
- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
- if rc < 0:
- raise ValueError(_("Could not create key for %s") % target)
-
- (rc, exists) = semanage_fcontext_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if file context for %s is defined") % target)
-
- if not exists:
- (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if file context for %s is defined") % target)
-
- if exists:
- raise ValueError(_("File context for %s already defined") % target)
-
- (rc, fcontext) = semanage_fcontext_create(self.sh)
- if rc < 0:
- raise ValueError(_("Could not create file context for %s") % target)
-
- rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
- if type != "<<none>>":
- con = self.createcon(target, seuser)
-
- rc = semanage_context_set_type(self.sh, con, type)
- if rc < 0:
- raise ValueError(_("Could not set type in file context for %s") % target)
-
- if (is_mls_enabled == 1) and (serange != ""):
- rc = semanage_context_set_mls(self.sh, con, serange)
- if rc < 0:
- raise ValueError(_("Could not set mls fields in file context for %s") % target)
- rc = semanage_fcontext_set_con(self.sh, fcontext, con)
- if rc < 0:
- raise ValueError(_("Could not set file context for %s") % target)
-
- semanage_fcontext_set_type(fcontext, file_types[ftype])
-
- rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
- if rc < 0:
- raise ValueError(_("Could not add file context for %s") % target)
-
- if type != "<<none>>":
- semanage_context_free(con)
- semanage_fcontext_key_free(k)
- semanage_fcontext_free(fcontext)
-
- def add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
- self.begin()
- self.__add(target, type, ftype, serange, seuser)
- self.commit()
-
- def __modify(self, target, setype, ftype, serange, seuser):
- if serange == "" and setype == "" and seuser == "":
- raise ValueError(_("Requires setype, serange or seuser"))
- if setype and setype not in self.valid_types:
- raise ValueError(_("Type %s is invalid, must be a port type") % setype)
-
- self.validate(target)
-
- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % target)
-
- (rc, exists) = semanage_fcontext_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if file context for %s is defined") % target)
- if not exists:
- (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
- if not exists:
- raise ValueError(_("File context for %s is not defined") % target)
-
- (rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
- if rc < 0:
- (rc, fcontext) = semanage_fcontext_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query file context for %s") % target)
-
- if setype != "<<none>>":
- con = semanage_fcontext_get_con(fcontext)
-
- if con == None:
- con = self.createcon(target)
-
- if (is_mls_enabled == 1) and (serange != ""):
- semanage_context_set_mls(self.sh, con, untranslate(serange))
- if seuser != "":
- semanage_context_set_user(self.sh, con, seuser)
-
- if setype != "":
- semanage_context_set_type(self.sh, con, setype)
-
- rc = semanage_fcontext_set_con(self.sh, fcontext, con)
- if rc < 0:
- raise ValueError(_("Could not set file context for %s") % target)
- else:
- rc = semanage_fcontext_set_con(self.sh, fcontext, None)
- if rc < 0:
- raise ValueError(_("Could not set file context for %s") % target)
-
- rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
- if rc < 0:
- raise ValueError(_("Could not modify file context for %s") % target)
-
- semanage_fcontext_key_free(k)
- semanage_fcontext_free(fcontext)
-
- def modify(self, target, setype, ftype, serange, seuser):
- self.begin()
- self.__modify(target, setype, ftype, serange, seuser)
- self.commit()
-
- def deleteall(self):
- (rc, flist) = semanage_fcontext_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list the file contexts"))
-
- self.begin()
-
- for fcontext in flist:
- target = semanage_fcontext_get_expr(fcontext)
- ftype = semanage_fcontext_get_type(fcontext)
- ftype_str = semanage_fcontext_get_type_str(ftype)
- (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % target)
-
- rc = semanage_fcontext_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete the file context %s") % target)
- semanage_fcontext_key_free(k)
-
- self.equiv = {}
- self.equal_ind = True
- self.commit()
-
- def __delete(self, target, ftype):
- if target in self.equiv.keys():
- self.equiv.pop(target)
- self.equal_ind = True
- return
-
- (rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % target)
-
- (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if file context for %s is defined") % target)
- if not exists:
- (rc, exists) = semanage_fcontext_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if file context for %s is defined") % target)
- if exists:
- raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
- else:
- raise ValueError(_("File context for %s is not defined") % target)
-
- rc = semanage_fcontext_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete file context for %s") % target)
-
- semanage_fcontext_key_free(k)
-
- def delete(self, target, ftype):
- self.begin()
- self.__delete( target, ftype)
- self.commit()
-
- def get_all(self, locallist = 0):
- if locallist:
- (rc, self.flist) = semanage_fcontext_list_local(self.sh)
+ raise ValueError(_("Could not set mls fields in file context for %s") % target)
+ rc = semanage_fcontext_set_con(self.sh, fcontext, con)
+ if rc < 0:
+ raise ValueError(_("Could not set file context for %s") % target)
+
+ semanage_fcontext_set_type(fcontext, file_types[ftype])
+
+ rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
+ if rc < 0:
+ raise ValueError(_("Could not add file context for %s") % target)
+
+ if type != "<<none>>":
+ semanage_context_free(con)
+ semanage_fcontext_key_free(k)
+ semanage_fcontext_free(fcontext)
+
+ def add(self, target, type, ftype="", serange="", seuser="system_u"):
+ self.begin()
+ self.__add(target, type, ftype, serange, seuser)
+ self.commit()
+
+ def __modify(self, target, setype, ftype, serange, seuser):
+ if serange == "" and setype == "" and seuser == "":
+ raise ValueError(_("Requires setype, serange or seuser"))
+ if setype and setype not in self.valid_types:
+ raise ValueError(_("Type %s is invalid, must be a port type") % setype)
+
+ self.validate(target)
+
+ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % target)
+
+ (rc, exists) = semanage_fcontext_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if file context for %s is defined") % target)
+ if not exists:
+ (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+ if not exists:
+ raise ValueError(_("File context for %s is not defined") % target)
+
+ (rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
+ if rc < 0:
+ (rc, fcontext) = semanage_fcontext_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query file context for %s") % target)
+
+ if setype != "<<none>>":
+ con = semanage_fcontext_get_con(fcontext)
+
+ if con == None:
+ con = self.createcon(target)
+
+ if (is_mls_enabled == 1) and (serange != ""):
+ semanage_context_set_mls(self.sh, con, untranslate(serange))
+ if seuser != "":
+ semanage_context_set_user(self.sh, con, seuser)
+
+ if setype != "":
+ semanage_context_set_type(self.sh, con, setype)
+
+ rc = semanage_fcontext_set_con(self.sh, fcontext, con)
+ if rc < 0:
+ raise ValueError(_("Could not set file context for %s") % target)
+ else:
+ rc = semanage_fcontext_set_con(self.sh, fcontext, None)
+ if rc < 0:
+ raise ValueError(_("Could not set file context for %s") % target)
+
+ rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
+ if rc < 0:
+ raise ValueError(_("Could not modify file context for %s") % target)
+
+ semanage_fcontext_key_free(k)
+ semanage_fcontext_free(fcontext)
+
+ def modify(self, target, setype, ftype, serange, seuser):
+ self.begin()
+ self.__modify(target, setype, ftype, serange, seuser)
+ self.commit()
+
+ def deleteall(self):
+ (rc, flist) = semanage_fcontext_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list the file contexts"))
+
+ self.begin()
+
+ for fcontext in flist:
+ target = semanage_fcontext_get_expr(fcontext)
+ ftype = semanage_fcontext_get_type(fcontext)
+ ftype_str = semanage_fcontext_get_type_str(ftype)
+ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % target)
+
+ rc = semanage_fcontext_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete the file context %s") % target)
+ semanage_fcontext_key_free(k)
+
+ self.equiv = {}
+ self.equal_ind = True
+ self.commit()
+
+ def __delete(self, target, ftype):
+ if target in self.equiv.keys():
+ self.equiv.pop(target)
+ self.equal_ind = True
+ return
+
+ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % target)
+
+ (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if file context for %s is defined") % target)
+ if not exists:
+ (rc, exists) = semanage_fcontext_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if file context for %s is defined") % target)
+ if exists:
+ raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
+ else:
+ raise ValueError(_("File context for %s is not defined") % target)
+
+ rc = semanage_fcontext_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete file context for %s") % target)
+
+ semanage_fcontext_key_free(k)
+
+ def delete(self, target, ftype):
+ self.begin()
+ self.__delete(target, ftype)
+ self.commit()
+
+ def get_all(self, locallist=0):
+ if locallist:
+ (rc, self.flist) = semanage_fcontext_list_local(self.sh)
+ else:
+ (rc, self.flist) = semanage_fcontext_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list file contexts"))
+
+ (rc, fclocal) = semanage_fcontext_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list local file contexts"))
+
+ self.flist += fclocal
+
+ ddict = {}
+ for fcontext in self.flist:
+ expr = semanage_fcontext_get_expr(fcontext)
+ ftype = semanage_fcontext_get_type(fcontext)
+ ftype_str = semanage_fcontext_get_type_str(ftype)
+ con = semanage_fcontext_get_con(fcontext)
+ if con:
+ ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+ else:
+ ddict[(expr, ftype_str)] = con
+
+ return ddict
+
+ def customized(self):
+ l = []
+ fcon_dict = self.get_all(True)
+ keys = fcon_dict.keys()
+ keys.sort()
+ for k in keys:
+ if fcon_dict[k]:
+ l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
+
+ if len(self.equiv):
+ for target in self.equiv.keys():
+ l.append("-a -e %s %s" % (self.equiv[target], target))
+ return l
+
+ def list(self, heading=1, locallist=0):
+ fcon_dict = self.get_all(locallist)
+ keys = fcon_dict.keys()
+ if len(keys) != 0:
+ keys.sort()
+ if heading:
+ print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
+ for k in keys:
+ if fcon_dict[k]:
+ if is_mls_enabled:
+ print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3], False))
+ else:
+ print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2])
else:
- (rc, self.flist) = semanage_fcontext_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list file contexts"))
-
- (rc, fclocal) = semanage_fcontext_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list local file contexts"))
-
- self.flist += fclocal
-
- ddict = {}
- for fcontext in self.flist:
- expr = semanage_fcontext_get_expr(fcontext)
- ftype = semanage_fcontext_get_type(fcontext)
- ftype_str = semanage_fcontext_get_type_str(ftype)
- con = semanage_fcontext_get_con(fcontext)
- if con:
- ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
- else:
- ddict[(expr, ftype_str)] = con
-
- return ddict
-
- def customized(self):
- l = []
- fcon_dict = self.get_all(True)
- keys = fcon_dict.keys()
- keys.sort()
- for k in keys:
- if fcon_dict[k]:
- l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
-
- if len(self.equiv):
- for target in self.equiv.keys():
- l.append("-a -e %s %s" % (self.equiv[target], target))
- return l
-
- def list(self, heading = 1, locallist = 0 ):
- fcon_dict = self.get_all(locallist)
- keys = fcon_dict.keys()
- if len(keys) != 0:
- keys.sort()
- if heading:
- print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
- for k in keys:
- if fcon_dict[k]:
- if is_mls_enabled:
- print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3],False))
- else:
- print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1],fcon_dict[k][2])
- else:
- print "%-50s %-18s <<None>>" % (k[0], k[1])
-
- if len(self.equiv_dist):
- if not locallist:
- if heading:
- print _("\nSELinux Distribution fcontext Equivalence \n")
- for target in self.equiv_dist.keys():
- print "%s = %s" % (target, self.equiv_dist[target])
- if len(self.equiv):
- if heading:
- print _("\nSELinux Local fcontext Equivalence \n")
-
- for target in self.equiv.keys():
- print "%s = %s" % (target, self.equiv[target])
-
-class booleanRecords(semanageRecords):
- def __init__(self, store = ""):
- semanageRecords.__init__(self, store)
- self.dict = {}
- self.dict["TRUE"] = 1
- self.dict["FALSE"] = 0
- self.dict["ON"] = 1
- self.dict["OFF"] = 0
- self.dict["1"] = 1
- self.dict["0"] = 0
-
- try:
- rc, self.current_booleans = selinux.security_get_boolean_names()
- rc, ptype = selinux.selinux_getpolicytype()
- except:
- self.current_booleans = []
- ptype = None
-
- if self.store == None or self.store == ptype:
- self.modify_local = True
- else:
- self.modify_local = False
-
- def __mod(self, name, value):
- name = selinux.selinux_boolean_sub(name)
-
- (rc, k) = semanage_bool_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
- (rc, exists) = semanage_bool_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if boolean %s is defined") % name)
- if not exists:
- raise ValueError(_("Boolean %s is not defined") % name)
-
- (rc, b) = semanage_bool_query(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not query file context %s") % name)
+ print "%-50s %-18s <<None>>" % (k[0], k[1])
- if value.upper() in self.dict:
- semanage_bool_set_value(b, self.dict[value.upper()])
- else:
- raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()) )
-
- if self.modify_local and name in self.current_booleans:
- rc = semanage_bool_set_active(self.sh, k, b)
- if rc < 0:
- raise ValueError(_("Could not set active value of boolean %s") % name)
- rc = semanage_bool_modify_local(self.sh, k, b)
- if rc < 0:
- raise ValueError(_("Could not modify boolean %s") % name)
- semanage_bool_key_free(k)
- semanage_bool_free(b)
-
- def modify(self, name, value = None, use_file = False):
- self.begin()
- if use_file:
- fd = open(name)
- for b in fd.read().split("\n"):
- b = b.strip()
- if len(b) == 0:
- continue
-
- try:
- boolname, val = b.split("=")
- except ValueError:
- raise ValueError(_("Bad format %s: Record %s" % ( name, b) ))
- self.__mod(boolname.strip(), val.strip())
- fd.close()
- else:
- self.__mod(name, value)
+ if len(self.equiv_dist):
+ if not locallist:
+ if heading:
+ print _("\nSELinux Distribution fcontext Equivalence \n")
+ for target in self.equiv_dist.keys():
+ print "%s = %s" % (target, self.equiv_dist[target])
+ if len(self.equiv):
+ if heading:
+ print _("\nSELinux Local fcontext Equivalence \n")
- self.commit()
-
- def __delete(self, name):
- name = selinux.selinux_boolean_sub(name)
+ for target in self.equiv.keys():
+ print "%s = %s" % (target, self.equiv[target])
- (rc, k) = semanage_bool_key_create(self.sh, name)
- if rc < 0:
- raise ValueError(_("Could not create a key for %s") % name)
- (rc, exists) = semanage_bool_exists(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if boolean %s is defined") % name)
- if not exists:
- raise ValueError(_("Boolean %s is not defined") % name)
-
- (rc, exists) = semanage_bool_exists_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not check if boolean %s is defined") % name)
- if not exists:
- raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
-
- rc = semanage_bool_del_local(self.sh, k)
- if rc < 0:
- raise ValueError(_("Could not delete boolean %s") % name)
-
- semanage_bool_key_free(k)
-
- def delete(self, name):
- self.begin()
- self.__delete(name)
- self.commit()
-
- def deleteall(self):
- (rc, self.blist) = semanage_bool_list_local(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list booleans"))
-
- self.begin()
-
- for boolean in self.blist:
- name = semanage_bool_get_name(boolean)
- self.__delete(name)
-
- self.commit()
-
- def get_all(self, locallist = 0):
- ddict = {}
- if locallist:
- (rc, self.blist) = semanage_bool_list_local(self.sh)
- else:
- (rc, self.blist) = semanage_bool_list(self.sh)
- if rc < 0:
- raise ValueError(_("Could not list booleans"))
-
- for boolean in self.blist:
- value = []
- name = semanage_bool_get_name(boolean)
- value.append(semanage_bool_get_value(boolean))
- if self.modify_local and boolean in self.current_booleans:
- value.append(selinux.security_get_boolean_pending(name))
- value.append(selinux.security_get_boolean_active(name))
- else:
- value.append(value[0])
- value.append(value[0])
- ddict[name] = value
-
- return ddict
-
- def get_desc(self, name):
- name = selinux.selinux_boolean_sub(name)
- return boolean_desc(name)
-
- def get_category(self, name):
- name = selinux.selinux_boolean_sub(name)
- return boolean_category(name)
-
- def customized(self):
- l = []
- ddict = self.get_all(True)
- keys = ddict.keys()
- keys.sort()
- for k in keys:
- if ddict[k]:
- l.append("-m -%s %s" % (ddict[k][2], k))
- return l
-
- def list(self, heading = True, locallist = False, use_file = False):
- on_off = (_("off"), _("on"))
- if use_file:
- ddict = self.get_all(locallist)
- keys = ddict.keys()
- for k in keys:
- if ddict[k]:
- print "%s=%s" % (k, ddict[k][2])
- return
- ddict = self.get_all(locallist)
- keys = ddict.keys()
- if len(keys) == 0:
- return
-
- if heading:
- print "%-30s %s %s %s\n" % (_("SELinux boolean"),_("State"), _("Default"), _("Description"))
- for k in keys:
- if ddict[k]:
- print "%-30s (%-5s,%5s) %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))
+
+class booleanRecords(semanageRecords):
+
+ def __init__(self, store=""):
+ semanageRecords.__init__(self, store)
+ self.dict = {}
+ self.dict["TRUE"] = 1
+ self.dict["FALSE"] = 0
+ self.dict["ON"] = 1
+ self.dict["OFF"] = 0
+ self.dict["1"] = 1
+ self.dict["0"] = 0
+
+ try:
+ rc, self.current_booleans = selinux.security_get_boolean_names()
+ rc, ptype = selinux.selinux_getpolicytype()
+ except:
+ self.current_booleans = []
+ ptype = None
+
+ if self.store == None or self.store == ptype:
+ self.modify_local = True
+ else:
+ self.modify_local = False
+
+ def __mod(self, name, value):
+ name = selinux.selinux_boolean_sub(name)
+
+ (rc, k) = semanage_bool_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+ (rc, exists) = semanage_bool_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if boolean %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Boolean %s is not defined") % name)
+
+ (rc, b) = semanage_bool_query(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not query file context %s") % name)
+
+ if value.upper() in self.dict:
+ semanage_bool_set_value(b, self.dict[value.upper()])
+ else:
+ raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()))
+
+ if self.modify_local and name in self.current_booleans:
+ rc = semanage_bool_set_active(self.sh, k, b)
+ if rc < 0:
+ raise ValueError(_("Could not set active value of boolean %s") % name)
+ rc = semanage_bool_modify_local(self.sh, k, b)
+ if rc < 0:
+ raise ValueError(_("Could not modify boolean %s") % name)
+ semanage_bool_key_free(k)
+ semanage_bool_free(b)
+
+ def modify(self, name, value=None, use_file=False):
+ self.begin()
+ if use_file:
+ fd = open(name)
+ for b in fd.read().split("\n"):
+ b = b.strip()
+ if len(b) == 0:
+ continue
+
+ try:
+ boolname, val = b.split("=")
+ except ValueError:
+ raise ValueError(_("Bad format %s: Record %s" % (name, b)))
+ self.__mod(boolname.strip(), val.strip())
+ fd.close()
+ else:
+ self.__mod(name, value)
+
+ self.commit()
+
+ def __delete(self, name):
+ name = selinux.selinux_boolean_sub(name)
+
+ (rc, k) = semanage_bool_key_create(self.sh, name)
+ if rc < 0:
+ raise ValueError(_("Could not create a key for %s") % name)
+ (rc, exists) = semanage_bool_exists(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if boolean %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Boolean %s is not defined") % name)
+
+ (rc, exists) = semanage_bool_exists_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not check if boolean %s is defined") % name)
+ if not exists:
+ raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
+
+ rc = semanage_bool_del_local(self.sh, k)
+ if rc < 0:
+ raise ValueError(_("Could not delete boolean %s") % name)
+
+ semanage_bool_key_free(k)
+
+ def delete(self, name):
+ self.begin()
+ self.__delete(name)
+ self.commit()
+
+ def deleteall(self):
+ (rc, self.blist) = semanage_bool_list_local(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list booleans"))
+
+ self.begin()
+
+ for boolean in self.blist:
+ name = semanage_bool_get_name(boolean)
+ self.__delete(name)
+
+ self.commit()
+
+ def get_all(self, locallist=0):
+ ddict = {}
+ if locallist:
+ (rc, self.blist) = semanage_bool_list_local(self.sh)
+ else:
+ (rc, self.blist) = semanage_bool_list(self.sh)
+ if rc < 0:
+ raise ValueError(_("Could not list booleans"))
+
+ for boolean in self.blist:
+ value = []
+ name = semanage_bool_get_name(boolean)
+ value.append(semanage_bool_get_value(boolean))
+ if self.modify_local and boolean in self.current_booleans:
+ value.append(selinux.security_get_boolean_pending(name))
+ value.append(selinux.security_get_boolean_active(name))
+ else:
+ value.append(value[0])
+ value.append(value[0])
+ ddict[name] = value
+
+ return ddict
+
+ def get_desc(self, name):
+ name = selinux.selinux_boolean_sub(name)
+ return boolean_desc(name)
+
+ def get_category(self, name):
+ name = selinux.selinux_boolean_sub(name)
+ return boolean_category(name)
+
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ if ddict[k]:
+ l.append("-m -%s %s" % (ddict[k][2], k))
+ return l
+
+ def list(self, heading=True, locallist=False, use_file=False):
+ on_off = (_("off"), _("on"))
+ if use_file:
+ ddict = self.get_all(locallist)
+ keys = ddict.keys()
+ for k in keys:
+ if ddict[k]:
+ print "%s=%s" % (k, ddict[k][2])
+ return
+ ddict = self.get_all(locallist)
+ keys = ddict.keys()
+ if len(keys) == 0:
+ return
+
+ if heading:
+ print "%-30s %s %s %s\n" % (_("SELinux boolean"), _("State"), _("Default"), _("Description"))
+ for k in keys:
+ if ddict[k]:
+ print "%-30s (%-5s,%5s) %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))
diff --git a/policycoreutils/semanage/test-semanage.py b/policycoreutils/semanage/test-semanage.py
index d39013eb..293e1fdc 100644
--- a/policycoreutils/semanage/test-semanage.py
+++ b/policycoreutils/semanage/test-semanage.py
@@ -1,59 +1,65 @@
-import unittest, os, shutil, sys
+import unittest
+import os
+import shutil
+import sys
from tempfile import mkdtemp
from subprocess import Popen, PIPE
import argparse
-object_list = [ 'login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean','permissive', "dontaudit"]
+object_list = ['login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean', 'permissive', "dontaudit"]
+
class SemanageTests(unittest.TestCase):
+
def assertDenied(self, err):
self.assertTrue('Permission denied' in err,
- '"Permission denied" not found in %r' % err)
+ '"Permission denied" not found in %r' % err)
+
def assertNotFound(self, err):
self.assertTrue('not found' in err,
- '"not found" not found in %r' % err)
+ '"not found" not found in %r' % err)
def assertFailure(self, status):
self.assertTrue(status != 0,
- '"semanage succeeded when it should have failed')
+ '"semanage succeeded when it should have failed')
def assertSuccess(self, status, err):
self.assertTrue(status == 0,
- '"semanage should have succeeded for this test %r' % err)
+ '"semanage should have succeeded for this test %r' % err)
def test_extract(self):
for object in object_list:
- if object in ["dontaudit","module","permissive"]:
+ if object in ["dontaudit", "module", "permissive"]:
continue
"Verify semanage %s -E" % object
- p = Popen(['semanage', object, '-E'], stdout = PIPE)
+ p = Popen(['semanage', object, '-E'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_input_output(self):
print("Verify semanage export -f /tmp/out")
- p = Popen(['semanage', "export", '-f', '/tmp/out'], stdout = PIPE)
+ p = Popen(['semanage', "export", '-f', '/tmp/out'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage export -S targeted -f -")
- p = Popen(["semanage","export","-S","targeted","-f","-"], stdout = PIPE)
+ p = Popen(["semanage", "export", "-S", "targeted", "-f", "-"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage -S targeted -o -")
- p = Popen(["semanage","-S","targeted","-o","-"], stdout = PIPE)
+ p = Popen(["semanage", "-S", "targeted", "-o", "-"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage import -f /tmp/out")
- p = Popen(['semanage', "import", '-f', '/tmp/out'], stdout = PIPE)
+ p = Popen(['semanage', "import", '-f', '/tmp/out'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage import -S targeted -f /tmp/out")
- p = Popen(["semanage","import","-S","targeted","-f", "/tmp/out"], stdout = PIPE)
+ p = Popen(["semanage", "import", "-S", "targeted", "-f", "/tmp/out"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage -S targeted -i /tmp/out")
- p = Popen(["semanage", "-S","targeted","-i", "/tmp/out"], stdout = PIPE)
+ p = Popen(["semanage", "-S", "targeted", "-i", "/tmp/out"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
@@ -62,7 +68,7 @@ class SemanageTests(unittest.TestCase):
if object in ["dontaudit"]:
continue
"Verify semanage %s -l" % object
- p = Popen(['semanage', object, '-l'], stdout = PIPE)
+ p = Popen(['semanage', object, '-l'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
@@ -71,165 +77,170 @@ class SemanageTests(unittest.TestCase):
if object in ["module", "permissive", "dontaudit"]:
continue
print("Verify semanage %s -l" % object)
- p = Popen(['semanage', object, '-lC'], stdout = PIPE)
+ p = Popen(['semanage', object, '-lC'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_fcontext(self):
- p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?" ], stderr = PIPE)
- out, err = p.communicate()
+ p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stderr=PIPE)
+ out, err = p.communicate()
- print("Verify semanage fcontext -a")
- p = Popen(["semanage", "fcontext", "-a", "-t", "httpd_sys_content_t", "/ha-web(/.*)?" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage fcontext -m")
- p = Popen(["semanage", "fcontext", "-m", "-t", "default_t", "/ha-web(/.*)?" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage fcontext -d")
- p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -a")
+ p = Popen(["semanage", "fcontext", "-a", "-t", "httpd_sys_content_t", "/ha-web(/.*)?"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -m")
+ p = Popen(["semanage", "fcontext", "-m", "-t", "default_t", "/ha-web(/.*)?"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -d")
+ p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
def test_fcontext_e(self):
- p = Popen(["semanage", "fcontext", "-d", "/myhome" ], stderr = PIPE)
- out, err = p.communicate()
- p = Popen(["semanage", "fcontext", "-d", "/myhome1" ], stderr = PIPE)
- out, err = p.communicate()
+ p = Popen(["semanage", "fcontext", "-d", "/myhome"], stderr=PIPE)
+ out, err = p.communicate()
+ p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stderr=PIPE)
+ out, err = p.communicate()
- print("Verify semanage fcontext -a -e")
- p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage fcontext -m -e")
- p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome1" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage fcontext -d -e")
- p = Popen(["semanage", "fcontext", "-d", "/myhome1" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -a -e")
+ p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -m -e")
+ p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome1"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage fcontext -d -e")
+ p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
def test_port(self):
- # Cleanup
- p = Popen(["semanage", "port", "-d", "-p", "tcp", "55" ], stdout = PIPE, stderr = PIPE)
- out, err = p.communicate()
+ # Cleanup
+ p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
- # test
- print("Verify semanage port -a")
- p = Popen(["semanage", "port", "-a", "-t", "ssh_port_t", "-p", "tcp", "55" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage port -m")
- p = Popen(["semanage", "port", "-m", "-t", "http_port_t", "-p", "tcp", "55" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage port -d")
- p = Popen(["semanage", "port", "-d", "-p", "tcp", "55" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
+ # test
+ print("Verify semanage port -a")
+ p = Popen(["semanage", "port", "-a", "-t", "ssh_port_t", "-p", "tcp", "55"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage port -m")
+ p = Popen(["semanage", "port", "-m", "-t", "http_port_t", "-p", "tcp", "55"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage port -d")
+ p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
def test_login(self):
- # Cleanup
- p = Popen(["userdel", "-f", "-r", "testlogin" ], stderr = PIPE, stdout = PIPE)
- out, err = p.communicate()
- p = Popen(["semanage", "user", "-d", "testuser_u" ], stderr = PIPE, stdout = PIPE)
- out, err = p.communicate()
- p = Popen(["semanage", "login", "-d", "testlogin" ], stderr = PIPE, stdout = PIPE)
- out, err = p.communicate()
+ # Cleanup
+ p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
+ out, err = p.communicate()
+ p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
+ out, err = p.communicate()
+ p = Popen(["semanage", "login", "-d", "testlogin"], stderr=PIPE, stdout=PIPE)
+ out, err = p.communicate()
- #test
- print("Verify semanage user -a")
- p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify useradd ")
- p = Popen(["useradd", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage login -a")
- p = Popen(["semanage", "login", "-a", "-s", "testuser_u", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage login -m -r")
- p = Popen(["semanage", "login", "-m", "-r", "s0-s0:c1", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage login -m -s")
- p = Popen(["semanage", "login", "-m", "-s", "staff_u", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage login -m -s -r")
- p = Popen(["semanage", "login", "-m", "-s", "testuser_u", "-r", "s0", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage login -d")
- p = Popen(["semanage", "login", "-d", "testlogin" ], stdout = PIPE)
- out, err = p.communicate()
- print("Verify userdel ")
- p = Popen(["userdel", "-f", "-r", "testlogin" ], stderr = PIPE, stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage user -d")
- p = Popen(["semanage", "user", "-d", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
+ #test
+ print("Verify semanage user -a")
+ p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify useradd ")
+ p = Popen(["useradd", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage login -a")
+ p = Popen(["semanage", "login", "-a", "-s", "testuser_u", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage login -m -r")
+ p = Popen(["semanage", "login", "-m", "-r", "s0-s0:c1", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage login -m -s")
+ p = Popen(["semanage", "login", "-m", "-s", "staff_u", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage login -m -s -r")
+ p = Popen(["semanage", "login", "-m", "-s", "testuser_u", "-r", "s0", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage login -d")
+ p = Popen(["semanage", "login", "-d", "testlogin"], stdout=PIPE)
+ out, err = p.communicate()
+ print("Verify userdel ")
+ p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage user -d")
+ p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
def test_user(self):
- # Cleanup
- p = Popen(["semanage", "user", "-d", "testuser_u" ], stderr = PIPE, stdout = PIPE)
- out, err = p.communicate()
+ # Cleanup
+ p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
+ out, err = p.communicate()
- # test
- print("Verify semanage user -a")
- p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage user -m -R")
- p = Popen(["semanage", "user", "-m", "-R", "sysadm_r unconfined_r", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage user -m -r")
- p = Popen(["semanage", "user", "-m", "-r", "s0-s0:c1", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
- print("Verify semanage user -d")
- p = Popen(["semanage", "user", "-d", "testuser_u" ], stdout = PIPE)
- out, err = p.communicate()
- self.assertSuccess(p.returncode, err)
+ # test
+ print("Verify semanage user -a")
+ p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage user -m -R")
+ p = Popen(["semanage", "user", "-m", "-R", "sysadm_r unconfined_r", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage user -m -r")
+ p = Popen(["semanage", "user", "-m", "-r", "s0-s0:c1", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
+ print("Verify semanage user -d")
+ p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
+ out, err = p.communicate()
+ self.assertSuccess(p.returncode, err)
def test_boolean(self):
import selinux
- boolean_status={0:"--off",1:"--on"}
- boolean_state=selinux.security_get_boolean_active("httpd_anon_write")
+ boolean_status = {0: "--off", 1: "--on"}
+ boolean_state = selinux.security_get_boolean_active("httpd_anon_write")
# Test
print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[not boolean_state])
- p = Popen(["semanage","boolean","-m",boolean_status[(not boolean_state)],"httpd_anon_write"], stdout = PIPE)
+ p = Popen(["semanage", "boolean", "-m", boolean_status[(not boolean_state)], "httpd_anon_write"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[boolean_state])
- p = Popen(["semanage","boolean","-m",boolean_status[boolean_state],"httpd_anon_write"], stdout = PIPE)
+ p = Popen(["semanage", "boolean", "-m", boolean_status[boolean_state], "httpd_anon_write"], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
+
def semanage_suite():
semanage_suite = unittest.TestSuite()
semanage_suite.addTest(unittest.makeSuite(SemanageTests))
return semanage_suite
+
def semanage_custom_suite(test_list):
- suiteSemanage=unittest.TestSuite()
+ suiteSemanage = unittest.TestSuite()
for t in test_list:
suiteSemanage.addTest(SemanageTests(t))
return suiteSemanage
+
def semanage_run_test(suite):
unittest.TextTestRunner(verbosity=2).run(suite)
+
class CheckTest(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
@@ -240,6 +251,7 @@ class CheckTest(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, newval)
+
def semanage_args(args):
if args.list:
print("You can run the following tests:")
@@ -250,22 +262,23 @@ def semanage_args(args):
if args.test:
semanage_run_test(semanage_custom_suite(args.test))
+
def gen_semanage_test_args(parser):
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', "--all", dest="all", default=False,
- action="store_true",
- help=("Run all semanage unit tests"))
+ action="store_true",
+ help=("Run all semanage unit tests"))
group.add_argument('-l', "--list", dest="list", default=False,
- action="store_true",
- help=("List all semanage unit tests"))
+ action="store_true",
+ help=("List all semanage unit tests"))
group.add_argument('-t', "--test", dest="test", default=[],
- action=CheckTest, nargs="*",
- help=("Run selected semanage unit test(s)"))
+ action=CheckTest, nargs="*",
+ help=("Run selected semanage unit test(s)"))
group.set_defaults(func=semanage_args)
if __name__ == "__main__":
import selinux
- semanage_test_list=filter(lambda x: x.startswith("test_"), dir(SemanageTests))
+ semanage_test_list = filter(lambda x: x.startswith("test_"), dir(SemanageTests))
if selinux.security_getenforce() == 1:
parser = argparse.ArgumentParser(description='Semanage unit test script')
gen_semanage_test_args(parser)
@@ -273,10 +286,10 @@ if __name__ == "__main__":
args = parser.parse_args()
args.func(args)
sys.exit(0)
- except ValueError,e:
+ except ValueError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
- except IOError,e:
+ except IOError as e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except KeyboardInterrupt:
diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index dde0efbd..9cd04e76 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -41,6 +41,11 @@ remove existing module
.B \-l,\-\-list-modules=[KIND]
display list of installed modules (other than base)
.TP
+.B \-E,\-\-extract=MODULE_PKG
+Extract a module from the store as an HLL or CIL file to the current directory.
+A module is extracted as HLL by default. The name of the module written is
+<module-name>.<lang_ext>
+.TP
.B KIND:
.TP
standard
@@ -81,6 +86,12 @@ Use an alternate path for the policy store root
.TP
.B \-v,\-\-verbose
be verbose
+.TP
+.B \-c,\-\-cil
+Extract module as a CIL file. This only affects the \-\-extract option.
+.TP
+.B \-H,\-\-hll
+Extract module as an HLL file. This only affects the \-\-extract option.
.SH EXAMPLE
.nf
@@ -108,6 +119,9 @@ $ semodule \-l full
$ semodule \-B \-p "/tmp"
# Set an alternate path for the policy store root
$ semodule \-B \-S "/tmp/var/lib/selinux"
+# Write the HLL version of puppet and the CIL version of wireshark
+# modules at priority 400 to the current working directory
+$ semodule \-X 400 \-g wireshark \-\-cil \-g puppet \-\-hll
.fi
.SH SEE ALSO
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index baff057d..bcfaa2bd 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -20,16 +20,17 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <libgen.h>
+#include <limits.h>
#include <semanage/modules.h>
enum client_modes {
- NO_MODE, INSTALL_M, REMOVE_M,
+ NO_MODE, INSTALL_M, REMOVE_M, EXTRACT_M, CIL_M, HLL_M,
LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
};
/* list of modes in which one ought to commit afterwards */
static const int do_commit[] = {
- 0, 1, 1,
+ 0, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1,
};
@@ -49,10 +50,12 @@ static int disable_dontaudit;
static int preserve_tunables;
static int ignore_module_cache;
static uint16_t priority;
+static int priority_set = 0;
static semanage_handle_t *sh = NULL;
static char *store;
static char *store_root;
+int extract_cil = 0;
extern char *optarg;
extern int optind;
@@ -130,6 +133,7 @@ static void usage(char *progname)
printf(" -X,--priority=PRIORITY set priority for following operations (1-999)\n");
printf(" -e,--enable=MODULE_NAME enable module\n");
printf(" -d,--disable=MODULE_NAME disable module\n");
+ printf(" -E,--extract=MODULE_NAME extract module\n");
printf("Other options:\n");
printf(" -s,--store name of the store to operate on\n");
printf(" -N,-n,--noreload do not reload policy after commit\n");
@@ -140,6 +144,8 @@ static void usage(char *progname)
printf(" -C,--ignore-module-cache Rebuild CIL modules compiled from HLL files\n");
printf(" -p,--path use an alternate path for the policy root\n");
printf(" -S,--store-path use an alternate path for the policy store root\n");
+ printf(" -c, --cil extract module as cil. This only affects module extraction.\n");
+ printf(" -H, --hll extract module as hll. This only affects module extraction.\n");
}
/* Sets the global mode variable to new_mode, but only if no other
@@ -175,6 +181,9 @@ static void parse_command_line(int argc, char **argv)
{"base", required_argument, NULL, 'b'},
{"help", 0, NULL, 'h'},
{"install", required_argument, NULL, 'i'},
+ {"extract", required_argument, NULL, 'E'},
+ {"cil", 0, NULL, 'c'},
+ {"hll", 0, NULL, 'H'},
{"list-modules", optional_argument, NULL, 'l'},
{"verbose", 0, NULL, 'v'},
{"remove", required_argument, NULL, 'r'},
@@ -192,13 +201,15 @@ static void parse_command_line(int argc, char **argv)
{"store-path", required_argument, NULL, 'S'},
{NULL, 0, NULL, 0}
};
+ int extract_selected = 0;
+ int cil_hll_set = 0;
int i;
verbose = 0;
reload = 0;
no_reload = 0;
priority = 400;
while ((i =
- getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:", opts,
+ getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:E:cH", opts,
NULL)) != -1) {
switch (i) {
case 'b':
@@ -211,6 +222,18 @@ static void parse_command_line(int argc, char **argv)
case 'i':
set_mode(INSTALL_M, optarg);
break;
+ case 'E':
+ set_mode(EXTRACT_M, optarg);
+ extract_selected = 1;
+ break;
+ case 'c':
+ set_mode(CIL_M, NULL);
+ cil_hll_set = 1;
+ break;
+ case 'H':
+ set_mode(HLL_M, NULL);
+ cil_hll_set = 1;
+ break;
case 'l':
set_mode(LIST_M, optarg);
break;
@@ -281,10 +304,15 @@ static void parse_command_line(int argc, char **argv)
usage(argv[0]);
exit(1);
}
+ if (extract_selected == 0 && cil_hll_set == 1) {
+ fprintf(stderr, "--cil and --hll require a module to export with the --extract option.\n");
+ usage(argv[0]);
+ exit(1);
+ }
if (optind < argc) {
int mode;
- /* if -i/u/r was the last command treat any remaining
+ /* if -i/u/r/E was the last command treat any remaining
* arguments as args. Will allow 'semodule -i *.pp' to
* work as expected.
*/
@@ -293,6 +321,8 @@ static void parse_command_line(int argc, char **argv)
mode = INSTALL_M;
} else if (commands && commands[num_commands - 1].mode == REMOVE_M) {
mode = REMOVE_M;
+ } else if (commands && commands[num_commands - 1].mode == EXTRACT_M) {
+ mode = EXTRACT_M;
} else {
fprintf(stderr, "unknown additional arguments:\n");
while (optind < argc)
@@ -389,6 +419,113 @@ int main(int argc, char *argv[])
semanage_module_install_file(sh, mode_arg);
break;
}
+ case EXTRACT_M:{
+ semanage_module_info_t *extract_info = NULL;
+ semanage_module_key_t *modkey = NULL;
+ uint16_t curr_priority;
+ void *data = NULL;
+ size_t data_len = 0;
+ char output_path[PATH_MAX];
+ const char *output_name = NULL;
+ const char *lang_ext = NULL;
+ int rlen;
+ FILE *output_fd = NULL;
+
+ result = semanage_module_key_create(sh, &modkey);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ result = semanage_module_key_set_name(sh, modkey, mode_arg);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ if (priority_set == 0) {
+ result = semanage_module_get_module_info(sh, modkey, &extract_info);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ semanage_module_info_get_priority(sh, extract_info, &curr_priority);
+ printf("Module '%s' does not exist at the default priority '%d'. "
+ "Extracting at highest existing priority '%d'.\n", mode_arg, priority, curr_priority);
+ priority = curr_priority;
+ }
+
+ result = semanage_module_key_set_priority(sh, modkey, priority);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ if (verbose) {
+ printf
+ ("Attempting to extract module '%s':\n",
+ mode_arg);
+ }
+ result = semanage_module_extract(sh, modkey, extract_cil, &data, &data_len, &extract_info);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ if (extract_cil) {
+ lang_ext = "cil";
+ } else {
+ result = semanage_module_info_get_lang_ext(sh, extract_info, &lang_ext);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+ }
+
+ result = semanage_module_info_get_name(sh, extract_info, &output_name);
+ if (result != 0) {
+ goto cleanup_extract;
+ }
+
+ rlen = snprintf(output_path, PATH_MAX, "%s.%s", output_name, lang_ext);
+ if (rlen < 0 || rlen >= PATH_MAX) {
+ fprintf(stderr, "%s: Failed to generate output path.\n", argv[0]);
+ result = -1;
+ goto cleanup_extract;
+ }
+
+ if (access(output_path, F_OK) == 0) {
+ fprintf(stderr, "%s: %s is already extracted with extension %s.\n", argv[0], mode_arg, lang_ext);
+ result = -1;
+ goto cleanup_extract;
+ }
+
+ output_fd = fopen(output_path, "w");
+ if (output_fd == NULL) {
+ fprintf(stderr, "%s: Unable to open %s\n", argv[0], output_path);
+ result = -1;
+ goto cleanup_extract;
+ }
+
+ if (fwrite(data, 1, data_len, output_fd) < data_len) {
+ fprintf(stderr, "%s: Unable to write to %s\n", argv[0], output_path);
+ result = -1;
+ goto cleanup_extract;
+ }
+cleanup_extract:
+ if (output_fd != NULL) {
+ fclose(output_fd);
+ }
+ if (data_len > 0) {
+ munmap(data, data_len);
+ }
+ semanage_module_info_destroy(sh, extract_info);
+ free(extract_info);
+ semanage_module_key_destroy(sh, modkey);
+ free(modkey);
+ break;
+ }
+ case CIL_M:
+ extract_cil = 1;
+ break;
+ case HLL_M:
+ extract_cil = 0;
+ break;
case REMOVE_M:{
if (verbose) {
printf
@@ -515,6 +652,7 @@ cleanup_list:
case PRIORITY_M:{
char *endptr = NULL;
priority = (uint16_t)strtoul(mode_arg, &endptr, 10);
+ priority_set = 1;
if ((result = semanage_set_default_priority(sh, priority)) != 0) {
fprintf(stderr,
diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
index 458a4d21..7f4a91c1 100644
--- a/policycoreutils/sepolicy/selinux_client.py
+++ b/policycoreutils/sepolicy/selinux_client.py
@@ -2,6 +2,7 @@ import dbus
import dbus.service
from sepolicy.sedbus import SELinuxDBus
+
def convert_customization(buf):
cust_dict = {}
cust_dict["fcontext-equiv"] = {}
@@ -14,24 +15,24 @@ def convert_customization(buf):
if rec[0] not in cust_dict:
cust_dict[rec[0]] = {}
if rec[0] == "boolean":
- cust_dict["boolean"][rec[-1]] = { "active": rec[2] == "-1" }
+ cust_dict["boolean"][rec[-1]] = {"active": rec[2] == "-1"}
if rec[0] == "login":
- cust_dict["login"][rec[-1]] = { "seuser": rec[3], "range": rec[5] }
+ cust_dict["login"][rec[-1]] = {"seuser": rec[3], "range": rec[5]}
if rec[0] == "interface":
- cust_dict["login"][rec[-1]] = { "type": rec[3] }
+ cust_dict["login"][rec[-1]] = {"type": rec[3]}
if rec[0] == "user":
- cust_dict["user"][rec[-1]] = { "level": rec[3], "range": rec[5], "role": rec[7] }
+ cust_dict["user"][rec[-1]] = {"level": rec[3], "range": rec[5], "role": rec[7]}
if rec[0] == "port":
- cust_dict["port"][(rec[-1], rec[-2] )] = { "type": rec[3] }
+ cust_dict["port"][(rec[-1], rec[-2])] = {"type": rec[3]}
if rec[0] == "node":
- cust_dict["node"][rec[-1]] = { "mask": rec[3], "protocol":rec[5], "type": rec[7] }
+ cust_dict["node"][rec[-1]] = {"mask": rec[3], "protocol": rec[5], "type": rec[7]}
if rec[0] == "fcontext":
if rec[2] == "-e":
- cust_dict["fcontext-equiv"][(rec[-1])] = { "equiv": rec[3] }
+ cust_dict["fcontext-equiv"][(rec[-1])] = {"equiv": rec[3]}
else:
- cust_dict["fcontext"][(rec[-1],rec[3])] = { "type": rec[5] }
+ cust_dict["fcontext"][(rec[-1], rec[3])] = {"type": rec[5]}
if rec[0] == "module":
- cust_dict["module"][rec[-1]] = { "enabled": rec[2] != "-d" }
+ cust_dict["module"][rec[-1]] = {"enabled": rec[2] != "-d"}
return cust_dict
if __name__ == "__main__":
diff --git a/policycoreutils/sepolicy/selinux_server.py b/policycoreutils/sepolicy/selinux_server.py
index e94c38fc..cdf4d168 100644
--- a/policycoreutils/sepolicy/selinux_server.py
+++ b/policycoreutils/sepolicy/selinux_server.py
@@ -10,9 +10,11 @@ import os
import selinux
from subprocess import Popen, PIPE, STDOUT
+
class selinux_server(slip.dbus.service.Object):
default_polkit_auth_required = "org.selinux.semanage"
- def __init__ (self, *p, **k):
+
+ def __init__(self, *p, **k):
super(selinux_server, self).__init__(*p, **k)
#
@@ -22,7 +24,7 @@ class selinux_server(slip.dbus.service.Object):
@slip.dbus.polkit.require_auth("org.selinux.semanage")
@dbus.service.method("org.selinux", in_signature='s')
def semanage(self, buf):
- p = Popen(["/usr/sbin/semanage", "import"],stdout=PIPE, stderr=PIPE, stdin=PIPE)
+ p = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE)
p.stdin.write(buf)
output = p.communicate()
if p.returncode and p.returncode != 0:
@@ -36,7 +38,7 @@ class selinux_server(slip.dbus.service.Object):
@slip.dbus.polkit.require_auth("org.selinux.customized")
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
def customized(self):
- p = Popen(["/usr/sbin/semanage", "export"],stdout=PIPE, stderr=PIPE)
+ p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE)
buf = p.stdout.read()
output = p.communicate()
if p.returncode and p.returncode != 0:
@@ -50,7 +52,7 @@ class selinux_server(slip.dbus.service.Object):
@slip.dbus.polkit.require_auth("org.selinux.semodule_list")
@dbus.service.method("org.selinux", in_signature='', out_signature='s')
def semodule_list(self):
- p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE)
+ p = Popen(["/usr/sbin/semodule", "-l"], stdout=PIPE, stderr=PIPE)
buf = p.stdout.read()
output = p.communicate()
if p.returncode and p.returncode != 0:
@@ -80,7 +82,7 @@ class selinux_server(slip.dbus.service.Object):
@dbus.service.method("org.selinux", in_signature='i')
def relabel_on_boot(self, value):
if value == 1:
- fd = open("/.autorelabel","w")
+ fd = open("/.autorelabel", "w")
fd.close()
else:
os.unlink("/.autorelabel")
@@ -109,12 +111,11 @@ class selinux_server(slip.dbus.service.Object):
@slip.dbus.polkit.require_auth("org.selinux.change_default_mode")
@dbus.service.method("org.selinux", in_signature='s')
def change_default_mode(self, value):
- values = [ "enforcing", "permissive", "disabled" ]
+ values = ["enforcing", "permissive", "disabled"]
if value not in values:
raise ValueError("Enforcement mode must be %s" % ", ".join(values))
self.write_selinux_config(enforcing=value)
-
#
# The change_default_policy method modifies the policy type
#
@@ -127,10 +128,10 @@ class selinux_server(slip.dbus.service.Object):
raise ValueError("%s does not exist" % path)
if __name__ == "__main__":
- mainloop = gobject.MainLoop()
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- system_bus = dbus.SystemBus()
- name = dbus.service.BusName("org.selinux", system_bus)
- object = selinux_server(system_bus, "/org/selinux/object")
- slip.dbus.service.set_mainloop(mainloop)
- mainloop.run()
+ mainloop = gobject.MainLoop()
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+ system_bus = dbus.SystemBus()
+ name = dbus.service.BusName("org.selinux", system_bus)
+ object = selinux_server(system_bus, "/org/selinux/object")
+ slip.dbus.service.set_mainloop(mainloop)
+ mainloop.run()
diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
index 74fb3476..08a5c2fb 100755
--- a/policycoreutils/sepolicy/sepolicy.py
+++ b/policycoreutils/sepolicy/sepolicy.py
@@ -21,38 +21,43 @@
# 02111-1307 USA
#
#
-import os, sys
+import os
+import sys
import selinux
import sepolicy
from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text
import argparse
import gettext
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
usage = "sepolicy generate [-h] [-n NAME] [-p PATH] ["
-usage_dict = {' --newtype':('-t [TYPES [TYPES ...]]',),' --customize':('-d DOMAIN','-a ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --admin_user':('[-r TRANSITION_ROLE ]',"[ -w WRITEPATHS ]",), ' --application':('COMMAND',"[ -w WRITEPATHS ]",), ' --cgi':('COMMAND',"[ -w WRITEPATHS ]",), ' --confined_admin':('-a ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --dbus':('COMMAND',"[ -w WRITEPATHS ]",), ' --desktop_user':('',"[ -w WRITEPATHS ]",),' --inetd':('COMMAND',"[ -w WRITEPATHS ]",),' --init':('COMMAND',"[ -w WRITEPATHS ]",), ' --sandbox':("[ -w WRITEPATHS ]",), ' --term_user':("[ -w WRITEPATHS ]",), ' --x_user':("[ -w WRITEPATHS ]",)}
+usage_dict = {' --newtype': ('-t [TYPES [TYPES ...]]',), ' --customize': ('-d DOMAIN', '-a ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --admin_user': ('[-r TRANSITION_ROLE ]', "[ -w WRITEPATHS ]",), ' --application': ('COMMAND', "[ -w WRITEPATHS ]",), ' --cgi': ('COMMAND', "[ -w WRITEPATHS ]",), ' --confined_admin': ('-a ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --dbus': ('COMMAND', "[ -w WRITEPATHS ]",), ' --desktop_user': ('', "[ -w WRITEPATHS ]",), ' --inetd': ('COMMAND', "[ -w WRITEPATHS ]",), ' --init': ('COMMAND', "[ -w WRITEPATHS ]",), ' --sandbox': ("[ -w WRITEPATHS ]",), ' --term_user': ("[ -w WRITEPATHS ]",), ' --x_user': ("[ -w WRITEPATHS ]",)}
+
class CheckPath(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
if not os.path.exists(values):
- raise ValueError("%s does not exist" % values)
+ raise ValueError("%s does not exist" % values)
setattr(namespace, self.dest, values)
+
class CheckType(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
domains = sepolicy.get_all_domains()
- if isinstance(values,str):
+ if isinstance(values, str):
setattr(namespace, self.dest, values)
else:
newval = getattr(namespace, self.dest)
@@ -63,14 +68,16 @@ class CheckType(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, newval)
+
class CheckBoolean(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
booleans = sepolicy.get_all_booleans()
newval = getattr(namespace, self.dest)
if not newval:
newval = []
- if isinstance(values,str):
+ if isinstance(values, str):
v = selinux.selinux_boolean_sub(values)
if v not in booleans:
raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans)))
@@ -84,11 +91,13 @@ class CheckBoolean(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, newval)
+
class CheckDomain(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
domains = sepolicy.get_all_domains()
- if isinstance(values,str):
+ if isinstance(values, str):
if values not in domains:
raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains)))
setattr(namespace, self.dest, values)
@@ -104,17 +113,22 @@ class CheckDomain(argparse.Action):
setattr(namespace, self.dest, newval)
all_classes = None
+
+
class CheckClass(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
global all_classes
if not all_classes:
- all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
+ all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
if values not in all_classes:
raise ValueError("%s must be an SELinux class:\nValid classes: %s" % (values, ", ".join(all_classes)))
setattr(namespace, self.dest, values)
+
class CheckAdmin(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.interface import get_admin
newval = getattr(namespace, self.dest)
@@ -126,7 +140,9 @@ class CheckAdmin(argparse.Action):
newval.append(values)
setattr(namespace, self.dest, newval)
+
class CheckPort(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
@@ -137,7 +153,9 @@ class CheckPort(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, newval)
+
class CheckPortType(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
port_types = sepolicy.get_all_port_types()
newval = getattr(namespace, self.dest)
@@ -149,13 +167,17 @@ class CheckPortType(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, values)
+
class LoadPolicy(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
import sepolicy
sepolicy.policy(values)
setattr(namespace, self.dest, values)
+
class CheckPolicyType(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
from sepolicy.generate import get_poltype_desc, poltype
if values not in poltype.keys():
@@ -163,31 +185,37 @@ class CheckPolicyType(argparse.Action):
newval.append(v)
setattr(namespace, self.dest, values)
+
class CheckUser(argparse.Action):
+
def __call__(self, parser, namespace, value, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
newval = []
users = sepolicy.get_all_users()
if value not in users:
- raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
+ raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
newval.append(value)
setattr(namespace, self.dest, newval)
+
class CheckRole(argparse.Action):
+
def __call__(self, parser, namespace, value, option_string=None):
newval = getattr(namespace, self.dest)
if not newval:
newval = []
roles = sepolicy.get_all_roles()
if value not in roles:
- raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
+ raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
newval.append(value[:-2])
setattr(namespace, self.dest, newval)
+
class InterfaceInfo(argparse.Action):
+
def __call__(self, parser, namespace, values, option_string=None):
- from sepolicy.interface import get_interface_dict
+ from sepolicy.interface import get_interface_dict
interface_dict = get_interface_dict()
for v in values:
if v not in interface_dict.keys():
@@ -195,19 +223,21 @@ class InterfaceInfo(argparse.Action):
setattr(namespace, self.dest, values)
-def generate_custom_usage(usage_text,usage_dict):
+
+def generate_custom_usage(usage_text, usage_dict):
sorted_keys = []
for i in usage_dict.keys():
sorted_keys.append(i)
sorted_keys.sort()
for k in sorted_keys:
- usage_text += "%s %s |" % (k,(" ".join(usage_dict[k])))
+ usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
usage_text = usage_text[:-1] + "]"
usage_text = _(usage_text)
return usage_text
-def numcmp(val1,val2):
+
+def numcmp(val1, val2):
try:
v1 = int(val1.split(",")[0].split("-")[0])
v2 = int(val2.split(",")[0].split("-")[0])
@@ -218,28 +248,30 @@ def numcmp(val1,val2):
if v1 < v2:
return -1
except:
- return cmp(val1,val2)
+ return cmp(val1, val2)
+
def _print_net(src, protocol, perm):
import sepolicy.network
portdict = sepolicy.network.get_network_connect(src, protocol, perm)
if len(portdict) > 0:
- bold_start="\033[1m"
- bold_end="\033[0;0m"
- print "\n"+bold_start+"%s: %s %s" % (src, protocol, perm) + bold_end
- port_strings=[]
- boolean_text=""
+ bold_start = "\033[1m"
+ bold_end = "\033[0;0m"
+ print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
+ port_strings = []
+ boolean_text = ""
for p in portdict:
for t, recs in portdict[p]:
- cond=get_conditionals(src,t,"%s_socket" % protocol, [perm])
+ cond = get_conditionals(src, t, "%s_socket" % protocol, [perm])
if cond:
- boolean_text=get_conditionals_format_text(cond)
+ boolean_text = get_conditionals_format_text(cond)
port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text))
else:
port_strings.append("%s (%s)" % (", ".join(recs), t))
port_strings.sort(numcmp)
for p in port_strings:
- print "\t" + p
+ print "\t" + p
+
def network(args):
portrecs, portrecsbynum = sepolicy.gen_port_dict()
@@ -268,10 +300,10 @@ def network(args):
print "Undefined port type"
for t in args.type:
- if (t,'tcp') in portrecs.keys():
- print "%s: tcp: %s" % (t, ",".join(portrecs[t,'tcp']))
- if (t,'udp') in portrecs.keys():
- print "%s: udp: %s" % (t, ",".join(portrecs[t,'udp']))
+ if (t, 'tcp') in portrecs.keys():
+ print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
+ if (t, 'udp') in portrecs.keys():
+ print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
for a in args.applications:
d = sepolicy.get_init_transtype(a)
@@ -283,6 +315,7 @@ def network(args):
for net in ("tcp", "udp"):
_print_net(d, net, "name_bind")
+
def gui_run(args):
try:
import sepolicy.gui
@@ -291,16 +324,18 @@ def gui_run(args):
except ImportError:
raise ValueError(_("You need to install policycoreutils-gui package to use the gui option"))
+
def gen_gui_args(parser):
gui = parser.add_parser("gui",
help=_('Graphical User Interface for SELinux Policy'))
gui.add_argument("-d", "--domain", default=None,
- action=CheckDomain,
- help=_("Domain name(s) of man pages to be created"))
+ action=CheckDomain,
+ help=_("Domain name(s) of man pages to be created"))
gui.add_argument("-t", "--test", default=False, action="store_true",
- help=argparse.SUPPRESS)
+ help=argparse.SUPPRESS)
gui.set_defaults(func=gui_run)
+
def manpage(args):
from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains
@@ -316,12 +351,13 @@ def manpage(args):
test_domains = args.domain
for domain in test_domains:
- m = ManPage(domain, path, args.root,args.source_files, args.web)
+ m = ManPage(domain, path, args.root, args.source_files, args.web)
print m.get_man_page_path()
if args.web:
HTMLManPages(manpage_roles, manpage_domains, path, args.os)
+
def gen_manpage_args(parser):
man = parser.add_parser("manpage",
help=_('Generate SELinux man pages'))
@@ -345,37 +381,40 @@ def gen_manpage_args(parser):
help=_("Domain name(s) of man pages to be created"))
man.set_defaults(func=manpage)
+
def gen_network_args(parser):
- net = parser.add_parser("network",
- help=_('Query SELinux policy network information'))
-
- group = net.add_mutually_exclusive_group(required=True)
- group.add_argument("-l", "--list", dest="list_ports",
- action="store_true",
- help=_("list all SELinux port types"))
- group.add_argument("-p", "--port", dest="port", default=[],
- action=CheckPort, nargs="+", type=int,
- help=_("show SELinux type related to the port"))
- group.add_argument("-t", "--type", dest="type", default=[],
- action=CheckPortType,nargs="+",
- help=_("Show ports defined for this SELinux type"))
- group.add_argument("-d", "--domain", dest="domain", default=[],
- action=CheckDomain, nargs="+",
- help=_("show ports to which this domain can bind and/or connect"))
- group.add_argument("-a", "--application", dest="applications", default=[],
- nargs="+",
- help=_("show ports to which this application can bind and/or connect"))
- net.set_defaults(func=network)
+ net = parser.add_parser("network",
+ help=_('Query SELinux policy network information'))
+
+ group = net.add_mutually_exclusive_group(required=True)
+ group.add_argument("-l", "--list", dest="list_ports",
+ action="store_true",
+ help=_("list all SELinux port types"))
+ group.add_argument("-p", "--port", dest="port", default=[],
+ action=CheckPort, nargs="+", type=int,
+ help=_("show SELinux type related to the port"))
+ group.add_argument("-t", "--type", dest="type", default=[],
+ action=CheckPortType, nargs="+",
+ help=_("Show ports defined for this SELinux type"))
+ group.add_argument("-d", "--domain", dest="domain", default=[],
+ action=CheckDomain, nargs="+",
+ help=_("show ports to which this domain can bind and/or connect"))
+ group.add_argument("-a", "--application", dest="applications", default=[],
+ nargs="+",
+ help=_("show ports to which this application can bind and/or connect"))
+ net.set_defaults(func=network)
+
def communicate(args):
- from sepolicy.communicate import get_types
+ from sepolicy.communicate import get_types
- writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
- readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
- out = list(set(writable) & set(readable))
+ writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
+ readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
+ out = list(set(writable) & set(readable))
+
+ for t in out:
+ print t
- for t in out:
- print t
def gen_communicate_args(parser):
comm = parser.add_parser("communicate",
@@ -389,10 +428,11 @@ def gen_communicate_args(parser):
comm.add_argument("-c", "--class", required=False, dest="tclass",
action=CheckClass,
default="file", help="class to use for communications, Default 'file'")
- comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess", default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'")
- comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess", default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'")
+ comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess", default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'")
+ comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess", default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'")
comm.set_defaults(func=communicate)
+
def booleans(args):
from sepolicy import boolean_desc
if args.all:
@@ -402,6 +442,7 @@ def booleans(args):
for b in args.booleans:
print "%s=_(\"%s\")" % (b, boolean_desc(b))
+
def gen_booleans_args(parser):
bools = parser.add_parser("booleans",
help=_('query SELinux Policy to see description of booleans'))
@@ -414,11 +455,13 @@ def gen_booleans_args(parser):
help=_("boolean to get description"))
bools.set_defaults(func=booleans)
+
def transition(args):
from sepolicy.transition import setrans
mytrans = setrans(args.source, args.target)
mytrans.output()
+
def gen_transition_args(parser):
trans = parser.add_parser("transition",
help=_('query SELinux Policy to see how a source process domain can transition to the target process domain'))
@@ -430,6 +473,7 @@ def gen_transition_args(parser):
help=_("target process domain"))
trans.set_defaults(func=transition)
+
def print_interfaces(interfaces, args, append=""):
from sepolicy.interface import get_interface_format_text, interface_compile_test
for i in interfaces:
@@ -446,6 +490,7 @@ def print_interfaces(interfaces, args, append=""):
else:
print i
+
def interface(args):
from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces
if args.list_admin:
@@ -455,13 +500,14 @@ def interface(args):
if args.list:
print_interfaces(get_all_interfaces(args.file), args)
if args.interfaces:
- print_interfaces(args.interfaces, args)
+ print_interfaces(args.interfaces, args)
+
def generate(args):
from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE
cmd = None
# numbers present POLTYPE defined in sepolicy.generate
- conflict_args = {'TYPES':(NEWTYPE,), 'DOMAIN':(EUSER,), 'ADMIN_DOMAIN':(AUSER, RUSER, EUSER,)}
+ conflict_args = {'TYPES': (NEWTYPE,), 'DOMAIN': (EUSER,), 'ADMIN_DOMAIN': (AUSER, RUSER, EUSER,)}
error_text = ""
if args.policytype is None:
@@ -477,7 +523,7 @@ def generate(args):
raise ValueError(_("Command required for this type of policy"))
cmd = os.path.realpath(args.command)
if not args.name:
- args.name = os.path.basename(cmd).replace("-","_")
+ args.name = os.path.basename(cmd).replace("-", "_")
mypolicy = policy(args.name, args.policytype)
if cmd:
@@ -498,7 +544,7 @@ def generate(args):
if len(args.writepaths) > 0 and args.policytype == NEWTYPE:
- raise ValueError(_("-w option can not be used with the --newtype option"))
+ raise ValueError(_("-w option can not be used with the --newtype option"))
for p in args.writepaths:
if os.path.isdir(p):
@@ -516,6 +562,7 @@ def generate(args):
mypolicy.gen_symbols()
print mypolicy.generate(args.path)
+
def gen_interface_args(parser):
itf = parser.add_parser("interface",
help=_('List SELinux Policy interfaces'))
@@ -528,12 +575,12 @@ def gen_interface_args(parser):
itf.add_argument("-f", "--file", dest="file",
help="Interface file")
group = itf.add_mutually_exclusive_group(required=True)
- group.add_argument("-a", "--list_admin", dest="list_admin",action="store_true", default=False,
+ group.add_argument("-a", "--list_admin", dest="list_admin", action="store_true", default=False,
help="List all domains with admin interface - DOMAIN_admin()")
- group.add_argument("-u", "--list_user", dest="list_user",action="store_true",
+ group.add_argument("-u", "--list_user", dest="list_user", action="store_true",
default=False,
help="List all domains with SELinux user role interface - DOMAIN_role()")
- group.add_argument("-l", "--list", dest="list",action="store_true",
+ group.add_argument("-l", "--list", dest="list", action="store_true",
default=False,
help="List all interfaces")
group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces",
@@ -541,23 +588,24 @@ def gen_interface_args(parser):
help=_("Enter interface names, you wish to query"))
itf.set_defaults(func=interface)
+
def gen_generate_args(parser):
from sepolicy.generate import DAEMON, get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE
generate_usage = generate_custom_usage(usage, usage_dict)
- pol = parser.add_parser("generate", usage = generate_usage,
+ pol = parser.add_parser("generate", usage=generate_usage,
help=_('Generate SELinux Policy module template'))
pol.add_argument("-d", "--domain", dest="domain", default=[],
action=CheckDomain, nargs="*",
help=_("Enter domain type which you will be extending"))
pol.add_argument("-u", "--user", dest="user", default=[],
- action=CheckUser,
+ action=CheckUser,
help=_("Enter SELinux user(s) which will transition to this domain"))
pol.add_argument("-r", "--role", dest="role", default=[],
action=CheckRole,
help=_("Enter SELinux role(s) to which the administror domain will transition"))
- pol.add_argument("-a", "--admin", dest="admin_domain",default=[],
+ pol.add_argument("-a", "--admin", dest="admin_domain", default=[],
action=CheckAdmin,
help=_("Enter domain(s) which this confined admin will administrate"))
pol.add_argument("-n", "--name", dest="name",
@@ -566,29 +614,29 @@ def gen_generate_args(parser):
pol.add_argument("-T", "--test", dest="test", default=False, action="store_true",
help=argparse.SUPPRESS)
pol.add_argument("-t", "--type", dest="types", default=[], nargs="*",
- action=CheckType,
+ action=CheckType,
help="Enter type(s) for which you will generate new definition and rule(s)")
pol.add_argument("-p", "--path", dest="path", default=os.getcwd(),
help=_("path in which the generated policy files will be stored"))
- pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default = [],
+ pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default=[],
help=_("path to which the confined processes will need to write"))
cmdtype = pol.add_argument_group(_("Policy types which require a command"))
cmdgroup = cmdtype.add_mutually_exclusive_group(required=False)
cmdgroup.add_argument("--application", dest="policytype", const=USER,
- action="store_const",
- help=_("Generate '%s' policy") % poltype[USER])
+ action="store_const",
+ help=_("Generate '%s' policy") % poltype[USER])
cmdgroup.add_argument("--cgi", dest="policytype", const=CGI,
- action="store_const",
- help=_("Generate '%s' policy") % poltype[CGI])
+ action="store_const",
+ help=_("Generate '%s' policy") % poltype[CGI])
cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS,
- action="store_const",
- help=_("Generate '%s' policy") % poltype[DBUS])
+ action="store_const",
+ help=_("Generate '%s' policy") % poltype[DBUS])
cmdgroup.add_argument("--inetd", dest="policytype", const=INETD,
- action="store_const",
- help=_("Generate '%s' policy") % poltype[INETD])
+ action="store_const",
+ help=_("Generate '%s' policy") % poltype[INETD])
cmdgroup.add_argument("--init", dest="policytype", const=DAEMON,
- action="store_const", default=DAEMON,
- help=_("Generate '%s' policy") % poltype[DAEMON])
+ action="store_const", default=DAEMON,
+ help=_("Generate '%s' policy") % poltype[DAEMON])
type = pol.add_argument_group("Policy types which do not require a command")
group = type.add_mutually_exclusive_group(required=False)
@@ -616,7 +664,7 @@ def gen_generate_args(parser):
group.add_argument("--x_user", dest="policytype", const=XUSER,
action="store_const",
help=_("Generate '%s' policy") % poltype[XUSER])
- pol.add_argument("command",nargs="?", default=None,
+ pol.add_argument("command", nargs="?", default=None,
help=_("executable to confine"))
pol.set_defaults(func=generate)
@@ -637,15 +685,15 @@ if __name__ == '__main__':
try:
if os.path.basename(sys.argv[0]) == "sepolgen":
- args = parser.parse_args([ "generate" ] + sys.argv[1:])
+ args = parser.parse_args(["generate"] + sys.argv[1:])
else:
args = parser.parse_args()
args.func(args)
sys.exit(0)
- except ValueError,e:
+ except ValueError, e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
- except IOError,e:
+ except IOError, e:
sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
sys.exit(1)
except KeyboardInterrupt:
diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
index 679725d7..693c6fe6 100644
--- a/policycoreutils/sepolicy/sepolicy/__init__.py
+++ b/policycoreutils/sepolicy/sepolicy/__init__.py
@@ -4,8 +4,9 @@
# Author: Ryan Hallisey <rhallise@redhat.com>
import _policy
-import selinux, glob
-PROGNAME="policycoreutils"
+import selinux
+import glob
+PROGNAME = "policycoreutils"
import gettext
import sepolgen.defaults as defaults
import sepolgen.interfaces as interfaces
@@ -16,7 +17,7 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
@@ -27,7 +28,7 @@ ATTRIBUTE = _policy.ATTRIBUTE
PORT = _policy.PORT
USER = _policy.USER
BOOLEAN = _policy.BOOLEAN
-TCLASS = _policy.CLASS
+TCLASS = _policy.CLASS
ALLOW = 'allow'
AUDITALLOW = 'auditallow'
@@ -40,11 +41,13 @@ CLASS = 'class'
TRANSITION = 'transition'
ROLE_ALLOW = 'role_allow'
+
def info(setype, name=None):
dict_list = _policy.info(setype, name)
return dict_list
-def search(types, info = {}):
+
+def search(types, info={}):
seinfo = info
valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]
for setype in types:
@@ -62,35 +65,38 @@ def search(types, info = {}):
dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list)
return dict_list
-def get_conditionals(src,dest,tclass,perm):
+
+def get_conditionals(src, dest, tclass, perm):
tdict = {}
tlist = []
if dest.endswith("_t"):
- allows=search([ALLOW],{SOURCE:src,TARGET:dest,CLASS:tclass,PERMS:perm})
+ allows = search([ALLOW], {SOURCE: src, TARGET: dest, CLASS: tclass, PERMS: perm})
else:
# to include attribute
- allows=search([ALLOW],{SOURCE:src,CLASS:tclass,PERMS:perm})
+ allows = search([ALLOW], {SOURCE: src, CLASS: tclass, PERMS: perm})
for i in allows:
if i['target'] == dest:
- allows=[]
+ allows = []
allows.append(i)
try:
for i in map(lambda y: (y), filter(lambda x: set(perm).issubset(x[PERMS]) and x['boolean'], allows)):
- tdict.update({'source':i['source'],'boolean':i['boolean']})
+ tdict.update({'source': i['source'], 'boolean': i['boolean']})
if tdict not in tlist:
tlist.append(tdict)
- tdict={}
+ tdict = {}
except KeyError:
return(tlist)
return (tlist)
+
def get_conditionals_format_text(cond):
enabled = len(filter(lambda x: x['boolean'][0][1], cond)) > 0
return _("-- Allowed %s [ %s ]") % (enabled, " || ".join(set(map(lambda x: "%s=%d" % (x['boolean'][0][0], x['boolean'][0][1]), cond))))
+
def get_types_from_attribute(attribute):
- return info(ATTRIBUTE,attribute)[0]["types"]
+ return info(ATTRIBUTE, attribute)[0]["types"]
file_type_str = {}
file_type_str["a"] = _("all files")
@@ -112,9 +118,10 @@ trans_file_type_str["-s"] = "s"
trans_file_type_str["-l"] = "l"
trans_file_type_str["-p"] = "p"
+
def get_file_types(setype):
- flist=[]
- mpaths={}
+ flist = []
+ mpaths = {}
for f in get_all_file_types():
if f.startswith(gen_short_name(setype)):
flist.append(f)
@@ -126,12 +133,13 @@ def get_file_types(setype):
mpaths[f] = []
return mpaths
+
def get_writable_files(setype):
all_attributes = get_all_attributes()
file_types = get_all_file_types()
all_writes = []
mpaths = {}
- permlist = search([ALLOW],{'source':setype, 'permlist':['open', 'write'], 'class':'file'})
+ permlist = search([ALLOW], {'source': setype, 'permlist': ['open', 'write'], 'class': 'file'})
if permlist == None or len(permlist) == 0:
return mpaths
@@ -159,13 +167,17 @@ def get_writable_files(setype):
try:
mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]])
except KeyError:
- mpaths[f] = [] #{"regex":[],"paths":[]}
+ mpaths[f] = [] # {"regex":[],"paths":[]}
return mpaths
-import os, re, sys
+import os
+import re
+import sys
+
+
def find_file(reg):
if os.path.exists(reg):
- return [ reg ]
+ return [reg]
try:
pat = re.compile(r"%s$" % reg)
except:
@@ -190,7 +202,8 @@ def find_file(reg):
except:
return []
-def find_all_files(domain, exclude_list = []):
+
+def find_all_files(domain, exclude_list=[]):
all_entrypoints = []
executable_files = get_entrypoints(domain)
for exe in executable_files.keys():
@@ -202,7 +215,9 @@ def find_all_files(domain, exclude_list = []):
return None
#return all_entrypoints
-def find_entrypoint_path(exe, exclude_list = []):
+
+
+def find_entrypoint_path(exe, exclude_list=[]):
fcdict = get_fcdict()
try:
if exe.endswith("_exec_t") and exe not in exclude_list:
@@ -213,40 +228,47 @@ def find_entrypoint_path(exe, exclude_list = []):
pass
return None
+
def read_file_equiv(edict, fc_path, modify):
- fd = open(fc_path, "r")
- fc = fd.readlines()
- fd.close()
- for e in fc:
- f = e.split()
- edict[f[0]] = { "equiv" : f[1], "modify" : modify }
- return edict
-
-file_equiv_modified=None
-def get_file_equiv_modified(fc_path = selinux.selinux_file_context_path()):
- global file_equiv_modified
- if file_equiv_modified:
- return file_equiv_modified
- file_equiv_modified = {}
- file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True)
+ fd = open(fc_path, "r")
+ fc = fd.readlines()
+ fd.close()
+ for e in fc:
+ f = e.split()
+ edict[f[0]] = {"equiv": f[1], "modify": modify}
+ return edict
+
+file_equiv_modified = None
+
+
+def get_file_equiv_modified(fc_path=selinux.selinux_file_context_path()):
+ global file_equiv_modified
+ if file_equiv_modified:
return file_equiv_modified
+ file_equiv_modified = {}
+ file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True)
+ return file_equiv_modified
+
+file_equiv = None
-file_equiv=None
-def get_file_equiv(fc_path = selinux.selinux_file_context_path()):
- global file_equiv
- if file_equiv:
- return file_equiv
- file_equiv = get_file_equiv_modified(fc_path)
- file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify = False)
+
+def get_file_equiv(fc_path=selinux.selinux_file_context_path()):
+ global file_equiv
+ if file_equiv:
return file_equiv
+ file_equiv = get_file_equiv_modified(fc_path)
+ file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify=False)
+ return file_equiv
+
+local_files = None
+
-local_files=None
-def get_local_file_paths(fc_path = selinux.selinux_file_context_path()):
+def get_local_file_paths(fc_path=selinux.selinux_file_context_path()):
global local_files
if local_files:
return local_files
- local_files=[]
- fd = open(fc_path+".local", "r")
+ local_files = []
+ fd = open(fc_path + ".local", "r")
fc = fd.readlines()
fd.close()
for i in fc:
@@ -264,19 +286,21 @@ def get_local_file_paths(fc_path = selinux.selinux_file_context_path()):
pass
return local_files
-fcdict=None
-def get_fcdict(fc_path = selinux.selinux_file_context_path()):
+fcdict = None
+
+
+def get_fcdict(fc_path=selinux.selinux_file_context_path()):
global fcdict
if fcdict:
return fcdict
fd = open(fc_path, "r")
fc = fd.readlines()
fd.close()
- fd = open(fc_path+".homedirs", "r")
+ fd = open(fc_path + ".homedirs", "r")
fc += fd.readlines()
fd.close()
fcdict = {}
- fd = open(fc_path+".local", "r")
+ fd = open(fc_path + ".local", "r")
fc += fd.readlines()
fd.close()
@@ -292,45 +316,49 @@ def get_fcdict(fc_path = selinux.selinux_file_context_path()):
if t in fcdict:
fcdict[t]["regex"].append(rec[0])
else:
- fcdict[t] = { "regex": [ rec[0] ], "ftype": ftype}
+ fcdict[t] = {"regex": [rec[0]], "ftype": ftype}
except:
pass
- fcdict["logfile"] = { "regex" : [ "all log files" ]}
- fcdict["user_tmp_type"] = { "regex" : [ "all user tmp files" ]}
- fcdict["user_home_type"] = { "regex" : [ "all user home files" ]}
- fcdict["virt_image_type"] = { "regex" : [ "all virtual image files" ]}
- fcdict["noxattrfs"] = { "regex" : [ "all files on file systems which do not support extended attributes" ]}
- fcdict["sandbox_tmpfs_type"] = { "regex" : [ "all sandbox content in tmpfs file systems" ]}
- fcdict["user_tmpfs_type"] = { "regex" : [ "all user content in tmpfs file systems" ]}
- fcdict["file_type"] = { "regex" : [ "all files on the system" ]}
- fcdict["samba_share_t"] = { "regex" : [ "use this label for random content that will be shared using samba" ]}
+ fcdict["logfile"] = {"regex": ["all log files"]}
+ fcdict["user_tmp_type"] = {"regex": ["all user tmp files"]}
+ fcdict["user_home_type"] = {"regex": ["all user home files"]}
+ fcdict["virt_image_type"] = {"regex": ["all virtual image files"]}
+ fcdict["noxattrfs"] = {"regex": ["all files on file systems which do not support extended attributes"]}
+ fcdict["sandbox_tmpfs_type"] = {"regex": ["all sandbox content in tmpfs file systems"]}
+ fcdict["user_tmpfs_type"] = {"regex": ["all user content in tmpfs file systems"]}
+ fcdict["file_type"] = {"regex": ["all files on the system"]}
+ fcdict["samba_share_t"] = {"regex": ["use this label for random content that will be shared using samba"]}
return fcdict
+
def get_transitions_into(setype):
try:
- return filter(lambda x: x["transtype"] == setype, search([TRANSITION],{ 'class':'process'}))
+ return filter(lambda x: x["transtype"] == setype, search([TRANSITION], {'class': 'process'}))
except TypeError:
pass
return None
+
def get_transitions(setype):
try:
- return search([TRANSITION],{'source':setype, 'class':'process'})
+ return search([TRANSITION], {'source': setype, 'class': 'process'})
except TypeError:
pass
return None
+
def get_file_transitions(setype):
try:
- return filter(lambda x: x['class'] != "process", search([TRANSITION],{'source':setype}))
+ return filter(lambda x: x['class'] != "process", search([TRANSITION], {'source': setype}))
except TypeError:
pass
return None
+
def get_boolean_rules(setype, boolean):
boollist = []
- permlist = search([ALLOW],{'source':setype })
+ permlist = search([ALLOW], {'source': setype})
for p in permlist:
if "boolean" in p:
try:
@@ -341,21 +369,24 @@ def get_boolean_rules(setype, boolean):
pass
return boollist
+
def get_all_entrypoints():
return get_types_from_attribute("entry_type")
+
def get_entrypoint_types(setype):
entrypoints = []
try:
- entrypoints = map(lambda x: x['target'],filter(lambda x: x['source'] == setype, search([ALLOW],{'source':setype, 'permlist':['entrypoint'], 'class':'file'})))
+ entrypoints = map(lambda x: x['target'], filter(lambda x: x['source'] == setype, search([ALLOW], {'source': setype, 'permlist': ['entrypoint'], 'class': 'file'})))
except TypeError:
pass
return entrypoints
+
def get_init_transtype(path):
entrypoint = selinux.getfilecon(path)[1].split(":")[2]
try:
- entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION],{'source':"init_t", 'class':'process'}))
+ entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION], {'source': "init_t", 'class': 'process'}))
if len(entrypoints) == 0:
return None
return entrypoints[0]["transtype"]
@@ -363,9 +394,10 @@ def get_init_transtype(path):
pass
return None
+
def get_init_entrypoint(transtype):
try:
- entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION],{'source':"init_t", 'class':'process'}))
+ entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION], {'source': "init_t", 'class': 'process'}))
if len(entrypoints) == 0:
return None
return entrypoints[0]["target"]
@@ -373,14 +405,16 @@ def get_init_entrypoint(transtype):
pass
return None
+
def get_init_entrypoint_target(entrypoint):
try:
- entrypoints = map(lambda x: x['transtype'], search([TRANSITION],{'source':"init_t", 'target':entrypoint, 'class':'process'}))
+ entrypoints = map(lambda x: x['transtype'], search([TRANSITION], {'source': "init_t", 'target': entrypoint, 'class': 'process'}))
return entrypoints[0]
except TypeError:
pass
return None
+
def get_entrypoints(setype):
fcdict = get_fcdict()
mpaths = {}
@@ -391,10 +425,11 @@ def get_entrypoints(setype):
mpaths[f] = []
return mpaths
-def get_installed_policy(root = "/"):
+
+def get_installed_policy(root="/"):
try:
path = root + selinux.selinux_binary_policy_path()
- policies = glob.glob ("%s.*" % path )
+ policies = glob.glob("%s.*" % path)
policies.sort()
return policies[-1]
except:
@@ -402,6 +437,8 @@ def get_installed_policy(root = "/"):
raise ValueError(_("No SELinux Policy installed"))
methods = []
+
+
def get_methods():
global methods
if len(methods) > 0:
@@ -423,39 +460,46 @@ def get_methods():
return methods
all_types = None
+
+
def get_all_types():
global all_types
if all_types == None:
all_types = map(lambda x: x['name'], info(TYPE))
return all_types
-user_types = None
+user_types = None
+
+
def get_user_types():
global user_types
if user_types == None:
- user_types = info(ATTRIBUTE,"userdomain")[0]["types"]
+ user_types = info(ATTRIBUTE, "userdomain")[0]["types"]
return user_types
role_allows = None
-def get_all_role_allows():
- global role_allows
- if role_allows:
- return role_allows
- role_allows = {}
- for r in search([ROLE_ALLOW]):
- if r["source"] == "system_r" or r["target"] == "system_r":
- continue
- if r["source"] in role_allows:
- role_allows[r["source"]].append(r["target"])
- else:
- role_allows[r["source"]] = [ r["target"] ]
+
+def get_all_role_allows():
+ global role_allows
+ if role_allows:
return role_allows
+ role_allows = {}
+ for r in search([ROLE_ALLOW]):
+ if r["source"] == "system_r" or r["target"] == "system_r":
+ continue
+ if r["source"] in role_allows:
+ role_allows[r["source"]].append(r["target"])
+ else:
+ role_allows[r["source"]] = [r["target"]]
+
+ return role_allows
+
def get_all_entrypoint_domains():
import re
all_domains = []
- types=get_all_types()
+ types = get_all_types()
types.sort()
for i in types:
m = re.findall("(.*)%s" % "_exec_t$", i)
@@ -467,6 +511,7 @@ def get_all_entrypoint_domains():
portrecs = None
portrecsbynum = None
+
def gen_interfaces():
import commands
ifile = defaults.interface_info()
@@ -482,11 +527,12 @@ def gen_interfaces():
raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
print commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1]
+
def gen_port_dict():
global portrecs
global portrecsbynum
if portrecs:
- return ( portrecs, portrecsbynum )
+ return (portrecs, portrecsbynum)
portrecsbynum = {}
portrecs = {}
for i in info(PORT):
@@ -496,94 +542,111 @@ def gen_port_dict():
port = "%s-%s" % (str(i['low']), str(i['high']))
if (i['type'], i['protocol']) in portrecs:
- portrecs [(i['type'], i['protocol'])].append(port)
+ portrecs[(i['type'], i['protocol'])].append(port)
else:
- portrecs [(i['type'], i['protocol'])] = [port]
+ portrecs[(i['type'], i['protocol'])] = [port]
if 'range' in i:
- portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'], i['range'])
+ portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type'], i['range'])
else:
- portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'])
+ portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type'])
- return ( portrecs, portrecsbynum )
+ return (portrecs, portrecsbynum)
all_domains = None
+
+
def get_all_domains():
- global all_domains
- if not all_domains:
- all_domains = info(ATTRIBUTE,"domain")[0]["types"]
- return all_domains
+ global all_domains
+ if not all_domains:
+ all_domains = info(ATTRIBUTE, "domain")[0]["types"]
+ return all_domains
roles = None
+
+
def get_all_roles():
- global roles
- if roles:
- return roles
- roles = map(lambda x: x['name'], info(ROLE))
- roles.remove("object_r")
- roles.sort()
+ global roles
+ if roles:
return roles
+ roles = map(lambda x: x['name'], info(ROLE))
+ roles.remove("object_r")
+ roles.sort()
+ return roles
selinux_user_list = None
+
+
def get_selinux_users():
global selinux_user_list
if not selinux_user_list:
selinux_user_list = info(USER)
for x in selinux_user_list:
- x['range']="".join(x['range'].split(" "))
+ x['range'] = "".join(x['range'].split(" "))
return selinux_user_list
login_mappings = None
+
+
def get_login_mappings():
global login_mappings
if login_mappings:
return login_mappings
fd = open(selinux.selinux_usersconf_path(), "r")
- buf=fd.read()
+ buf = fd.read()
fd.close()
login_mappings = []
- for b in buf.split("\n"):
+ for b in buf.split("\n"):
b = b.strip()
if len(b) == 0 or b.startswith("#"):
continue
x = b.split(":")
- login_mappings.append({ "name": x[0], "seuser": x[1], "mls":":".join(x[2:])})
+ login_mappings.append({"name": x[0], "seuser": x[1], "mls": ":".join(x[2:])})
return login_mappings
+
def get_all_users():
users = map(lambda x: x['name'], get_selinux_users())
users.sort()
return users
file_types = None
+
+
def get_all_file_types():
- global file_types
- if file_types:
- return file_types
- file_types = info(ATTRIBUTE,"file_type")[0]["types"]
- file_types.sort()
+ global file_types
+ if file_types:
return file_types
+ file_types = info(ATTRIBUTE, "file_type")[0]["types"]
+ file_types.sort()
+ return file_types
port_types = None
+
+
def get_all_port_types():
- global port_types
- if port_types:
- return port_types
- port_types = info(ATTRIBUTE,"port_type")[0]["types"]
- port_types.sort()
+ global port_types
+ if port_types:
return port_types
+ port_types = info(ATTRIBUTE, "port_type")[0]["types"]
+ port_types.sort()
+ return port_types
bools = None
+
+
def get_all_bools():
- global bools
- if not bools:
- bools = info(BOOLEAN)
- return bools
+ global bools
+ if not bools:
+ bools = info(BOOLEAN)
+ return bools
+
-def prettyprint(f,trim):
+def prettyprint(f, trim):
return " ".join(f[:-len(trim)].split("_"))
+
def markup(f):
return f
@@ -604,104 +667,108 @@ DEFAULT_DIRS["/var/run/lock"] = "var_lock_t"
DEFAULT_DIRS["/var/spool"] = "var_spool_t"
DEFAULT_DIRS["/var/www"] = "content_t"
+
def get_description(f, markup=markup):
txt = "Set files with the %s type, if you want to " % markup(f)
if f.endswith("_var_run_t"):
- return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
+ return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
if f.endswith("_pid_t"):
- return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
+ return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
if f.endswith("_var_lib_t"):
- return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t")
+ return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_t"):
- return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t")
+ return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t")
if f.endswith("_var_spool_t"):
- return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
+ return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_spool_t"):
- return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
+ return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
if f.endswith("_cache_t") or f.endswith("_var_cache_t"):
- return txt + "store the files under the /var/cache directory."
+ return txt + "store the files under the /var/cache directory."
if f.endswith("_keytab_t"):
- return txt + "treat the files as kerberos keytab files."
+ return txt + "treat the files as kerberos keytab files."
if f.endswith("_lock_t"):
- return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t")
+ return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f, "_lock_t")
if f.endswith("_log_t"):
- return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t")
+ return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f, "_log_t")
if f.endswith("_config_t"):
- return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t")
+ return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_config_t")
if f.endswith("_conf_t"):
- return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t")
+ return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_conf_t")
if f.endswith("_exec_t"):
- return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
+ return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
if f.endswith("_cgi_content_t"):
- return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
+ return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
if f.endswith("_rw_content_t"):
- return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t")
+ return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_content_t")
if f.endswith("_rw_t"):
- return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_t")
+ return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_t")
if f.endswith("_write_t"):
- return txt + "treat the files as %s read/write content." % prettyprint(f,"_write_t")
+ return txt + "treat the files as %s read/write content." % prettyprint(f, "_write_t")
if f.endswith("_db_t"):
- return txt + "treat the files as %s database content." % prettyprint(f,"_db_t")
+ return txt + "treat the files as %s database content." % prettyprint(f, "_db_t")
if f.endswith("_ra_content_t"):
- return txt + "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t")
+ return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_conten_t")
if f.endswith("_cert_t"):
- return txt + "treat the files as %s certificate data." % prettyprint(f,"_cert_t")
+ return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t")
if f.endswith("_key_t"):
- return txt + "treat the files as %s key data." % prettyprint(f,"_key_t")
+ return txt + "treat the files as %s key data." % prettyprint(f, "_key_t")
if f.endswith("_secret_t"):
- return txt + "treat the files as %s secret data." % prettyprint(f,"_key_t")
+ return txt + "treat the files as %s secret data." % prettyprint(f, "_key_t")
if f.endswith("_ra_t"):
- return txt + "treat the files as %s read/append content." % prettyprint(f,"_ra_t")
+ return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_t")
if f.endswith("_ro_t"):
- return txt + "treat the files as %s read/only content." % prettyprint(f,"_ro_t")
+ return txt + "treat the files as %s read/only content." % prettyprint(f, "_ro_t")
if f.endswith("_modules_t"):
- return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t")
+ return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t")
if f.endswith("_content_t"):
- return txt + "treat the files as %s content." % prettyprint(f, "_content_t")
+ return txt + "treat the files as %s content." % prettyprint(f, "_content_t")
if f.endswith("_state_t"):
- return txt + "treat the files as %s state data." % prettyprint(f, "_state_t")
+ return txt + "treat the files as %s state data." % prettyprint(f, "_state_t")
if f.endswith("_files_t"):
- return txt + "treat the files as %s content." % prettyprint(f, "_files_t")
+ return txt + "treat the files as %s content." % prettyprint(f, "_files_t")
if f.endswith("_file_t"):
- return txt + "treat the files as %s content." % prettyprint(f, "_file_t")
+ return txt + "treat the files as %s content." % prettyprint(f, "_file_t")
if f.endswith("_data_t"):
- return txt + "treat the files as %s content." % prettyprint(f, "_data_t")
+ return txt + "treat the files as %s content." % prettyprint(f, "_data_t")
if f.endswith("_file_t"):
- return txt + "treat the data as %s content." % prettyprint(f, "_file_t")
+ return txt + "treat the data as %s content." % prettyprint(f, "_file_t")
if f.endswith("_tmp_t"):
- return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
+ return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
if f.endswith("_etc_t"):
- return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
+ return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
if f.endswith("_home_t"):
- return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t")
+ return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t")
if f.endswith("_tmpfs_t"):
- return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
+ return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
if f.endswith("_unit_file_t"):
- return txt + "treat files as a systemd unit file."
+ return txt + "treat files as a systemd unit file."
if f.endswith("_htaccess_t"):
- return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
+ return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
- return txt + "treat the files as %s data." % prettyprint(f,"_t")
+ return txt + "treat the files as %s data." % prettyprint(f, "_t")
all_attributes = None
+
+
def get_all_attributes():
- global all_attributes
- if not all_attributes:
- all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
- return all_attributes
+ global all_attributes
+ if not all_attributes:
+ all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
+ return all_attributes
+
def policy(policy_file):
global all_domains
@@ -734,12 +801,14 @@ except ValueError, e:
if selinux.is_selinux_enabled() == 1:
raise e
+
def _dict_has_perms(dict, perms):
for perm in perms:
if perm not in dict[PERMS]:
return False
return True
+
def gen_short_name(setype):
all_domains = get_all_domains()
if setype.endswith("_t"):
@@ -747,20 +816,21 @@ def gen_short_name(setype):
else:
domainname = setype
if domainname + "_t" not in all_domains:
- raise ValueError("domain %s_t does not exist" % domainname)
- if domainname[-1]=='d':
+ raise ValueError("domain %s_t does not exist" % domainname)
+ if domainname[-1] == 'd':
short_name = domainname[:-1] + "_"
else:
short_name = domainname + "_"
return (domainname, short_name)
+
def get_bools(setype):
bools = []
domainbools = []
domainname, short_name = gen_short_name(setype)
- for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW],{'source' : setype}))):
+ for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW], {'source': setype}))):
for b in i:
- if not isinstance(b,tuple):
+ if not isinstance(b, tuple):
continue
try:
enabled = selinux.security_get_boolean_active(b[0])
@@ -771,10 +841,12 @@ def get_bools(setype):
domainbools.append((b[0], enabled))
else:
if (b[0], enabled) not in bools and (b[0], not enabled) not in bools:
- bools.append((b[0],enabled))
+ bools.append((b[0], enabled))
return (domainbools, bools)
booleans = None
+
+
def get_all_booleans():
global booleans
if not booleans:
@@ -783,6 +855,8 @@ def get_all_booleans():
booleans_dict = None
import gzip
+
+
def policy_xml(path="/usr/share/selinux/devel/policy.xml"):
try:
fd = gzip.open(path)
@@ -794,36 +868,38 @@ def policy_xml(path="/usr/share/selinux/devel/policy.xml"):
fd.close()
return buf
+
def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"):
- global booleans_dict
- if booleans_dict:
- return booleans_dict
- import xml.etree.ElementTree
- import re
- booleans_dict = {}
- try:
- tree = xml.etree.ElementTree.fromstring(policy_xml(path))
- for l in tree.findall("layer"):
- for m in l.findall("module"):
- for b in m.findall("tunable"):
- desc = b.find("desc").find("p").text.strip("\n")
- desc = re.sub("\n", " ", desc)
- booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
- for b in m.findall("bool"):
- desc = b.find("desc").find("p").text.strip("\n")
- desc = re.sub("\n", " ", desc)
- booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
- for i in tree.findall("bool"):
- desc = i.find("desc").find("p").text.strip("\n")
- desc = re.sub("\n", " ", desc)
- booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
- for i in tree.findall("tunable"):
- desc = i.find("desc").find("p").text.strip("\n")
- desc = re.sub("\n", " ", desc)
- booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
- except IOError, e:
- pass
+ global booleans_dict
+ if booleans_dict:
return booleans_dict
+ import xml.etree.ElementTree
+ import re
+ booleans_dict = {}
+ try:
+ tree = xml.etree.ElementTree.fromstring(policy_xml(path))
+ for l in tree.findall("layer"):
+ for m in l.findall("module"):
+ for b in m.findall("tunable"):
+ desc = b.find("desc").find("p").text.strip("\n")
+ desc = re.sub("\n", " ", desc)
+ booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
+ for b in m.findall("bool"):
+ desc = b.find("desc").find("p").text.strip("\n")
+ desc = re.sub("\n", " ", desc)
+ booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
+ for i in tree.findall("bool"):
+ desc = i.find("desc").find("p").text.strip("\n")
+ desc = re.sub("\n", " ", desc)
+ booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
+ for i in tree.findall("tunable"):
+ desc = i.find("desc").find("p").text.strip("\n")
+ desc = re.sub("\n", " ", desc)
+ booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
+ except IOError, e:
+ pass
+ return booleans_dict
+
def boolean_category(boolean):
booleans_dict = gen_bool_dict()
@@ -832,13 +908,15 @@ def boolean_category(boolean):
else:
return _("unknown")
+
def boolean_desc(boolean):
- booleans_dict = gen_bool_dict()
- if boolean in booleans_dict:
- return _(booleans_dict[boolean][2])
- else:
- desc = boolean.split("_")
- return "Allow %s to %s" % (desc[0], " ".join(desc[1:]))
+ booleans_dict = gen_bool_dict()
+ if boolean in booleans_dict:
+ return _(booleans_dict[boolean][2])
+ else:
+ desc = boolean.split("_")
+ return "Allow %s to %s" % (desc[0], " ".join(desc[1:]))
+
def get_os_version():
os_version = ""
@@ -852,14 +930,15 @@ def get_os_version():
os_version = ""
if os_version[0:2] == "fc":
- os_version = "Fedora"+os_version[2:]
+ os_version = "Fedora" + os_version[2:]
elif os_version[0:2] == "el":
- os_version = "RHEL"+os_version[2:]
+ os_version = "RHEL" + os_version[2:]
else:
os_version = ""
return os_version
+
def reinit():
global all_attributes
global all_domains
@@ -888,7 +967,7 @@ def reinit():
bools = None
fcdict = None
file_types = None
- local_files=None
+ local_files = None
methods = None
methods = None
portrecs = None
diff --git a/policycoreutils/sepolicy/sepolicy/booleans.py b/policycoreutils/sepolicy/sepolicy/booleans.py
index 9003652b..56bef264 100644
--- a/policycoreutils/sepolicy/sepolicy/booleans.py
+++ b/policycoreutils/sepolicy/sepolicy/booleans.py
@@ -1,5 +1,5 @@
#! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat
+# Copyright (C) 2012 Red Hat
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,22 +16,25 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
-import sepolicy, sys
-search=sepolicy.search
-info=sepolicy.info
+#
+import sepolicy
+import sys
+search = sepolicy.search
+info = sepolicy.info
+
def expand_attribute(attribute):
try:
return info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
except RuntimeError:
- return [ attribute ]
+ return [attribute]
+
def get_types(src, tclass, perm):
- allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
+ allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
if not allows:
raise TypeError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
index 9b9a09ad..9939c23a 100755
--- a/policycoreutils/sepolicy/sepolicy/communicate.py
+++ b/policycoreutils/sepolicy/sepolicy/communicate.py
@@ -1,5 +1,5 @@
#! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat
+# Copyright (C) 2012 Red Hat
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,13 +16,16 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
-import sepolicy, sys
-search=sepolicy.search
-info=sepolicy.info
+#
+import sepolicy
+import sys
+search = sepolicy.search
+info = sepolicy.info
+
+
def usage(parser, msg):
parser.print_help()
@@ -35,10 +38,11 @@ def expand_attribute(attribute):
try:
return info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
except RuntimeError:
- return [ attribute ]
+ return [attribute]
+
def get_types(src, tclass, perm):
- allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
+ allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
if not allows:
raise ValueError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
@@ -46,4 +50,3 @@ def get_types(src, tclass, perm):
for l in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):
tlist = tlist + expand_attribute(l)
return tlist
-
diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
index 4858582d..a92783ac 100644
--- a/policycoreutils/sepolicy/sepolicy/generate.py
+++ b/policycoreutils/sepolicy/sepolicy/generate.py
@@ -21,7 +21,9 @@
# 02111-1307 USA
#
#
-import os, sys, stat
+import os
+import sys
+import stat
import re
import sepolicy
from sepolicy import get_all_types, get_all_attributes, get_all_roles
@@ -49,7 +51,7 @@ import sepolgen.defaults as defaults
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -58,20 +60,22 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
def get_rpm_nvr_from_header(hdr):
'Given an RPM header return the package NVR as a string'
- name = hdr['name']
+ name = hdr['name']
version = hdr['version']
release = hdr['release']
- release_version = version+"-"+release.split(".")[0]
+ release_version = version + "-" + release.split(".")[0]
os_version = release.split(".")[1]
- return [name,release_version,os_version]
+ return [name, release_version, os_version]
+
def get_rpm_nvr_list(package):
try:
@@ -88,6 +92,7 @@ def get_rpm_nvr_list(package):
return nvr
+
def get_all_ports():
dict = {}
for p in sepolicy.info(sepolicy.PORT):
@@ -95,9 +100,10 @@ def get_all_ports():
p['type'] == "port_t" or \
p['type'] == "hi_reserved_port_t":
continue
- dict[(p['low'], p['high'], p['protocol'])]=(p['type'], p['range'])
+ dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p['range'])
return dict
+
def get_all_users():
users = map(lambda x: x['name'], sepolicy.info(sepolicy.USER))
users.remove("system_u")
@@ -126,7 +132,7 @@ AUSER = 10
RUSER = 11
NEWTYPE = 12
-poltype={}
+poltype = {}
poltype[DAEMON] = _("Standard Init Daemon")
poltype[DBUS] = _("DBUS System Daemon")
poltype[INETD] = _("Internet Services Daemon")
@@ -141,6 +147,7 @@ poltype[AUSER] = _("Administrator Login User Role")
poltype[RUSER] = _("Confined Root Administrator Role")
poltype[NEWTYPE] = _("Module information for a new type")
+
def get_poltype_desc():
keys = poltype.keys()
keys.sort()
@@ -148,1143 +155,1126 @@ def get_poltype_desc():
for k in keys:
msg += "%2s: %s\n" % (k, poltype[k])
return msg
-
-APPLICATIONS = [ DAEMON, DBUS, INETD, USER, CGI ]
-USERS = [ XUSER, TUSER, LUSER, AUSER, RUSER]
+
+APPLICATIONS = [DAEMON, DBUS, INETD, USER, CGI]
+USERS = [XUSER, TUSER, LUSER, AUSER, RUSER]
+
def verify_ports(ports):
if ports == "":
return []
- max_port=2**16
+ max_port = 2 ** 16
try:
temp = []
for a in ports.split(","):
- r = a.split("-")
+ r = a.split("-")
if len(r) > 2:
- raise ValueError
+ raise ValueError
if len(r) == 1:
- begin = int (r[0])
- end = int (r[0])
+ begin = int(r[0])
+ end = int(r[0])
else:
- begin = int (r[0])
- end = int (r[1])
+ begin = int(r[0])
+ end = int(r[1])
if begin > end:
- raise ValueError
+ raise ValueError
for p in range(begin, end + 1):
if p < 1 or p > max_port:
- raise ValueError
+ raise ValueError
temp.append(p)
return temp
except ValueError:
- raise ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port ))
+ raise ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port))
+
class policy:
- def __init__(self, name, type):
- self.rpms = []
- self.ports = []
- self.all_roles = get_all_roles()
- self.types = []
-
- if type not in poltype:
- raise ValueError(_("You must enter a valid policy type"))
-
- if not name:
- raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
- try:
- self.ports = get_all_ports()
- except ValueError, e:
- print "Can not get port types, must be root for this information"
- except RuntimeError, e:
- print "Can not get port types", e
-
- self.symbols = {}
- self.symbols["openlog"] = "set_use_kerberos(True)"
- self.symbols["openlog"] = "set_use_kerb_rcache(True)"
- self.symbols["openlog"] = "set_use_syslog(True)"
- self.symbols["gethostby"] = "set_use_resolve(True)"
- self.symbols["getaddrinfo"] = "set_use_resolve(True)"
- self.symbols["getnameinfo"] = "set_use_resolve(True)"
- self.symbols["krb"] = "set_use_kerberos(True)"
- self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)"
- self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)"
- self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)"
- self.symbols["__syslog_chk"] = "set_use_syslog(True)"
- self.symbols["getpwnam"] = "set_use_uid(True)"
- self.symbols["getpwuid"] = "set_use_uid(True)"
- self.symbols["dbus_"] = "set_use_dbus(True)"
- self.symbols["pam_"] = "set_use_pam(True)"
- self.symbols["pam_"] = "set_use_audit(True)"
- self.symbols["fork"] = "add_process('fork')"
- self.symbols["transition"] = "add_process('transition')"
- self.symbols["sigchld"] = "add_process('sigchld')"
- self.symbols["sigkill"] = "add_process('sigkill')"
- self.symbols["sigstop"] = "add_process('sigstop')"
- self.symbols["signull"] = "add_process('signull')"
- self.symbols["ptrace"] = "add_process('ptrace')"
- self.symbols["getsched"] = "add_process('getsched')"
- self.symbols["setsched"] = "add_process('setsched')"
- self.symbols["getsession"] = "add_process('getsession')"
- self.symbols["getpgid"] = "add_process('getpgid')"
- self.symbols["setpgid"] = "add_process('setpgid')"
- self.symbols["getcap"] = "add_process('getcap')"
- self.symbols["setcap"] = "add_process('setcap')"
- self.symbols["share"] = "add_process('share')"
- self.symbols["getattr"] = "add_process('getattr')"
- self.symbols["setexec"] = "add_process('setexec')"
- self.symbols["setfscreate"] = "add_process('setfscreate')"
- self.symbols["noatsecure"] = "add_process('noatsecure')"
- self.symbols["siginh"] = "add_process('siginh')"
- self.symbols["kill"] = "add_process('signal_perms')"
- self.symbols["setrlimit"] = "add_process('setrlimit')"
- self.symbols["rlimitinh"] = "add_process('rlimitinh')"
- self.symbols["dyntransition"] = "add_process('dyntransition')"
- self.symbols["setcurrent"] = "add_process('setcurrent')"
- self.symbols["execmem"] = "add_process('execmem')"
- self.symbols["execstack"] = "add_process('execstack')"
- self.symbols["execheap"] = "add_process('execheap')"
- self.symbols["setkeycreate"] = "add_process('setkeycreate')"
- self.symbols["setsockcreate"] = "add_process('setsockcreate')"
-
- self.symbols["chown"] = "add_capability('chown')"
- self.symbols["dac_override"] = "add_capability('dac_override')"
- self.symbols["dac_read_search"] = "add_capability('dac_read_search')"
- self.symbols["fowner"] = "add_capability('fowner')"
- self.symbols["fsetid"] = "add_capability('fsetid')"
- self.symbols["setgid"] = "add_capability('setgid')"
- self.symbols["setegid"] = "add_capability('setgid')"
- self.symbols["setresgid"] = "add_capability('setgid')"
- self.symbols["setregid"] = "add_capability('setgid')"
- self.symbols["setresuid"] = "add_capability('setuid')"
- self.symbols["setuid"] = "add_capability('setuid')"
- self.symbols["seteuid"] = "add_capability('setuid')"
- self.symbols["setreuid"] = "add_capability('setuid')"
- self.symbols["setresuid"] = "add_capability('setuid')"
- self.symbols["setpcap"] = "add_capability('setpcap')"
- self.symbols["linux_immutable"] = "add_capability('linux_immutable')"
- self.symbols["net_bind_service"] = "add_capability('net_bind_service')"
- self.symbols["net_broadcast"] = "add_capability('net_broadcast')"
- self.symbols["net_admin"] = "add_capability('net_admin')"
- self.symbols["net_raw"] = "add_capability('net_raw')"
- self.symbols["ipc_lock"] = "add_capability('ipc_lock')"
- self.symbols["ipc_owner"] = "add_capability('ipc_owner')"
- self.symbols["sys_module"] = "add_capability('sys_module')"
- self.symbols["sys_rawio"] = "add_capability('sys_rawio')"
- self.symbols["chroot"] = "add_capability('sys_chroot')"
- self.symbols["sys_chroot"] = "add_capability('sys_chroot')"
- self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')"
- self.symbols["sys_pacct"] = "add_capability('sys_pacct')"
- self.symbols["mount"] = "add_capability('sys_admin')"
- self.symbols["unshare"] = "add_capability('sys_admin')"
- self.symbols["sys_admin"] = "add_capability('sys_admin')"
- self.symbols["sys_boot"] = "add_capability('sys_boot')"
- self.symbols["sys_nice"] = "add_capability('sys_nice')"
- self.symbols["sys_resource"] = "add_capability('sys_resource')"
- self.symbols["sys_time"] = "add_capability('sys_time')"
- self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')"
- self.symbols["mknod"] = "add_capability('mknod')"
- self.symbols["lease"] = "add_capability('lease')"
- self.symbols["audit_write"] = "add_capability('audit_write')"
- self.symbols["audit_control"] = "add_capability('audit_control')"
- self.symbols["setfcap"] = "add_capability('setfcap')"
-
- self.DEFAULT_DIRS = {}
- self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw];
- self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp];
- self.DEFAULT_DIRS["rw"] = ["rw", [], rw];
- self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file];
- self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file];
- self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file];
- self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache];
- self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib];
- self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log];
- self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run];
- self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool];
-
- self.DEFAULT_EXT = {}
- self.DEFAULT_EXT["_tmp_t"] = tmp;
- self.DEFAULT_EXT["_unit_file_t"] = unit_file;
- self.DEFAULT_EXT["_var_cache_t"] = var_cache;
- self.DEFAULT_EXT["_var_lib_t"] = var_lib;
- self.DEFAULT_EXT["_var_log_t"] = var_log;
- self.DEFAULT_EXT["_var_run_t"] = var_run;
- self.DEFAULT_EXT["_var_spool_t"] = var_spool;
- self.DEFAULT_EXT["_port_t"] = network;
-
- self.DEFAULT_KEYS=["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system" ]
-
- self.DEFAULT_TYPES = (\
-( self.generate_daemon_types, self.generate_daemon_rules), \
-( self.generate_dbusd_types, self.generate_dbusd_rules), \
-( self.generate_inetd_types, self.generate_inetd_rules), \
-( self.generate_cgi_types, self.generate_cgi_rules), \
-( self.generate_sandbox_types, self.generate_sandbox_rules), \
-( self.generate_userapp_types, self.generate_userapp_rules), \
-( self.generate_existing_user_types, self.generate_existing_user_rules), \
-( self.generate_min_login_user_types, self.generate_login_user_rules), \
-( self.generate_x_login_user_types, self.generate_x_login_user_rules), \
-( self.generate_login_user_types, self.generate_login_user_rules), \
-( self.generate_admin_user_types, self.generate_login_user_rules), \
-( self.generate_root_user_types, self.generate_root_user_rules), \
-( self.generate_new_types, self.generate_new_rules))
- if not re.match(r"^[a-zA-Z0-9-_]+$", name):
- raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\""))
-
- if type == CGI:
- self.name = "httpd_%s_script" % name
- else:
- self.name = name
-
- self.file_name = name
-
- self.capabilities = []
- self.processes = []
- self.type = type
- self.initscript = ""
- self.program = None
- self.in_tcp = [False, False, False, []]
- self.in_udp = [False, False, False, []]
- self.out_tcp = [False, False, False, []]
- self.out_udp = [False, False, False, []]
- self.use_resolve = False
- self.use_tmp = False
- self.use_uid = False
- self.use_syslog = False
- self.use_kerberos = False
- self.manage_krb5_rcache = False
- self.use_pam = False
- self.use_dbus = False
- self.use_audit = False
- self.use_etc = self.type not in [ EUSER, NEWTYPE ]
- self.use_localization = self.type not in [ EUSER, NEWTYPE ]
- self.use_fd = self.type not in [ EUSER, NEWTYPE ]
- self.use_terminal = False
- self.use_mail = False
- self.booleans = {}
- self.files = {}
- self.dirs = {}
- self.found_tcp_ports=[]
- self.found_udp_ports=[]
- self.need_tcp_type=False
- self.need_udp_type=False
- self.admin_domains = []
- self.existing_domains = []
- self.transition_domains = []
- self.transition_users = []
- self.roles = []
-
- def __isnetset(self, l):
- return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0
-
- def set_admin_domains(self, admin_domains):
- self.admin_domains = admin_domains
-
- def set_existing_domains(self, existing_domains):
- self.existing_domains = existing_domains
-
- def set_admin_roles(self, roles):
- self.roles = roles
-
- def set_transition_domains(self, transition_domains):
- self.transition_domains = transition_domains
-
- def set_transition_users(self, transition_users):
- self.transition_users = transition_users
-
- def use_in_udp(self):
- return self.__isnetset(self.in_udp)
-
- def use_out_udp(self):
- return self.__isnetset(self.out_udp)
-
- def use_udp(self):
- return self.use_in_udp() or self.use_out_udp()
-
- def use_in_tcp(self):
- return self.__isnetset(self.in_tcp)
-
- def use_out_tcp(self):
- return self.__isnetset(self.out_tcp)
-
- def use_tcp(self):
- return self.use_in_tcp() or self.use_out_tcp()
-
- def use_network(self):
- return self.use_tcp() or self.use_udp()
-
- def find_port(self, port, protocol="tcp"):
- for begin,end,p in self.ports.keys():
- if port >= begin and port <= end and protocol == p:
- return self.ports[begin, end, protocol]
- return None
-
- def set_program(self, program):
- if self.type not in APPLICATIONS:
- raise ValueError(_("User Role types can not be assigned executables."))
+ def __init__(self, name, type):
+ self.rpms = []
+ self.ports = []
+ self.all_roles = get_all_roles()
+ self.types = []
+
+ if type not in poltype:
+ raise ValueError(_("You must enter a valid policy type"))
+
+ if not name:
+ raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
+ try:
+ self.ports = get_all_ports()
+ except ValueError, e:
+ print "Can not get port types, must be root for this information"
+ except RuntimeError, e:
+ print "Can not get port types", e
+
+ self.symbols = {}
+ self.symbols["openlog"] = "set_use_kerberos(True)"
+ self.symbols["openlog"] = "set_use_kerb_rcache(True)"
+ self.symbols["openlog"] = "set_use_syslog(True)"
+ self.symbols["gethostby"] = "set_use_resolve(True)"
+ self.symbols["getaddrinfo"] = "set_use_resolve(True)"
+ self.symbols["getnameinfo"] = "set_use_resolve(True)"
+ self.symbols["krb"] = "set_use_kerberos(True)"
+ self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)"
+ self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)"
+ self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)"
+ self.symbols["__syslog_chk"] = "set_use_syslog(True)"
+ self.symbols["getpwnam"] = "set_use_uid(True)"
+ self.symbols["getpwuid"] = "set_use_uid(True)"
+ self.symbols["dbus_"] = "set_use_dbus(True)"
+ self.symbols["pam_"] = "set_use_pam(True)"
+ self.symbols["pam_"] = "set_use_audit(True)"
+ self.symbols["fork"] = "add_process('fork')"
+ self.symbols["transition"] = "add_process('transition')"
+ self.symbols["sigchld"] = "add_process('sigchld')"
+ self.symbols["sigkill"] = "add_process('sigkill')"
+ self.symbols["sigstop"] = "add_process('sigstop')"
+ self.symbols["signull"] = "add_process('signull')"
+ self.symbols["ptrace"] = "add_process('ptrace')"
+ self.symbols["getsched"] = "add_process('getsched')"
+ self.symbols["setsched"] = "add_process('setsched')"
+ self.symbols["getsession"] = "add_process('getsession')"
+ self.symbols["getpgid"] = "add_process('getpgid')"
+ self.symbols["setpgid"] = "add_process('setpgid')"
+ self.symbols["getcap"] = "add_process('getcap')"
+ self.symbols["setcap"] = "add_process('setcap')"
+ self.symbols["share"] = "add_process('share')"
+ self.symbols["getattr"] = "add_process('getattr')"
+ self.symbols["setexec"] = "add_process('setexec')"
+ self.symbols["setfscreate"] = "add_process('setfscreate')"
+ self.symbols["noatsecure"] = "add_process('noatsecure')"
+ self.symbols["siginh"] = "add_process('siginh')"
+ self.symbols["kill"] = "add_process('signal_perms')"
+ self.symbols["setrlimit"] = "add_process('setrlimit')"
+ self.symbols["rlimitinh"] = "add_process('rlimitinh')"
+ self.symbols["dyntransition"] = "add_process('dyntransition')"
+ self.symbols["setcurrent"] = "add_process('setcurrent')"
+ self.symbols["execmem"] = "add_process('execmem')"
+ self.symbols["execstack"] = "add_process('execstack')"
+ self.symbols["execheap"] = "add_process('execheap')"
+ self.symbols["setkeycreate"] = "add_process('setkeycreate')"
+ self.symbols["setsockcreate"] = "add_process('setsockcreate')"
+
+ self.symbols["chown"] = "add_capability('chown')"
+ self.symbols["dac_override"] = "add_capability('dac_override')"
+ self.symbols["dac_read_search"] = "add_capability('dac_read_search')"
+ self.symbols["fowner"] = "add_capability('fowner')"
+ self.symbols["fsetid"] = "add_capability('fsetid')"
+ self.symbols["setgid"] = "add_capability('setgid')"
+ self.symbols["setegid"] = "add_capability('setgid')"
+ self.symbols["setresgid"] = "add_capability('setgid')"
+ self.symbols["setregid"] = "add_capability('setgid')"
+ self.symbols["setresuid"] = "add_capability('setuid')"
+ self.symbols["setuid"] = "add_capability('setuid')"
+ self.symbols["seteuid"] = "add_capability('setuid')"
+ self.symbols["setreuid"] = "add_capability('setuid')"
+ self.symbols["setresuid"] = "add_capability('setuid')"
+ self.symbols["setpcap"] = "add_capability('setpcap')"
+ self.symbols["linux_immutable"] = "add_capability('linux_immutable')"
+ self.symbols["net_bind_service"] = "add_capability('net_bind_service')"
+ self.symbols["net_broadcast"] = "add_capability('net_broadcast')"
+ self.symbols["net_admin"] = "add_capability('net_admin')"
+ self.symbols["net_raw"] = "add_capability('net_raw')"
+ self.symbols["ipc_lock"] = "add_capability('ipc_lock')"
+ self.symbols["ipc_owner"] = "add_capability('ipc_owner')"
+ self.symbols["sys_module"] = "add_capability('sys_module')"
+ self.symbols["sys_rawio"] = "add_capability('sys_rawio')"
+ self.symbols["chroot"] = "add_capability('sys_chroot')"
+ self.symbols["sys_chroot"] = "add_capability('sys_chroot')"
+ self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')"
+ self.symbols["sys_pacct"] = "add_capability('sys_pacct')"
+ self.symbols["mount"] = "add_capability('sys_admin')"
+ self.symbols["unshare"] = "add_capability('sys_admin')"
+ self.symbols["sys_admin"] = "add_capability('sys_admin')"
+ self.symbols["sys_boot"] = "add_capability('sys_boot')"
+ self.symbols["sys_nice"] = "add_capability('sys_nice')"
+ self.symbols["sys_resource"] = "add_capability('sys_resource')"
+ self.symbols["sys_time"] = "add_capability('sys_time')"
+ self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')"
+ self.symbols["mknod"] = "add_capability('mknod')"
+ self.symbols["lease"] = "add_capability('lease')"
+ self.symbols["audit_write"] = "add_capability('audit_write')"
+ self.symbols["audit_control"] = "add_capability('audit_control')"
+ self.symbols["setfcap"] = "add_capability('setfcap')"
+
+ self.DEFAULT_DIRS = {}
+ self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw]
+ self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp]
+ self.DEFAULT_DIRS["rw"] = ["rw", [], rw]
+ self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file]
+ self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file]
+ self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file]
+ self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache]
+ self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib]
+ self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log]
+ self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run]
+ self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool]
+
+ self.DEFAULT_EXT = {}
+ self.DEFAULT_EXT["_tmp_t"] = tmp
+ self.DEFAULT_EXT["_unit_file_t"] = unit_file
+ self.DEFAULT_EXT["_var_cache_t"] = var_cache
+ self.DEFAULT_EXT["_var_lib_t"] = var_lib
+ self.DEFAULT_EXT["_var_log_t"] = var_log
+ self.DEFAULT_EXT["_var_run_t"] = var_run
+ self.DEFAULT_EXT["_var_spool_t"] = var_spool
+ self.DEFAULT_EXT["_port_t"] = network
+
+ self.DEFAULT_KEYS = ["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system"]
+
+ self.DEFAULT_TYPES = (
+ (self.generate_daemon_types, self.generate_daemon_rules),
+ (self.generate_dbusd_types, self.generate_dbusd_rules),
+ (self.generate_inetd_types, self.generate_inetd_rules),
+ (self.generate_cgi_types, self.generate_cgi_rules),
+ (self.generate_sandbox_types, self.generate_sandbox_rules),
+ (self.generate_userapp_types, self.generate_userapp_rules),
+ (self.generate_existing_user_types, self.generate_existing_user_rules),
+ (self.generate_min_login_user_types, self.generate_login_user_rules),
+ (self.generate_x_login_user_types, self.generate_x_login_user_rules),
+ (self.generate_login_user_types, self.generate_login_user_rules),
+ (self.generate_admin_user_types, self.generate_login_user_rules),
+ (self.generate_root_user_types, self.generate_root_user_rules),
+ (self.generate_new_types, self.generate_new_rules))
+ if not re.match(r"^[a-zA-Z0-9-_]+$", name):
+ raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\""))
+
+ if type == CGI:
+ self.name = "httpd_%s_script" % name
+ else:
+ self.name = name
+
+ self.file_name = name
+
+ self.capabilities = []
+ self.processes = []
+ self.type = type
+ self.initscript = ""
+ self.program = None
+ self.in_tcp = [False, False, False, []]
+ self.in_udp = [False, False, False, []]
+ self.out_tcp = [False, False, False, []]
+ self.out_udp = [False, False, False, []]
+ self.use_resolve = False
+ self.use_tmp = False
+ self.use_uid = False
+ self.use_syslog = False
+ self.use_kerberos = False
+ self.manage_krb5_rcache = False
+ self.use_pam = False
+ self.use_dbus = False
+ self.use_audit = False
+ self.use_etc = self.type not in [EUSER, NEWTYPE]
+ self.use_localization = self.type not in [EUSER, NEWTYPE]
+ self.use_fd = self.type not in [EUSER, NEWTYPE]
+ self.use_terminal = False
+ self.use_mail = False
+ self.booleans = {}
+ self.files = {}
+ self.dirs = {}
+ self.found_tcp_ports = []
+ self.found_udp_ports = []
+ self.need_tcp_type = False
+ self.need_udp_type = False
+ self.admin_domains = []
+ self.existing_domains = []
+ self.transition_domains = []
+ self.transition_users = []
+ self.roles = []
+
+ def __isnetset(self, l):
+ return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0
+
+ def set_admin_domains(self, admin_domains):
+ self.admin_domains = admin_domains
+
+ def set_existing_domains(self, existing_domains):
+ self.existing_domains = existing_domains
+
+ def set_admin_roles(self, roles):
+ self.roles = roles
+
+ def set_transition_domains(self, transition_domains):
+ self.transition_domains = transition_domains
+
+ def set_transition_users(self, transition_users):
+ self.transition_users = transition_users
+
+ def use_in_udp(self):
+ return self.__isnetset(self.in_udp)
+
+ def use_out_udp(self):
+ return self.__isnetset(self.out_udp)
+
+ def use_udp(self):
+ return self.use_in_udp() or self.use_out_udp()
+
+ def use_in_tcp(self):
+ return self.__isnetset(self.in_tcp)
+
+ def use_out_tcp(self):
+ return self.__isnetset(self.out_tcp)
+
+ def use_tcp(self):
+ return self.use_in_tcp() or self.use_out_tcp()
+
+ def use_network(self):
+ return self.use_tcp() or self.use_udp()
+
+ def find_port(self, port, protocol="tcp"):
+ for begin, end, p in self.ports.keys():
+ if port >= begin and port <= end and protocol == p:
+ return self.ports[begin, end, protocol]
+ return None
+
+ def set_program(self, program):
+ if self.type not in APPLICATIONS:
+ raise ValueError(_("User Role types can not be assigned executables."))
+
+ self.program = program
- self.program = program
+ def set_init_script(self, initscript):
+ if self.type != DAEMON:
+ raise ValueError(_("Only Daemon apps can use an init script.."))
- def set_init_script(self, initscript):
- if self.type != DAEMON:
- raise ValueError(_("Only Daemon apps can use an init script.."))
+ self.initscript = initscript
- self.initscript = initscript
+ def set_in_tcp(self, all, reserved, unreserved, ports):
+ self.in_tcp = [all, reserved, unreserved, verify_ports(ports)]
- def set_in_tcp(self, all, reserved, unreserved, ports):
- self.in_tcp = [ all, reserved, unreserved, verify_ports(ports)]
+ def set_in_udp(self, all, reserved, unreserved, ports):
+ self.in_udp = [all, reserved, unreserved, verify_ports(ports)]
- def set_in_udp(self, all, reserved, unreserved, ports):
- self.in_udp = [ all, reserved, unreserved, verify_ports(ports)]
+ def set_out_tcp(self, all, ports):
+ self.out_tcp = [all, False, False, verify_ports(ports)]
- def set_out_tcp(self, all, ports):
- self.out_tcp = [ all , False, False, verify_ports(ports) ]
+ def set_out_udp(self, all, ports):
+ self.out_udp = [all, False, False, verify_ports(ports)]
- def set_out_udp(self, all, ports):
- self.out_udp = [ all , False, False, verify_ports(ports) ]
+ def set_use_resolve(self, val):
+ if val != True and val != False:
+ raise ValueError(_("use_resolve must be a boolean value "))
- def set_use_resolve(self, val):
- if val != True and val != False:
- raise ValueError(_("use_resolve must be a boolean value "))
+ self.use_resolve = val
- self.use_resolve = val
+ def set_use_syslog(self, val):
+ if val != True and val != False:
+ raise ValueError(_("use_syslog must be a boolean value "))
- def set_use_syslog(self, val):
- if val != True and val != False:
- raise ValueError(_("use_syslog must be a boolean value "))
+ self.use_syslog = val
- self.use_syslog = val
+ def set_use_kerberos(self, val):
+ if val != True and val != False:
+ raise ValueError(_("use_kerberos must be a boolean value "))
- def set_use_kerberos(self, val):
- if val != True and val != False:
- raise ValueError(_("use_kerberos must be a boolean value "))
+ self.use_kerberos = val
- self.use_kerberos = val
+ def set_manage_krb5_rcache(self, val):
+ if val != True and val != False:
+ raise ValueError(_("manage_krb5_rcache must be a boolean value "))
- def set_manage_krb5_rcache(self, val):
- if val != True and val != False:
- raise ValueError(_("manage_krb5_rcache must be a boolean value "))
+ self.manage_krb5_rcache = val
- self.manage_krb5_rcache = val
+ def set_use_pam(self, val):
+ self.use_pam = val == True
- def set_use_pam(self, val):
- self.use_pam = val == True
+ def set_use_dbus(self, val):
+ self.use_dbus = val == True
- def set_use_dbus(self, val):
- self.use_dbus = val == True
+ def set_use_audit(self, val):
+ self.use_audit = val == True
- def set_use_audit(self, val):
- self.use_audit = val == True
+ def set_use_etc(self, val):
+ self.use_etc = val == True
- def set_use_etc(self, val):
- self.use_etc = val == True
+ def set_use_localization(self, val):
+ self.use_localization = val == True
- def set_use_localization(self, val):
- self.use_localization = val == True
+ def set_use_fd(self, val):
+ self.use_fd = val == True
- def set_use_fd(self, val):
- self.use_fd = val == True
+ def set_use_terminal(self, val):
+ self.use_terminal = val == True
- def set_use_terminal(self, val):
- self.use_terminal = val == True
+ def set_use_mail(self, val):
+ self.use_mail = val == True
- def set_use_mail(self, val):
- self.use_mail = val == True
+ def set_use_tmp(self, val):
+ if self.type in USERS:
+ raise ValueError(_("USER Types automatically get a tmp type"))
- def set_use_tmp(self, val):
- if self.type in USERS:
- raise ValueError(_("USER Types automatically get a tmp type"))
+ if val:
+ self.DEFAULT_DIRS["/tmp"][1].append("/tmp")
+ else:
+ self.DEFAULT_DIRS["/tmp"][1] = []
- if val:
- self.DEFAULT_DIRS["/tmp"][1].append("/tmp");
- else:
- self.DEFAULT_DIRS["/tmp"][1]=[]
+ def set_use_uid(self, val):
+ self.use_uid = val == True
- def set_use_uid(self, val):
- self.use_uid = val == True
+ def generate_uid_rules(self):
+ if self.use_uid:
+ return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules)
+ else:
+ return ""
- def generate_uid_rules(self):
- if self.use_uid:
- return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules)
- else:
- return ""
+ def generate_syslog_rules(self):
+ if self.use_syslog:
+ return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules)
+ else:
+ return ""
- def generate_syslog_rules(self):
- if self.use_syslog:
- return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules)
- else:
- return ""
+ def generate_resolve_rules(self):
+ if self.use_resolve:
+ return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules)
+ else:
+ return ""
- def generate_resolve_rules(self):
- if self.use_resolve:
- return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules)
- else:
- return ""
+ def generate_kerberos_rules(self):
+ if self.use_kerberos:
+ return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules)
+ else:
+ return ""
- def generate_kerberos_rules(self):
- if self.use_kerberos:
- return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules)
- else:
- return ""
+ def generate_manage_krb5_rcache_rules(self):
+ if self.manage_krb5_rcache:
+ return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules)
+ else:
+ return ""
- def generate_manage_krb5_rcache_rules(self):
- if self.manage_krb5_rcache:
- return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules)
- else:
- return ""
-
- def generate_pam_rules(self):
- newte =""
- if self.use_pam:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules)
- return newte
-
- def generate_audit_rules(self):
- newte =""
- if self.use_audit:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules)
- return newte
-
- def generate_etc_rules(self):
- newte =""
- if self.use_etc:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules)
- return newte
-
- def generate_fd_rules(self):
- newte =""
- if self.use_fd:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules)
- return newte
-
- def generate_localization_rules(self):
- newte =""
- if self.use_localization:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules)
- return newte
-
- def generate_dbus_rules(self):
- newte =""
- if self.type != DBUS and self.use_dbus:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules)
- return newte
-
- def generate_mail_rules(self):
- newte =""
- if self.use_mail:
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules)
- return newte
-
- def generate_network_action(self, protocol, action, port_name):
- line = ""
- method = "corenet_%s_%s_%s" % (protocol, action, port_name)
- if method in sepolicy.get_methods():
- line = "%s(%s_t)\n" % (method, self.name)
- else:
- line = """
+ def generate_pam_rules(self):
+ newte = ""
+ if self.use_pam:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules)
+ return newte
+
+ def generate_audit_rules(self):
+ newte = ""
+ if self.use_audit:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules)
+ return newte
+
+ def generate_etc_rules(self):
+ newte = ""
+ if self.use_etc:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules)
+ return newte
+
+ def generate_fd_rules(self):
+ newte = ""
+ if self.use_fd:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules)
+ return newte
+
+ def generate_localization_rules(self):
+ newte = ""
+ if self.use_localization:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules)
+ return newte
+
+ def generate_dbus_rules(self):
+ newte = ""
+ if self.type != DBUS and self.use_dbus:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules)
+ return newte
+
+ def generate_mail_rules(self):
+ newte = ""
+ if self.use_mail:
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules)
+ return newte
+
+ def generate_network_action(self, protocol, action, port_name):
+ line = ""
+ method = "corenet_%s_%s_%s" % (protocol, action, port_name)
+ if method in sepolicy.get_methods():
+ line = "%s(%s_t)\n" % (method, self.name)
+ else:
+ line = """
gen_require(`
type %s_t;
')
allow %s_t %s_t:%s_socket name_%s;
""" % (port_name, self.name, port_name, protocol, action)
- return line
+ return line
- def generate_network_types(self):
- for i in self.in_tcp[PORTS]:
- rec = self.find_port(int(i), "tcp")
- if rec == None:
- self.need_tcp_type = True;
- else:
- port_name = rec[0][:-2]
- line = self.generate_network_action("tcp", "bind", port_name)
+ def generate_network_types(self):
+ for i in self.in_tcp[PORTS]:
+ rec = self.find_port(int(i), "tcp")
+ if rec == None:
+ self.need_tcp_type = True
+ else:
+ port_name = rec[0][:-2]
+ line = self.generate_network_action("tcp", "bind", port_name)
# line = "corenet_tcp_bind_%s(%s_t)\n" % (port_name, self.name)
- if line not in self.found_tcp_ports:
- self.found_tcp_ports.append(line)
+ if line not in self.found_tcp_ports:
+ self.found_tcp_ports.append(line)
- for i in self.out_tcp[PORTS]:
- rec = self.find_port(int(i), "tcp")
- if rec == None:
- self.need_tcp_type = True;
- else:
- port_name = rec[0][:-2]
- line = self.generate_network_action("tcp", "connect", port_name)
+ for i in self.out_tcp[PORTS]:
+ rec = self.find_port(int(i), "tcp")
+ if rec == None:
+ self.need_tcp_type = True
+ else:
+ port_name = rec[0][:-2]
+ line = self.generate_network_action("tcp", "connect", port_name)
# line = "corenet_tcp_connect_%s(%s_t)\n" % (port_name, self.name)
- if line not in self.found_tcp_ports:
- self.found_tcp_ports.append(line)
+ if line not in self.found_tcp_ports:
+ self.found_tcp_ports.append(line)
- for i in self.in_udp[PORTS]:
- rec = self.find_port(int(i),"udp")
- if rec == None:
- self.need_udp_type = True;
- else:
- port_name = rec[0][:-2]
- line = self.generate_network_action("udp", "bind", port_name)
+ for i in self.in_udp[PORTS]:
+ rec = self.find_port(int(i), "udp")
+ if rec == None:
+ self.need_udp_type = True
+ else:
+ port_name = rec[0][:-2]
+ line = self.generate_network_action("udp", "bind", port_name)
# line = "corenet_udp_bind_%s(%s_t)\n" % (port_name, self.name)
- if line not in self.found_udp_ports:
- self.found_udp_ports.append(line)
-
- if self.need_udp_type == True or self.need_tcp_type == True:
- return re.sub("TEMPLATETYPE", self.name, network.te_types)
- return ""
-
- def __find_path(self, file):
- for d in self.DEFAULT_DIRS:
- if file.find(d) == 0:
- self.DEFAULT_DIRS[d][1].append(file)
- return self.DEFAULT_DIRS[d]
- self.DEFAULT_DIRS["rw"][1].append(file)
- return self.DEFAULT_DIRS["rw"]
-
- def add_capability(self, capability):
- if capability not in self.capabilities:
- self.capabilities.append(capability)
-
- def set_types(self, types):
- self.types = types
-
- def add_process(self, process):
- if process not in self.processes:
- self.processes.append(process)
-
- def add_boolean(self, name, description):
- self.booleans[name] = description
-
- def add_file(self, file):
- self.files[file] = self.__find_path(file)
-
- def add_dir(self, file):
- self.dirs[file] = self.__find_path(file)
+ if line not in self.found_udp_ports:
+ self.found_udp_ports.append(line)
+
+ if self.need_udp_type == True or self.need_tcp_type == True:
+ return re.sub("TEMPLATETYPE", self.name, network.te_types)
+ return ""
+
+ def __find_path(self, file):
+ for d in self.DEFAULT_DIRS:
+ if file.find(d) == 0:
+ self.DEFAULT_DIRS[d][1].append(file)
+ return self.DEFAULT_DIRS[d]
+ self.DEFAULT_DIRS["rw"][1].append(file)
+ return self.DEFAULT_DIRS["rw"]
+
+ def add_capability(self, capability):
+ if capability not in self.capabilities:
+ self.capabilities.append(capability)
+
+ def set_types(self, types):
+ self.types = types
+
+ def add_process(self, process):
+ if process not in self.processes:
+ self.processes.append(process)
+
+ def add_boolean(self, name, description):
+ self.booleans[name] = description
+
+ def add_file(self, file):
+ self.files[file] = self.__find_path(file)
+
+ def add_dir(self, file):
+ self.dirs[file] = self.__find_path(file)
+
+ def generate_capabilities(self):
+ newte = ""
+ self.capabilities.sort()
+ if len(self.capabilities) > 0:
+ newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities))
+ return newte
+
+ def generate_process(self):
+ newte = ""
+ self.processes.sort()
+ if len(self.processes) > 0:
+ newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes))
+ return newte
+
+ def generate_network_rules(self):
+ newte = ""
+ if self.use_network():
+ newte = "\n"
+
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_network)
+
+ if self.use_tcp():
+ newte += "\n"
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp)
+
+ if self.use_in_tcp():
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp)
+
+ if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp)
+
+ if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp)
+
+ if self.in_tcp[ALL]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp)
+ if self.in_tcp[RESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp)
+ if self.in_tcp[UNRESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp)
+
+ if self.out_tcp[ALL]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp)
+ if self.out_tcp[RESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp)
+ if self.out_tcp[UNRESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp)
+
+ for i in self.found_tcp_ports:
+ newte += i
+
+ if self.use_udp():
+ newte += "\n"
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_udp)
+
+ if self.need_udp_type:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp)
+ if self.use_in_udp():
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp)
+ if self.in_udp[ALL]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp)
+ if self.in_udp[RESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp)
+ if self.in_udp[UNRESERVED]:
+ newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp)
+
+ for i in self.found_udp_ports:
+ newte += i
+ return newte
+
+ def generate_transition_rules(self):
+ newte = ""
+ for app in self.transition_domains:
+ tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules)
+ newte += re.sub("APPLICATION", app, tmp)
+
+ if self.type == USER:
+ for u in self.transition_users:
+ temp = re.sub("TEMPLATETYPE", self.name, executable.te_run_rules)
+ newte += re.sub("USER", u.split("_u")[0], temp)
+
+ return newte
+
+ def generate_admin_rules(self):
+ newte = ""
+ if self.type == EUSER:
+ for d in self.existing_domains:
+ name = d.split("_t")[0]
+ role = name + "_r"
+ for app in self.admin_domains:
+ tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules)
+ if role not in self.all_roles:
+ tmp = re.sub(role, "system_r", tmp)
- def generate_capabilities(self):
- newte = ""
- self.capabilities.sort()
- if len(self.capabilities) > 0:
- newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities))
- return newte
+ newte += re.sub("APPLICATION", app, tmp)
- def generate_process(self):
- newte = ""
- self.processes.sort()
- if len(self.processes) > 0:
- newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes))
return newte
+ if self.type == RUSER:
+ newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules)
- def generate_network_rules(self):
- newte = ""
- if self.use_network():
- newte = "\n"
-
- newte += re.sub("TEMPLATETYPE", self.name, network.te_network)
-
- if self.use_tcp():
- newte += "\n"
- newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp)
-
- if self.use_in_tcp():
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp)
-
- if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp)
-
- if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp)
-
-
- if self.in_tcp[ALL]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp)
- if self.in_tcp[RESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp)
- if self.in_tcp[UNRESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp)
-
- if self.out_tcp[ALL]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp)
- if self.out_tcp[RESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp)
- if self.out_tcp[UNRESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp)
-
- for i in self.found_tcp_ports:
- newte += i
-
- if self.use_udp():
- newte += "\n"
- newte += re.sub("TEMPLATETYPE", self.name, network.te_udp)
-
- if self.need_udp_type:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp)
- if self.use_in_udp():
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp)
- if self.in_udp[ALL]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp)
- if self.in_udp[RESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp)
- if self.in_udp[UNRESERVED]:
- newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp)
-
- for i in self.found_udp_ports:
- newte += i
- return newte
-
- def generate_transition_rules(self):
- newte = ""
- for app in self.transition_domains:
- tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules)
+ for app in self.admin_domains:
+ tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules)
newte += re.sub("APPLICATION", app, tmp)
- if self.type == USER:
- for u in self.transition_users:
- temp = re.sub("TEMPLATETYPE", self.name, executable.te_run_rules)
- newte += re.sub("USER", u.split("_u")[0], temp)
-
- return newte
-
- def generate_admin_rules(self):
- newte = ""
- if self.type == EUSER:
- for d in self.existing_domains:
- name = d.split("_t")[0]
- role = name + "_r"
- for app in self.admin_domains:
- tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules)
- if role not in self.all_roles:
- tmp = re.sub(role, "system_r", tmp)
-
-
- newte += re.sub("APPLICATION", app, tmp)
-
- return newte
-
- if self.type == RUSER:
- newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules)
+ for u in self.transition_users:
+ role = u.split("_u")[0]
- for app in self.admin_domains:
- tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules)
- newte += re.sub("APPLICATION", app, tmp)
+ if (role + "_r") in self.all_roles:
+ tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules)
+ newte += re.sub("USER", role, tmp)
- for u in self.transition_users:
- role = u.split("_u")[0]
+ return newte
- if (role + "_r") in self.all_roles:
- tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules)
- newte += re.sub("USER", role, tmp)
+ def generate_dbus_if(self):
+ newif = ""
+ if self.use_dbus:
+ newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules)
+ return newif
- return newte
-
- def generate_dbus_if(self):
- newif = ""
- if self.use_dbus:
- newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules)
- return newif
-
- def generate_sandbox_if(self):
- newif = ""
- if self.type != SANDBOX:
- return newif
- newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules)
+ def generate_sandbox_if(self):
+ newif = ""
+ if self.type != SANDBOX:
return newif
+ newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules)
+ return newif
+ def generate_admin_if(self):
+ newif = ""
+ newtypes = ""
+ if self.initscript != "":
+ newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types)
+ newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin)
+ for d in self.DEFAULT_KEYS:
+ if len(self.DEFAULT_DIRS[d][1]) > 0:
+ newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types)
+ newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules)
- def generate_admin_if(self):
- newif = ""
- newtypes = ""
- if self.initscript != "":
- newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types)
- newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin)
- for d in self.DEFAULT_KEYS:
- if len(self.DEFAULT_DIRS[d][1]) > 0:
- newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types)
- newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules)
-
- if newif != "":
- ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin)
- ret += newtypes
-
- ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin)
- ret += newif
- ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin)
- return ret
+ if newif != "":
+ ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin)
+ ret += newtypes
- return ""
+ ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin)
+ ret += newif
+ ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin)
+ return ret
- def generate_cgi_types(self):
- return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types)
+ return ""
- def generate_sandbox_types(self):
- return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types)
+ def generate_cgi_types(self):
+ return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types)
- def generate_userapp_types(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types)
+ def generate_sandbox_types(self):
+ return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types)
- def generate_inetd_types(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types)
+ def generate_userapp_types(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types)
- def generate_dbusd_types(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types)
+ def generate_inetd_types(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types)
- def generate_min_login_user_types(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types)
+ def generate_dbusd_types(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types)
- def generate_login_user_types(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types)
+ def generate_min_login_user_types(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types)
- def generate_admin_user_types(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types)
+ def generate_login_user_types(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types)
- def generate_existing_user_types(self):
- if len(self.existing_domains) == 0:
- raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
- newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
- newte += """gen_require(`"""
+ def generate_admin_user_types(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types)
- for d in self.existing_domains:
- newte += """
+ def generate_existing_user_types(self):
+ if len(self.existing_domains) == 0:
+ raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
+ newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
+ newte += """gen_require(`"""
+
+ for d in self.existing_domains:
+ newte += """
type %s;""" % d
- role = d.split("_t")[0] + "_r"
- if role in self.all_roles:
- newte += """
- role %s;""" % role
+ role = d.split("_t")[0] + "_r"
+ if role in self.all_roles:
newte += """
+ role %s;""" % role
+ newte += """
')
"""
- return newte;
-
- def generate_x_login_user_types(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types)
-
- def generate_root_user_types(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types)
-
- def generate_new_types(self):
- newte = ""
- if len(self.types) == 0:
- raise ValueError(_("Type field required"))
-
- for t in self.types:
- for i in self.DEFAULT_EXT:
- if t.endswith(i):
- print t, t[:-len(i)]
- newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
- break
-
- if NEWTYPE and newte == "":
- default_ext = []
- for i in self.DEFAULT_EXT:
- default_ext.append(i)
- raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
-
- return newte
-
- def generate_new_rules(self):
- return ""
-
- def generate_daemon_types(self):
- newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
- if self.initscript != "":
- newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types)
- return newte
-
- def generate_tmp_types(self):
- if self.use_tmp:
- return re.sub("TEMPLATETYPE", self.name, tmp.te_types)
- else:
- return ""
+ return newte
+
+ def generate_x_login_user_types(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types)
+
+ def generate_root_user_types(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types)
+
+ def generate_new_types(self):
+ newte = ""
+ if len(self.types) == 0:
+ raise ValueError(_("Type field required"))
+
+ for t in self.types:
+ for i in self.DEFAULT_EXT:
+ if t.endswith(i):
+ print t, t[:-len(i)]
+ newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
+ break
+
+ if NEWTYPE and newte == "":
+ default_ext = []
+ for i in self.DEFAULT_EXT:
+ default_ext.append(i)
+ raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
+
+ return newte
+
+ def generate_new_rules(self):
+ return ""
+
+ def generate_daemon_types(self):
+ newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
+ if self.initscript != "":
+ newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types)
+ return newte
+
+ def generate_tmp_types(self):
+ if self.use_tmp:
+ return re.sub("TEMPLATETYPE", self.name, tmp.te_types)
+ else:
+ return ""
- def generate_booleans(self):
- newte = ""
- for b in self.booleans:
- tmp = re.sub("BOOLEAN", b, boolean.te_boolean)
- newte += re.sub("DESCRIPTION", self.booleans[b], tmp)
- return newte
+ def generate_booleans(self):
+ newte = ""
+ for b in self.booleans:
+ tmp = re.sub("BOOLEAN", b, boolean.te_boolean)
+ newte += re.sub("DESCRIPTION", self.booleans[b], tmp)
+ return newte
- def generate_boolean_rules(self):
- newte = ""
- for b in self.booleans:
- newte += re.sub("BOOLEAN", b, boolean.te_rules)
- return newte
+ def generate_boolean_rules(self):
+ newte = ""
+ for b in self.booleans:
+ newte += re.sub("BOOLEAN", b, boolean.te_rules)
+ return newte
- def generate_sandbox_te(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types)
+ def generate_sandbox_te(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types)
- def generate_cgi_te(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types)
+ def generate_cgi_te(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types)
- def generate_daemon_rules(self):
- newif = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules)
+ def generate_daemon_rules(self):
+ newif = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules)
- return newif
+ return newif
- def generate_new_type_if(self):
- newif = ""
- for t in self.types:
- for i in self.DEFAULT_EXT:
- if t.endswith(i):
- reqtype = t[:-len(i)] + "_t"
- newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules)
- break
- return newif
+ def generate_new_type_if(self):
+ newif = ""
+ for t in self.types:
+ for i in self.DEFAULT_EXT:
+ if t.endswith(i):
+ reqtype = t[:-len(i)] + "_t"
+ newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules)
+ break
+ return newif
- def generate_login_user_rules(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules)
+ def generate_login_user_rules(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules)
- def generate_existing_user_rules(self):
- nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules)
- return nerules
+ def generate_existing_user_rules(self):
+ nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules)
+ return nerules
- def generate_x_login_user_rules(self):
- return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules)
+ def generate_x_login_user_rules(self):
+ return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules)
- def generate_root_user_rules(self):
- newte =re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules)
- return newte
+ def generate_root_user_rules(self):
+ newte = re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules)
+ return newte
- def generate_userapp_rules(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules)
+ def generate_userapp_rules(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules)
- def generate_inetd_rules(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules)
+ def generate_inetd_rules(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules)
- def generate_dbusd_rules(self):
- return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules)
+ def generate_dbusd_rules(self):
+ return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules)
- def generate_tmp_rules(self):
- if self.use_tmp:
- return re.sub("TEMPLATETYPE", self.name, tmp.te_rules)
- else:
- return ""
-
- def generate_cgi_rules(self):
- newte = ""
- newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules)
- return newte
-
- def generate_sandbox_rules(self):
- newte = ""
- newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules)
- return newte
-
- def generate_user_if(self):
- newif =""
- if self.use_terminal or self.type == USER:
- newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules)
-
- if self.type in ( TUSER, XUSER, AUSER, LUSER):
- newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules)
- return newif
-
- def generate_if(self):
- newif = ""
- newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules)
- if self.program:
- newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules)
- if self.initscript != "":
- newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules)
-
- for d in self.DEFAULT_KEYS:
- if len(self.DEFAULT_DIRS[d][1]) > 0:
- newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules)
- for i in self.DEFAULT_DIRS[d][1]:
- if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
- newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules)
- break
- newif += self.generate_user_if()
- newif += self.generate_dbus_if()
- newif += self.generate_admin_if()
- newif += self.generate_sandbox_if()
- newif += self.generate_new_type_if()
- newif += self.generate_new_rules()
-
- return newif
-
- def generate_default_types(self):
- return self.DEFAULT_TYPES[self.type][0]()
-
- def generate_default_rules(self):
- if self.DEFAULT_TYPES[self.type][1]:
- return self.DEFAULT_TYPES[self.type][1]()
- return ""
-
- def generate_roles_rules(self):
- newte = ""
- if self.type in ( TUSER, XUSER, AUSER, LUSER ):
- roles = ""
- if len(self.roles) > 0:
- newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
- newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules)
- for role in self.roles:
- tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules)
- newte += re.sub("ROLE", role, tmp)
- return newte
-
- def generate_te(self):
- newte = self.generate_default_types()
- for d in self.DEFAULT_KEYS:
- if len(self.DEFAULT_DIRS[d][1]) > 0:
- # CGI scripts already have a rw_t
- if self.type != CGI or d != "rw":
- newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
+ def generate_tmp_rules(self):
+ if self.use_tmp:
+ return re.sub("TEMPLATETYPE", self.name, tmp.te_rules)
+ else:
+ return ""
- if self.type != EUSER:
- newte +="""
+ def generate_cgi_rules(self):
+ newte = ""
+ newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules)
+ return newte
+
+ def generate_sandbox_rules(self):
+ newte = ""
+ newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules)
+ return newte
+
+ def generate_user_if(self):
+ newif = ""
+ if self.use_terminal or self.type == USER:
+ newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules)
+
+ if self.type in (TUSER, XUSER, AUSER, LUSER):
+ newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules)
+ return newif
+
+ def generate_if(self):
+ newif = ""
+ newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules)
+ if self.program:
+ newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules)
+ if self.initscript != "":
+ newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules)
+
+ for d in self.DEFAULT_KEYS:
+ if len(self.DEFAULT_DIRS[d][1]) > 0:
+ newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules)
+ for i in self.DEFAULT_DIRS[d][1]:
+ if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+ newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules)
+ break
+ newif += self.generate_user_if()
+ newif += self.generate_dbus_if()
+ newif += self.generate_admin_if()
+ newif += self.generate_sandbox_if()
+ newif += self.generate_new_type_if()
+ newif += self.generate_new_rules()
+
+ return newif
+
+ def generate_default_types(self):
+ return self.DEFAULT_TYPES[self.type][0]()
+
+ def generate_default_rules(self):
+ if self.DEFAULT_TYPES[self.type][1]:
+ return self.DEFAULT_TYPES[self.type][1]()
+ return ""
+
+ def generate_roles_rules(self):
+ newte = ""
+ if self.type in (TUSER, XUSER, AUSER, LUSER):
+ roles = ""
+ if len(self.roles) > 0:
+ newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
+ newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules)
+ for role in self.roles:
+ tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules)
+ newte += re.sub("ROLE", role, tmp)
+ return newte
+
+ def generate_te(self):
+ newte = self.generate_default_types()
+ for d in self.DEFAULT_KEYS:
+ if len(self.DEFAULT_DIRS[d][1]) > 0:
+ # CGI scripts already have a rw_t
+ if self.type != CGI or d != "rw":
+ newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
+
+ if self.type != EUSER:
+ newte += """
########################################
#
# %s local policy
#
""" % self.name
- newte += self.generate_capabilities()
- newte += self.generate_process()
- newte += self.generate_network_types()
- newte += self.generate_tmp_types()
- newte += self.generate_booleans()
- newte += self.generate_default_rules()
- newte += self.generate_boolean_rules()
-
- for d in self.DEFAULT_KEYS:
- if len(self.DEFAULT_DIRS[d][1]) > 0:
- if self.type == EUSER:
- newte_tmp = ""
- for domain in self.existing_domains:
- newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2]+"_t", self.DEFAULT_DIRS[d][2].te_rules)
- newte += re.sub("TEMPLATETYPE_rw_t", self.name+"_rw_t", newte_tmp)
- else:
- newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
- for i in self.DEFAULT_DIRS[d][1]:
- if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
- if self.type == EUSER:
- for domain in self.existing_domains:
- newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
-
- else:
- newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
- break
-
- newte += self.generate_tmp_rules()
- newte += self.generate_network_rules()
- newte += self.generate_fd_rules()
- newte += self.generate_etc_rules()
- newte += self.generate_pam_rules()
- newte += self.generate_uid_rules()
- newte += self.generate_audit_rules()
- newte += self.generate_syslog_rules()
- newte += self.generate_localization_rules()
- newte += self.generate_resolve_rules()
- newte += self.generate_roles_rules()
- newte += self.generate_mail_rules()
- newte += self.generate_transition_rules()
- newte += self.generate_admin_rules()
- newte += self.generate_dbus_rules()
- newte += self.generate_kerberos_rules()
- newte += self.generate_manage_krb5_rcache_rules()
-
- return newte
-
- def generate_fc(self):
- newfc = ""
- fclist = []
- for i in self.files.keys():
- if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
- t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file)
- else:
- t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file)
- t2 = re.sub("FILENAME", i, t1)
- fclist.append(re.sub("FILETYPE", self.files[i][0], t2))
+ newte += self.generate_capabilities()
+ newte += self.generate_process()
+ newte += self.generate_network_types()
+ newte += self.generate_tmp_types()
+ newte += self.generate_booleans()
+ newte += self.generate_default_rules()
+ newte += self.generate_boolean_rules()
+
+ for d in self.DEFAULT_KEYS:
+ if len(self.DEFAULT_DIRS[d][1]) > 0:
+ if self.type == EUSER:
+ newte_tmp = ""
+ for domain in self.existing_domains:
+ newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2] + "_t", self.DEFAULT_DIRS[d][2].te_rules)
+ newte += re.sub("TEMPLATETYPE_rw_t", self.name + "_rw_t", newte_tmp)
+ else:
+ newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
+ for i in self.DEFAULT_DIRS[d][1]:
+ if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+ if self.type == EUSER:
+ for domain in self.existing_domains:
+ newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
- for i in self.dirs.keys():
- t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir)
- t2 = re.sub("FILENAME", i, t1)
- fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2))
+ else:
+ newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
+ break
+
+ newte += self.generate_tmp_rules()
+ newte += self.generate_network_rules()
+ newte += self.generate_fd_rules()
+ newte += self.generate_etc_rules()
+ newte += self.generate_pam_rules()
+ newte += self.generate_uid_rules()
+ newte += self.generate_audit_rules()
+ newte += self.generate_syslog_rules()
+ newte += self.generate_localization_rules()
+ newte += self.generate_resolve_rules()
+ newte += self.generate_roles_rules()
+ newte += self.generate_mail_rules()
+ newte += self.generate_transition_rules()
+ newte += self.generate_admin_rules()
+ newte += self.generate_dbus_rules()
+ newte += self.generate_kerberos_rules()
+ newte += self.generate_manage_krb5_rcache_rules()
+
+ return newte
+
+ def generate_fc(self):
+ newfc = ""
+ fclist = []
+ for i in self.files.keys():
+ if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+ t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file)
+ else:
+ t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file)
+ t2 = re.sub("FILENAME", i, t1)
+ fclist.append(re.sub("FILETYPE", self.files[i][0], t2))
- if self.type in USERS + [ SANDBOX ]:
- if len(fclist) == 0:
- return executable.fc_user
+ for i in self.dirs.keys():
+ t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir)
+ t2 = re.sub("FILENAME", i, t1)
+ fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2))
- if self.type not in USERS + [ SANDBOX, EUSER, NEWTYPE ] and not self.program:
- raise ValueError(_("You must enter the executable path for your confined process"))
+ if self.type in USERS + [SANDBOX]:
+ if len(fclist) == 0:
+ return executable.fc_user
- if self.program:
- t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
- fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
+ if self.type not in USERS + [SANDBOX, EUSER, NEWTYPE] and not self.program:
+ raise ValueError(_("You must enter the executable path for your confined process"))
- if self.initscript != "":
- t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
- fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
+ if self.program:
+ t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
+ fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
- fclist.sort()
- newfc="\n".join(fclist)
- return newfc
-
- def generate_user_sh(self):
- newsh = ""
- if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
- return newsh
-
- roles = ""
- for role in self.roles:
- roles += " %s_r" % role
- if roles != "":
- roles += " system_r"
- tmp = re.sub("TEMPLATETYPE", self.name, script.users)
- newsh += re.sub("ROLES", roles, tmp)
-
- if self.type == RUSER or self.type == AUSER:
- for u in self.transition_users:
- tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans)
- newsh += re.sub("USER", u, tmp)
-
- if self.type == LUSER:
- newsh += re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context)
- else:
- newsh += re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context)
+ if self.initscript != "":
+ t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
+ fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
+ fclist.sort()
+ newfc = "\n".join(fclist)
+ return newfc
+ def generate_user_sh(self):
+ newsh = ""
+ if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
return newsh
- def generate_sh(self):
- temp = re.sub("TEMPLATETYPE", self.file_name, script.compile)
- temp = re.sub("DOMAINTYPE", self.name, temp)
- if self.type == EUSER:
- newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp)
- else:
- newsh = re.sub("TEMPLATEFILE", self.file_name, temp)
- newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
-
- if self.program:
- newsh += re.sub("FILENAME", self.program, script.restorecon)
- if self.initscript != "":
- newsh += re.sub("FILENAME", self.initscript, script.restorecon)
-
- for i in self.files.keys():
- newsh += re.sub("FILENAME", i, script.restorecon)
-
- for i in self.dirs.keys():
- newsh += re.sub("FILENAME", i, script.restorecon)
-
- for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]:
- if self.find_port(i,"tcp") == None:
- t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports)
- newsh += re.sub("TEMPLATETYPE", self.name, t1)
-
- for i in self.in_udp[PORTS]:
- if self.find_port(i,"udp") == None:
- t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports)
- newsh += re.sub("TEMPLATETYPE", self.name, t1)
-
- newsh += self.generate_user_sh()
- if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat","centos","SuSE","fedora","mandrake","mandriva")):
- newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
-
- return newsh
-
- def generate_spec(self):
- newspec = ""
-
- selinux_policyver = get_rpm_nvr_list("selinux-policy")[1]
- POLICYCOREUTILSVER = get_rpm_nvr_list("checkpolicy")[1]
-
- newspec += spec.header_comment_section
- if self.type in APPLICATIONS:
- newspec += spec.define_relabel_files_begin
- if self.program:
- newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end)
- if self.initscript != "":
- newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end)
- for i in self.files.keys():
- newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
- for i in self.dirs.keys():
- newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
-
- newspec += re.sub("VERSION", selinux_policyver, spec.base_section)
- newspec = re.sub("MODULENAME", self.file_name, newspec)
- newspec = re.sub("DOMAINNAME", self.name, newspec)
- if len(self.rpms) > 0:
- newspec += "Requires(post): %s\n" % ", ".join(self.rpms)
- newspec += re.sub("MODULENAME", self.file_name, spec.mid_section)
- newspec = re.sub("DOMAINNAME", self.name, newspec)
- newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec)
-
- if self.type not in APPLICATIONS:
- newspec = re.sub("%relabel_files", "", newspec)
-
- # Remove man pages from EUSER spec file
- if self.type == EUSER:
- newspec = re.sub(".*%s_selinux.8.*" % self.name,"", newspec)
- # Remove user context file from non users spec file
- if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
- newspec = re.sub(".*%s_u.*" % self.name,"", newspec)
- return newspec
-
- def write_spec(self, out_dir):
- specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
- fd = open(specfile, "w")
- fd.write(self.generate_spec())
- fd.close()
-
- return specfile
-
- def write_te(self, out_dir):
- tefile = "%s/%s.te" % (out_dir, self.file_name)
- fd = open(tefile, "w")
- fd.write(self.generate_te())
- fd.close()
- return tefile
-
- def write_sh(self, out_dir):
- shfile = "%s/%s.sh" % (out_dir, self.file_name)
- fd = open(shfile, "w")
- fd.write(self.generate_sh())
- fd.close()
- os.chmod(shfile, 0750)
- return shfile
-
- def write_if(self, out_dir):
- iffile = "%s/%s.if" % (out_dir, self.file_name)
- fd = open(iffile, "w")
- fd.write(self.generate_if())
- fd.close()
- return iffile
-
- def write_fc(self,out_dir):
- fcfile = "%s/%s.fc" % (out_dir, self.file_name)
- fd = open(fcfile, "w")
- fd.write(self.generate_fc())
- fd.close()
- return fcfile
-
- def __extract_rpms(self):
- import yum
- yb = yum.YumBase()
- yb.setCacheDir()
-
- for pkg in yb.rpmdb.searchProvides(self.program):
- self.rpms.append(pkg.name)
- for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist:
- for b in self.DEFAULT_DIRS:
- if b == "/etc":
- continue
- if fname.startswith(b):
- if os.path.isfile(fname):
- self.add_file(fname)
- else:
- self.add_dir(fname)
+ roles = ""
+ for role in self.roles:
+ roles += " %s_r" % role
+ if roles != "":
+ roles += " system_r"
+ tmp = re.sub("TEMPLATETYPE", self.name, script.users)
+ newsh += re.sub("ROLES", roles, tmp)
+
+ if self.type == RUSER or self.type == AUSER:
+ for u in self.transition_users:
+ tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans)
+ newsh += re.sub("USER", u, tmp)
+
+ if self.type == LUSER:
+ newsh += re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context)
+ else:
+ newsh += re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context)
+
+ return newsh
+
+ def generate_sh(self):
+ temp = re.sub("TEMPLATETYPE", self.file_name, script.compile)
+ temp = re.sub("DOMAINTYPE", self.name, temp)
+ if self.type == EUSER:
+ newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp)
+ else:
+ newsh = re.sub("TEMPLATEFILE", self.file_name, temp)
+ newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
+
+ if self.program:
+ newsh += re.sub("FILENAME", self.program, script.restorecon)
+ if self.initscript != "":
+ newsh += re.sub("FILENAME", self.initscript, script.restorecon)
+
+ for i in self.files.keys():
+ newsh += re.sub("FILENAME", i, script.restorecon)
+
+ for i in self.dirs.keys():
+ newsh += re.sub("FILENAME", i, script.restorecon)
+
+ for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]:
+ if self.find_port(i, "tcp") == None:
+ t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports)
+ newsh += re.sub("TEMPLATETYPE", self.name, t1)
+
+ for i in self.in_udp[PORTS]:
+ if self.find_port(i, "udp") == None:
+ t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports)
+ newsh += re.sub("TEMPLATETYPE", self.name, t1)
+
+ newsh += self.generate_user_sh()
+ if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
+ newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
+
+ return newsh
+
+ def generate_spec(self):
+ newspec = ""
+
+ selinux_policyver = get_rpm_nvr_list("selinux-policy")[1]
+ POLICYCOREUTILSVER = get_rpm_nvr_list("checkpolicy")[1]
+
+ newspec += spec.header_comment_section
+ if self.type in APPLICATIONS:
+ newspec += spec.define_relabel_files_begin
+ if self.program:
+ newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end)
+ if self.initscript != "":
+ newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end)
+ for i in self.files.keys():
+ newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
+ for i in self.dirs.keys():
+ newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
+
+ newspec += re.sub("VERSION", selinux_policyver, spec.base_section)
+ newspec = re.sub("MODULENAME", self.file_name, newspec)
+ newspec = re.sub("DOMAINNAME", self.name, newspec)
+ if len(self.rpms) > 0:
+ newspec += "Requires(post): %s\n" % ", ".join(self.rpms)
+ newspec += re.sub("MODULENAME", self.file_name, spec.mid_section)
+ newspec = re.sub("DOMAINNAME", self.name, newspec)
+ newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec)
+
+ if self.type not in APPLICATIONS:
+ newspec = re.sub("%relabel_files", "", newspec)
+
+ # Remove man pages from EUSER spec file
+ if self.type == EUSER:
+ newspec = re.sub(".*%s_selinux.8.*" % self.name, "", newspec)
+ # Remove user context file from non users spec file
+ if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
+ newspec = re.sub(".*%s_u.*" % self.name, "", newspec)
+ return newspec
+
+ def write_spec(self, out_dir):
+ specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
+ fd = open(specfile, "w")
+ fd.write(self.generate_spec())
+ fd.close()
+
+ return specfile
+
+ def write_te(self, out_dir):
+ tefile = "%s/%s.te" % (out_dir, self.file_name)
+ fd = open(tefile, "w")
+ fd.write(self.generate_te())
+ fd.close()
+ return tefile
+
+ def write_sh(self, out_dir):
+ shfile = "%s/%s.sh" % (out_dir, self.file_name)
+ fd = open(shfile, "w")
+ fd.write(self.generate_sh())
+ fd.close()
+ os.chmod(shfile, 0750)
+ return shfile
+
+ def write_if(self, out_dir):
+ iffile = "%s/%s.if" % (out_dir, self.file_name)
+ fd = open(iffile, "w")
+ fd.write(self.generate_if())
+ fd.close()
+ return iffile
+
+ def write_fc(self, out_dir):
+ fcfile = "%s/%s.fc" % (out_dir, self.file_name)
+ fd = open(fcfile, "w")
+ fd.write(self.generate_fc())
+ fd.close()
+ return fcfile
+
+ def __extract_rpms(self):
+ import yum
+ yb = yum.YumBase()
+ yb.setCacheDir()
+
+ for pkg in yb.rpmdb.searchProvides(self.program):
+ self.rpms.append(pkg.name)
+ for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist:
+ for b in self.DEFAULT_DIRS:
+ if b == "/etc":
+ continue
+ if fname.startswith(b):
+ if os.path.isfile(fname):
+ self.add_file(fname)
+ else:
+ self.add_dir(fname)
- for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]):
- for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist:
- for b in self.DEFAULT_DIRS:
- if b == "/etc":
- continue
- if fname.startswith(b):
- if os.path.isfile(fname):
- self.add_file(fname)
- else:
- self.add_dir(fname)
-
- # some packages have own systemd subpackage
- # tor-systemd for example
- binary_name = self.program.split("/")[-1]
- for bpkg in yb.rpmdb.searchNames([ "%s-systemd" % binary_name ]):
- for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist:
+ for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]):
+ for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist:
for b in self.DEFAULT_DIRS:
if b == "/etc":
continue
@@ -1294,82 +1284,96 @@ allow %s_t %s_t:%s_socket name_%s;
else:
self.add_dir(fname)
- def gen_writeable(self):
- try:
- self.__extract_rpms()
- except ImportError:
- pass
+ # some packages have own systemd subpackage
+ # tor-systemd for example
+ binary_name = self.program.split("/")[-1]
+ for bpkg in yb.rpmdb.searchNames(["%s-systemd" % binary_name]):
+ for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist:
+ for b in self.DEFAULT_DIRS:
+ if b == "/etc":
+ continue
+ if fname.startswith(b):
+ if os.path.isfile(fname):
+ self.add_file(fname)
+ else:
+ self.add_dir(fname)
+
+ def gen_writeable(self):
+ try:
+ self.__extract_rpms()
+ except ImportError:
+ pass
- if os.path.isfile("/var/run/%s.pid" % self.name):
- self.add_file("/var/run/%s.pid" % self.name)
+ if os.path.isfile("/var/run/%s.pid" % self.name):
+ self.add_file("/var/run/%s.pid" % self.name)
- if os.path.isdir("/var/run/%s" % self.name):
- self.add_dir("/var/run/%s" % self.name)
+ if os.path.isdir("/var/run/%s" % self.name):
+ self.add_dir("/var/run/%s" % self.name)
- if os.path.isdir("/var/log/%s" % self.name):
- self.add_dir("/var/log/%s" % self.name)
+ if os.path.isdir("/var/log/%s" % self.name):
+ self.add_dir("/var/log/%s" % self.name)
- if os.path.isfile("/var/log/%s.log" % self.name):
- self.add_file("/var/log/%s.log" % self.name)
+ if os.path.isfile("/var/log/%s.log" % self.name):
+ self.add_file("/var/log/%s.log" % self.name)
- if os.path.isdir("/var/lib/%s" % self.name):
- self.add_dir("/var/lib/%s" % self.name)
+ if os.path.isdir("/var/lib/%s" % self.name):
+ self.add_dir("/var/lib/%s" % self.name)
- if os.path.isfile("/etc/rc.d/init.d/%s" % self.name):
- self.set_init_script("/etc/rc\.d/init\.d/%s" % self.name)
+ if os.path.isfile("/etc/rc.d/init.d/%s" % self.name):
+ self.set_init_script("/etc/rc\.d/init\.d/%s" % self.name)
- # we don't want to have subdir in the .fc policy file
- # if we already specify labeling for parent dir
- temp_basepath = []
- for p in self.DEFAULT_DIRS.keys():
- temp_dirs = []
- try:
- temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/"
- except IndexError:
+ # we don't want to have subdir in the .fc policy file
+ # if we already specify labeling for parent dir
+ temp_basepath = []
+ for p in self.DEFAULT_DIRS.keys():
+ temp_dirs = []
+ try:
+ temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/"
+ except IndexError:
+ continue
+
+ for i in self.DEFAULT_DIRS[p][1]:
+ if i.startswith(temp_basepath):
+ temp_dirs.append(i)
+ else:
continue
- for i in self.DEFAULT_DIRS[p][1]:
- if i.startswith(temp_basepath):
- temp_dirs.append(i)
+ if len(temp_dirs) is not 0:
+ for i in temp_dirs:
+ if i in self.dirs.keys():
+ del(self.dirs[i])
+ elif i in self.files.keys():
+ del(self.files[i])
else:
continue
- if len(temp_dirs) is not 0:
- for i in temp_dirs:
- if i in self.dirs.keys():
- del(self.dirs[i])
- elif i in self.files.keys():
- del(self.files[i])
- else:
- continue
-
- self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs))
+ self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs))
- def gen_symbols(self):
- if self.type not in APPLICATIONS:
- return
- if not os.path.exists(self.program):
- sys.stderr.write("""
+ def gen_symbols(self):
+ if self.type not in APPLICATIONS:
+ return
+ if not os.path.exists(self.program):
+ sys.stderr.write("""
***************************************
Warning %s does not exist
***************************************
""" % self.program)
- return
- fd = os.popen("nm -D %s | grep U" % self.program)
- for s in fd.read().split():
- for b in self.symbols:
- if s.startswith(b):
- exec "self.%s" % self.symbols[b]
- fd.close()
-
- def generate(self, out_dir = os.getcwd() ):
- out = "Created the following files:\n"
- out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file"))
- out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file"))
- out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file"))
- if self.type != NEWTYPE:
- if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat","centos","SuSE","fedora","mandrake","mandriva")):
- out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
- out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
- return out
+ return
+ fd = os.popen("nm -D %s | grep U" % self.program)
+ for s in fd.read().split():
+ for b in self.symbols:
+ if s.startswith(b):
+ exec "self.%s" % self.symbols[b]
+ fd.close()
+
+ def generate(self, out_dir=os.getcwd()):
+ out = "Created the following files:\n"
+ out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file"))
+ out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file"))
+ out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file"))
+ if self.type != NEWTYPE:
+ if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
+ out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
+ out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
+ return out
diff --git a/policycoreutils/sepolicy/sepolicy/gui.py b/policycoreutils/sepolicy/sepolicy/gui.py
index 5ca87b98..313b77f6 100644
--- a/policycoreutils/sepolicy/sepolicy/gui.py
+++ b/policycoreutils/sepolicy/sepolicy/gui.py
@@ -38,18 +38,19 @@ import sepolicy.network
import sepolicy.manpage
import dbus
import time
-import os, re
+import os
+import re
import gettext
import unicodedata
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
@@ -58,37 +59,39 @@ reverse_file_type_str = {}
for f in sepolicy.file_type_str:
reverse_file_type_str[sepolicy.file_type_str[f]] = f
-enabled=[_("No"), _("Yes")]
-action=[_("Disable"), _("Enable")]
+enabled = [_("No"), _("Yes")]
+action = [_("Disable"), _("Enable")]
+
+
def compare(a, b):
- return cmp(a.lower(),b.lower())
+ return cmp(a.lower(), b.lower())
import distutils.sysconfig
-ADVANCED_LABEL = ( _("Advanced >>"), _("Advanced <<") )
-ADVANCED_SEARCH_LABEL = ( _("Advanced Search >>"), _("Advanced Search <<") )
+ADVANCED_LABEL = (_("Advanced >>"), _("Advanced <<"))
+ADVANCED_SEARCH_LABEL = (_("Advanced Search >>"), _("Advanced Search <<"))
OUTBOUND_PAGE = 0
INBOUND_PAGE = 1
-TRANSITIONS_FROM_PAGE=0
-TRANSITIONS_TO_PAGE=1
-TRANSITIONS_FILE_PAGE=2
+TRANSITIONS_FROM_PAGE = 0
+TRANSITIONS_TO_PAGE = 1
+TRANSITIONS_FILE_PAGE = 2
EXE_PAGE = 0
WRITABLE_PAGE = 1
APP_PAGE = 2
-BOOLEANS_PAGE=0
-FILES_PAGE=1
-NETWORK_PAGE=2
-TRANSITIONS_PAGE=3
-LOGIN_PAGE=4
-USER_PAGE=5
-LOCKDOWN_PAGE=6
-SYSTEM_PAGE=7
-FILE_EQUIV_PAGE=8
-START_PAGE=9
+BOOLEANS_PAGE = 0
+FILES_PAGE = 1
+NETWORK_PAGE = 2
+TRANSITIONS_PAGE = 3
+LOGIN_PAGE = 4
+USER_PAGE = 5
+LOCKDOWN_PAGE = 6
+SYSTEM_PAGE = 7
+FILE_EQUIV_PAGE = 8
+START_PAGE = 9
-keys = ["boolean", "fcontext", "fcontext-equiv", "port", "login", "user", "module", "node", "interface" ]
+keys = ["boolean", "fcontext", "fcontext-equiv", "port", "login", "user", "module", "node", "interface"]
DISABLED_TEXT = _("""<small>
To change from Disabled to Enforcing mode
@@ -98,9 +101,10 @@ To change from Disabled to Enforcing mode
* Change the system mode to Enforcing</small>
""")
+
class SELinuxGui():
- def __init__( self , app = None, test = False):
+ def __init__(self, app=None, test=False):
self.finish_init = False
self.opage = START_PAGE
self.dbus = SELinuxDBus()
@@ -119,8 +123,8 @@ class SELinuxGui():
self.init_cur()
self.application = app
self.filter_txt = ""
- builder = Gtk.Builder() # BUILDER OBJ
- self.code_path = distutils.sysconfig.get_python_lib(plat_specific = True) + "/sepolicy/"
+ builder = Gtk.Builder() # BUILDER OBJ
+ self.code_path = distutils.sysconfig.get_python_lib(plat_specific=True) + "/sepolicy/"
glade_file = self.code_path + "sepolicy.glade"
builder.add_from_file(glade_file)
self.outer_notebook = builder.get_object("outer_notebook")
@@ -314,7 +318,7 @@ class SELinuxGui():
self.files_delete_liststore = builder.get_object("files_delete_liststore")
self.network_delete_window = builder.get_object("network_delete_window")
self.network_delete_treeview = builder.get_object("network_delete_treeview")
- self.network_delete_liststore =builder.get_object("network_delete_liststore")
+ self.network_delete_liststore = builder.get_object("network_delete_liststore")
# Delete items **************************************
# Progress bar **************************************
@@ -323,7 +327,7 @@ class SELinuxGui():
# executable_files items ****************************
self.executable_files_treeview = builder.get_object("Executable_files_treeview") # Get the executable files tree view
- self.executable_files_filter= builder.get_object("executable_files_filter")
+ self.executable_files_filter = builder.get_object("executable_files_filter")
self.executable_files_filter.set_visible_func(self.filter_the_data)
self.executable_files_tab = builder.get_object("Executable_files_tab")
self.executable_files_tab_tooltip_txt = self.executable_files_tab.get_tooltip_text()
@@ -363,7 +367,7 @@ class SELinuxGui():
self.network_out_treeview = builder.get_object("outbound_treeview")
self.network_out_liststore = builder.get_object("network_out_liststore")
self.network_out_liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
- self.network_out_filter = builder.get_object("network_out_filter")
+ self.network_out_filter = builder.get_object("network_out_filter")
self.network_out_filter.set_visible_func(self.filter_the_data)
self.network_out_tab = builder.get_object("network_out_tab")
self.network_out_tab_tooltip_txt = self.network_out_tab.get_tooltip_text()
@@ -371,7 +375,7 @@ class SELinuxGui():
self.network_in_treeview = builder.get_object("inbound_treeview")
self.network_in_liststore = builder.get_object("network_in_liststore")
self.network_in_liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
- self.network_in_filter = builder.get_object("network_in_filter")
+ self.network_in_filter = builder.get_object("network_in_filter")
self.network_in_filter.set_visible_func(self.filter_the_data)
self.network_in_tab = builder.get_object("network_in_tab")
self.network_in_tab_tooltip_txt = self.network_in_tab.get_tooltip_text()
@@ -424,7 +428,7 @@ class SELinuxGui():
# Combobox and Entry items **************************
self.combobox_menu = builder.get_object("combobox_org") # This is the combobox box object, aka the arrow next to the entry text bar
self.combobox_menu_model = builder.get_object("application_liststore")
- self.completion_entry = builder.get_object("completion_entry") #self.combobox_menu.get_child()
+ self.completion_entry = builder.get_object("completion_entry") # self.combobox_menu.get_child()
self.completion_entry_model = builder.get_object("application_liststore")
self.entrycompletion_obj = builder.get_object("entrycompletion_obj")
#self.entrycompletion_obj = Gtk.EntryCompletion()
@@ -483,7 +487,7 @@ class SELinuxGui():
self.loading = 1
path = None
if test:
- domains = [ "httpd_t", "abrt_t" ]
+ domains = ["httpd_t", "abrt_t"]
if app and app not in domains:
domains.append(app)
else:
@@ -497,7 +501,7 @@ class SELinuxGui():
self.combo_box_initialize(domain, None)
self.advanced_search_initialize(domain)
self.all_list.append(domain)
- self.percentage = float(float(self.loading)/float(length))
+ self.percentage = float(float(self.loading) / float(length))
self.progress_bar.set_fraction(self.percentage)
self.progress_bar.set_pulse_step(self.percentage)
self.idle_func()
@@ -516,84 +520,84 @@ class SELinuxGui():
loading_gui.hide()
dic = {
- "on_combo_button_clicked" : self.open_combo_menu,
- "on_disable_ptrace_toggled" : self.on_disable_ptrace,
- "on_SELinux_window_configure_event" : self.hide_combo_menu,
- "on_entrycompletion_obj_match_selected" : self.set_application_label,
- "on_filter_changed" : self.get_filter_data,
- "on_save_changes_file_equiv_clicked" : self.update_to_file_equiv,
- "on_save_changes_login_clicked" : self.update_to_login,
- "on_save_changes_user_clicked" : self.update_to_user,
- "on_save_changes_files_clicked" : self.update_to_files,
- "on_save_changes_network_clicked" : self.update_to_network,
- "on_Advanced_text_files_button_press_event" : self.reveal_advanced,
- "item_in_tree_selected" : self.cursor_changed,
- "on_Application_file_types_treeview_configure_event" : self.resize_wrap,
- "on_save_delete_clicked" : self.on_save_delete_clicked,
- "on_moreTypes_treeview_files_row_activated" : self.populate_type_combo,
- "on_retry_button_files_clicked" : self.invalid_entry_retry,
- "on_make_path_recursive_toggled" : self.recursive_path,
- "on_files_path_entry_button_press_event" : self.highlight_entry_text,
- "on_files_path_entry_changed" : self.autofill_add_files_entry,
- "on_select_type_files_clicked" : self.select_type_more,
- "on_choose_file" : self.on_browse_select,
- "on_Enforcing_button_toggled" : self.set_enforce,
- "on_confirmation_close" : self.confirmation_close,
- "on_column_clicked" : self.column_clicked,
- "on_tab_switch" : self.clear_filters,
-
- "on_file_equiv_button_clicked" : self.show_file_equiv_page,
- "on_app/system_button_clicked" : self.system_interface,
- "on_app/users_button_clicked" : self.users_interface,
- "on_main_advanced_label_button_press_event": self.advanced_label_main,
-
- "on_Show_mislabeled_files_toggled" : self.show_mislabeled_files,
- "on_Browse_button_files_clicked" : self.browse_for_files,
- "on_cancel_popup_clicked" : self.close_popup,
- "on_treeview_cursor_changed" : self.cursor_changed,
- "on_login_seuser_combobox_changed" : self.login_seuser_combobox_change,
- "on_user_roles_combobox_changed":self.user_roles_combobox_change,
-
- "on_cancel_button_browse_clicked" : self.close_config_window,
- "on_apply_button_clicked" : self.apply_changes_button_press,
- "on_Revert_button_clicked" : self.update_or_revert_changes,
- "on_Update_button_clicked" : self.update_or_revert_changes,
- "on_advanced_filter_entry_changed" : self.get_advanced_filter_data,
- "on_advanced_search_treeview_row_activated" : self.advanced_item_selected,
- "on_Select_advanced_search_clicked" : self.advanced_item_button_push,
- "on_All_advanced_button_toggled" : self.advanced_radio_select,
- "on_Installed_advanced_button_toggled" : self.advanced_radio_select,
- "on_info_button_button_press_event" : self.on_help_button,
- "on_back_button_clicked" : self.on_help_back_clicked,
- "on_forward_button_clicked" : self.on_help_forward_clicked,
- "on_Boolean_treeview_columns_changed" : self.resize_columns,
- "on_completion_entry_changed" : self.application_selected,
- "on_Add_button_clicked" : self.add_button_clicked,
- "on_Delete_button_clicked" : self.delete_button_clicked,
- "on_Modify_button_clicked" : self.modify_button_clicked,
- "on_Show_modified_only_toggled" : self.on_show_modified_only,
- "on_cancel_button_config_clicked" : self.close_config_window,
- "on_Import_button_clicked" : self.import_config_show,
- "on_Export_button_clicked" : self.export_config_show,
- "on_enable_unconfined_toggled": self.unconfined_toggle,
- "on_enable_permissive_toggled": self.permissive_toggle,
- "on_system_policy_type_combobox_changed" : self.change_default_policy,
- "on_Enforcing_button_default_toggled" : self.change_default_mode,
- "on_Permissive_button_default_toggled" : self.change_default_mode,
- "on_Disabled_button_default_toggled" : self.change_default_mode,
-
- "on_Relabel_button_toggled_cb": self.relabel_on_reboot,
- "on_advanced_system_button_press_event" : self.reveal_advanced_system,
- "on_files_type_combobox_changed" : self.show_more_types,
- "on_filter_row_changed" : self.filter_the_data,
- "on_button_toggled" : self.tab_change,
- "gtk_main_quit": self.closewindow
- }
+ "on_combo_button_clicked": self.open_combo_menu,
+ "on_disable_ptrace_toggled": self.on_disable_ptrace,
+ "on_SELinux_window_configure_event": self.hide_combo_menu,
+ "on_entrycompletion_obj_match_selected": self.set_application_label,
+ "on_filter_changed": self.get_filter_data,
+ "on_save_changes_file_equiv_clicked": self.update_to_file_equiv,
+ "on_save_changes_login_clicked": self.update_to_login,
+ "on_save_changes_user_clicked": self.update_to_user,
+ "on_save_changes_files_clicked": self.update_to_files,
+ "on_save_changes_network_clicked": self.update_to_network,
+ "on_Advanced_text_files_button_press_event": self.reveal_advanced,
+ "item_in_tree_selected": self.cursor_changed,
+ "on_Application_file_types_treeview_configure_event": self.resize_wrap,
+ "on_save_delete_clicked": self.on_save_delete_clicked,
+ "on_moreTypes_treeview_files_row_activated": self.populate_type_combo,
+ "on_retry_button_files_clicked": self.invalid_entry_retry,
+ "on_make_path_recursive_toggled": self.recursive_path,
+ "on_files_path_entry_button_press_event": self.highlight_entry_text,
+ "on_files_path_entry_changed": self.autofill_add_files_entry,
+ "on_select_type_files_clicked": self.select_type_more,
+ "on_choose_file": self.on_browse_select,
+ "on_Enforcing_button_toggled": self.set_enforce,
+ "on_confirmation_close": self.confirmation_close,
+ "on_column_clicked": self.column_clicked,
+ "on_tab_switch": self.clear_filters,
+
+ "on_file_equiv_button_clicked": self.show_file_equiv_page,
+ "on_app/system_button_clicked": self.system_interface,
+ "on_app/users_button_clicked": self.users_interface,
+ "on_main_advanced_label_button_press_event": self.advanced_label_main,
+
+ "on_Show_mislabeled_files_toggled": self.show_mislabeled_files,
+ "on_Browse_button_files_clicked": self.browse_for_files,
+ "on_cancel_popup_clicked": self.close_popup,
+ "on_treeview_cursor_changed": self.cursor_changed,
+ "on_login_seuser_combobox_changed": self.login_seuser_combobox_change,
+ "on_user_roles_combobox_changed": self.user_roles_combobox_change,
+
+ "on_cancel_button_browse_clicked": self.close_config_window,
+ "on_apply_button_clicked": self.apply_changes_button_press,
+ "on_Revert_button_clicked": self.update_or_revert_changes,
+ "on_Update_button_clicked": self.update_or_revert_changes,
+ "on_advanced_filter_entry_changed": self.get_advanced_filter_data,
+ "on_advanced_search_treeview_row_activated": self.advanced_item_selected,
+ "on_Select_advanced_search_clicked": self.advanced_item_button_push,
+ "on_All_advanced_button_toggled": self.advanced_radio_select,
+ "on_Installed_advanced_button_toggled": self.advanced_radio_select,
+ "on_info_button_button_press_event": self.on_help_button,
+ "on_back_button_clicked": self.on_help_back_clicked,
+ "on_forward_button_clicked": self.on_help_forward_clicked,
+ "on_Boolean_treeview_columns_changed": self.resize_columns,
+ "on_completion_entry_changed": self.application_selected,
+ "on_Add_button_clicked": self.add_button_clicked,
+ "on_Delete_button_clicked": self.delete_button_clicked,
+ "on_Modify_button_clicked": self.modify_button_clicked,
+ "on_Show_modified_only_toggled": self.on_show_modified_only,
+ "on_cancel_button_config_clicked": self.close_config_window,
+ "on_Import_button_clicked": self.import_config_show,
+ "on_Export_button_clicked": self.export_config_show,
+ "on_enable_unconfined_toggled": self.unconfined_toggle,
+ "on_enable_permissive_toggled": self.permissive_toggle,
+ "on_system_policy_type_combobox_changed": self.change_default_policy,
+ "on_Enforcing_button_default_toggled": self.change_default_mode,
+ "on_Permissive_button_default_toggled": self.change_default_mode,
+ "on_Disabled_button_default_toggled": self.change_default_mode,
+
+ "on_Relabel_button_toggled_cb": self.relabel_on_reboot,
+ "on_advanced_system_button_press_event": self.reveal_advanced_system,
+ "on_files_type_combobox_changed": self.show_more_types,
+ "on_filter_row_changed": self.filter_the_data,
+ "on_button_toggled": self.tab_change,
+ "gtk_main_quit": self.closewindow
+ }
self.previously_modified_initialize(customized)
builder.connect_signals(dic)
self.window.show() # Show the gui to the screen
- GLib.timeout_add_seconds(5,self.selinux_status)
+ GLib.timeout_add_seconds(5, self.selinux_status)
self.selinux_status()
self.lockdown_inited = False
self.add_modify_delete_box.hide()
@@ -619,7 +623,7 @@ class SELinuxGui():
for k in keys:
self.cur_dict[k] = {}
- def remove_cur(self,ctr):
+ def remove_cur(self, ctr):
i = 0
for k in self.cur_dict:
for j in self.cur_dict[k]:
@@ -638,7 +642,7 @@ class SELinuxGui():
self.current_status_enforcing.set_sensitive(False)
self.current_status_permissive.set_sensitive(False)
self.enforcing_button_default.set_sensitive(False)
- self.status_bar.push(self.context_id, _("System Status: Disabled"))
+ self.status_bar.push(self.context_id, _("System Status: Disabled"))
self.info_text.set_label(DISABLED_TEXT)
else:
self.set_enforce_text(self.status)
@@ -670,7 +674,7 @@ class SELinuxGui():
mod = m.split()
if len(mod) < 2:
continue
- self.module_dict[mod[0]] = { "version": mod[1], "Disabled" : (len(mod) > 2) }
+ self.module_dict[mod[0]] = {"version": mod[1], "Disabled": (len(mod) > 2)}
self.enable_unconfined_button.set_active(not self.module_dict["unconfined"]["Disabled"])
self.enable_permissive_button.set_active(not self.module_dict["permissivedomains"]["Disabled"])
@@ -719,7 +723,7 @@ class SELinuxGui():
except IOError:
buf = ""
help_text = self.help_text.get_buffer()
- help_text.set_text(buf % { "APP": self.application })
+ help_text.set_text(buf % {"APP": self.application})
self.help_text.set_buffer(help_text)
self.help_image.set_from_file("%shelp/%s.png" % (self.code_path, self.help_list[self.help_page]))
self.show_popup(self.help_window)
@@ -737,70 +741,70 @@ class SELinuxGui():
self.help_list = []
if self.opage == START_PAGE:
self.help_window.set_title(_("Help: Start Page"))
- self.help_list = [ "start"]
+ self.help_list = ["start"]
if self.opage == BOOLEANS_PAGE:
self.help_window.set_title(_("Help: Booleans Page"))
- self.help_list = [ "booleans", "booleans_toggled", "booleans_more", "booleans_more_show"]
+ self.help_list = ["booleans", "booleans_toggled", "booleans_more", "booleans_more_show"]
if self.opage == FILES_PAGE:
ipage = self.inner_notebook_files.get_current_page()
if ipage == EXE_PAGE:
self.help_window.set_title(_("Help: Executable Files Page"))
- self.help_list = [ "files_exec" ]
+ self.help_list = ["files_exec"]
if ipage == WRITABLE_PAGE:
self.help_window.set_title(_("Help: Writable Files Page"))
- self.help_list = [ "files_write" ]
+ self.help_list = ["files_write"]
if ipage == APP_PAGE:
self.help_window.set_title(_("Help: Application Types Page"))
- self.help_list = [ "files_app" ]
+ self.help_list = ["files_app"]
if self.opage == NETWORK_PAGE:
ipage = self.inner_notebook_network.get_current_page()
if ipage == OUTBOUND_PAGE:
self.help_window.set_title(_("Help: Outbound Network Connections Page"))
- self.help_list = [ "ports_outbound" ]
+ self.help_list = ["ports_outbound"]
if ipage == INBOUND_PAGE:
self.help_window.set_title(_("Help: Inbound Network Connections Page"))
- self.help_list = [ "ports_inbound" ]
+ self.help_list = ["ports_inbound"]
if self.opage == TRANSITIONS_PAGE:
ipage = self.inner_notebook_transitions.get_current_page()
if ipage == TRANSITIONS_FROM_PAGE:
self.help_window.set_title(_("Help: Transition from application Page"))
- self.help_list = [ "transition_from", "transition_from_boolean", "transition_from_boolean_1", "transition_from_boolean_2"]
+ self.help_list = ["transition_from", "transition_from_boolean", "transition_from_boolean_1", "transition_from_boolean_2"]
if ipage == TRANSITIONS_TO_PAGE:
self.help_window.set_title(_("Help: Transition into application Page"))
- self.help_list = [ "transition_to" ]
+ self.help_list = ["transition_to"]
if ipage == TRANSITIONS_FILE_PAGE:
self.help_window.set_title(_("Help: Transition application file Page"))
- self.help_list = [ "transition_file" ]
+ self.help_list = ["transition_file"]
if self.opage == SYSTEM_PAGE:
- self.help_window.set_title(_("Help: Systems Page"))
- self.help_list = [ "system", "system_boot_mode", "system_current_mode", "system_export", "system_policy_type", "system_relabel" ]
+ self.help_window.set_title(_("Help: Systems Page"))
+ self.help_list = ["system", "system_boot_mode", "system_current_mode", "system_export", "system_policy_type", "system_relabel"]
if self.opage == LOCKDOWN_PAGE:
- self.help_window.set_title(_("Help: Lockdown Page"))
- self.help_list = [ "lockdown", "lockdown_unconfined", "lockdown_permissive", "lockdown_ptrace" ]
+ self.help_window.set_title(_("Help: Lockdown Page"))
+ self.help_list = ["lockdown", "lockdown_unconfined", "lockdown_permissive", "lockdown_ptrace"]
if self.opage == LOGIN_PAGE:
- self.help_window.set_title(_("Help: Login Page"))
- self.help_list = [ "login", "login_default" ]
+ self.help_window.set_title(_("Help: Login Page"))
+ self.help_list = ["login", "login_default"]
if self.opage == USER_PAGE:
- self.help_window.set_title(_("Help: SELinux User Page"))
- self.help_list = [ "users" ]
+ self.help_window.set_title(_("Help: SELinux User Page"))
+ self.help_list = ["users"]
if self.opage == FILE_EQUIV_PAGE:
- self.help_window.set_title(_("Help: File Equivalence Page"))
- self.help_list = [ "file_equiv"]
+ self.help_window.set_title(_("Help: File Equivalence Page"))
+ self.help_list = ["file_equiv"]
return self.help_show_page()
def open_combo_menu(self, *args):
if self.popup == 0:
self.popup = 1
location = self.window.get_position()
- self.main_selection_window.move(location[0]+2, location[1]+65)
+ self.main_selection_window.move(location[0] + 2, location[1] + 65)
self.main_selection_window.show()
else:
self.main_selection_window.hide()
@@ -827,7 +831,7 @@ class SELinuxGui():
def populate_system_policy(self):
selinux_path = selinux.selinux_path()
- types = map(lambda x: x[1], filter(lambda x: x[0]==selinux_path, os.walk(selinux_path)))[0]
+ types = map(lambda x: x[1], filter(lambda x: x[0] == selinux_path, os.walk(selinux_path)))[0]
types.sort()
ctr = 0
for item in types:
@@ -844,23 +848,23 @@ class SELinuxGui():
if self.filter_txt == "":
return True
try:
- for x in range(0,list.get_n_columns()):
+ for x in range(0, list.get_n_columns()):
try:
val = list.get_value(iter, x)
if val == True or val == False or val == None:
continue
# Returns true if filter_txt exists within the val
- if(val.find(self.filter_txt) != -1 or val.lower().find(self.filter_txt) != -1) :
+ if(val.find(self.filter_txt) != -1 or val.lower().find(self.filter_txt) != -1):
return True
except AttributeError, TypeError:
pass
- except: #ValueError:
+ except: # ValueError:
pass
return False
def net_update(self, app, netd, protocol, direction, model):
for k in netd.keys():
- for t,ports in netd[k]:
+ for t, ports in netd[k]:
pkey = (",".join(ports), protocol)
if pkey in self.cur_dict["port"]:
if self.cur_dict["port"][pkey]["action"] == "-d":
@@ -937,7 +941,7 @@ class SELinuxGui():
return
ctr += 1
- niter = liststore.get_iter(ctr-1)
+ niter = liststore.get_iter(ctr - 1)
if liststore.get_value(niter, 0) == _("More..."):
iter = liststore.insert_before(niter)
ctr = ctr - 1
@@ -1069,7 +1073,7 @@ class SELinuxGui():
def reinit(self):
sepolicy.reinit()
- self.fcdict=sepolicy.get_fcdict()
+ self.fcdict = sepolicy.get_fcdict()
self.local_file_paths = sepolicy.get_local_file_paths()
def previously_modified_initialize(self, buf):
@@ -1083,36 +1087,36 @@ class SELinuxGui():
if rec[0] not in self.cust_dict:
self.cust_dict[rec[0]] = {}
if rec[0] == "boolean":
- self.cust_dict["boolean"][rec[-1]] = { "active": rec[2] == "-1" }
+ self.cust_dict["boolean"][rec[-1]] = {"active": rec[2] == "-1"}
if rec[0] == "login":
- self.cust_dict["login"][rec[-1]] = { "seuser": rec[3], "range": rec[5] }
+ self.cust_dict["login"][rec[-1]] = {"seuser": rec[3], "range": rec[5]}
if rec[0] == "interface":
- self.cust_dict["interface"][rec[-1]] = { "type": rec[3] }
+ self.cust_dict["interface"][rec[-1]] = {"type": rec[3]}
if rec[0] == "user":
- self.cust_dict["user"][rec[-1]] = { "level": "s0", "range": rec[3], "role": rec[5] }
+ self.cust_dict["user"][rec[-1]] = {"level": "s0", "range": rec[3], "role": rec[5]}
if rec[0] == "port":
- self.cust_dict["port"][(rec[-1], rec[-2] )] = { "type": rec[3] }
+ self.cust_dict["port"][(rec[-1], rec[-2])] = {"type": rec[3]}
if rec[0] == "node":
- self.cust_dict["node"][rec[-1]] = { "mask": rec[3], "protocol":rec[5], "type": rec[7] }
+ self.cust_dict["node"][rec[-1]] = {"mask": rec[3], "protocol": rec[5], "type": rec[7]}
if rec[0] == "fcontext":
if rec[2] == "-e":
if "fcontext-equiv" not in self.cust_dict:
self.cust_dict["fcontext-equiv"] = {}
- self.cust_dict["fcontext-equiv"][(rec[-1])] = { "equiv": rec[3] }
+ self.cust_dict["fcontext-equiv"][(rec[-1])] = {"equiv": rec[3]}
else:
- self.cust_dict["fcontext"][(rec[-1],rec[3])] = { "type": rec[5] }
+ self.cust_dict["fcontext"][(rec[-1], rec[3])] = {"type": rec[5]}
if rec[0] == "module":
- self.cust_dict["module"][rec[-1]] = { "enabled": rec[2] != "-d" }
+ self.cust_dict["module"][rec[-1]] = {"enabled": rec[2] != "-d"}
if "module" not in self.cust_dict:
return
- for semodule, button in [ ("unconfined", self.disable_unconfined_button), ("permissivedomains", self.disable_permissive_button) ]:
+ for semodule, button in [("unconfined", self.disable_unconfined_button), ("permissivedomains", self.disable_permissive_button)]:
if semodule in self.cust_dict["module"]:
button.set_active(self.cust_dict["module"][semodule]["enabled"])
for i in keys:
if i not in self.cust_dict:
- self.cust_dict.update({i:{}})
+ self.cust_dict.update({i: {}})
def executable_files_initialize(self, application):
self.entrypoints = sepolicy.get_entrypoints(application)
@@ -1130,7 +1134,7 @@ class SELinuxGui():
def mislabeled(self, path):
try:
- con = selinux.matchpathcon(path,0)[1]
+ con = selinux.matchpathcon(path, 0)[1]
cur = selinux.getfilecon(path)[1]
return con != cur
except OSError:
@@ -1139,9 +1143,9 @@ class SELinuxGui():
def set_mislabeled(self, tree, path, iter, niter):
if not self.mislabeled(path):
return
- con = selinux.matchpathcon(path,0)[1]
+ con = selinux.matchpathcon(path, 0)[1]
cur = selinux.getfilecon(path)[1]
- self.mislabeled_files=True
+ self.mislabeled_files = True
# Set visibility of label
tree.set_value(niter, 3, True)
# Has a mislabel
@@ -1159,8 +1163,8 @@ class SELinuxGui():
continue
file_class = self.writable_files[write][1]
for path in self.writable_files[write][0]:
- if (path,file_class) in self.cur_dict["fcontext"]:
- if self.cur_dict["fcontext"][(path,file_class) ]["action"] == "-d":
+ if (path, file_class) in self.cur_dict["fcontext"]:
+ if self.cur_dict["fcontext"][(path, file_class)]["action"] == "-d":
continue
if write != self.cur_dict["fcontext"][(path, file_class)]["type"]:
continue
@@ -1172,7 +1176,7 @@ class SELinuxGui():
path = _("MISSING FILE PATH")
modify = False
else:
- modify = (path,file_class) in self.local_file_paths
+ modify = (path, file_class) in self.local_file_paths
for p in sepolicy.find_file(path):
niter = liststore.append(iter)
liststore.set_value(niter, 0, p)
@@ -1191,7 +1195,7 @@ class SELinuxGui():
def unmarkup(self, f):
if f:
- return re.sub("</b>$","", re.sub("^<b>","", f))
+ return re.sub("</b>$", "", re.sub("^<b>", "", f))
return None
def application_files_initialize(self, application):
@@ -1201,7 +1205,7 @@ class SELinuxGui():
continue
file_class = self.file_types[app][1]
for path in self.file_types[app][0]:
- desc = sepolicy.get_description(app, markup = self.markup)
+ desc = sepolicy.get_description(app, markup=self.markup)
if (path, file_class) in self.cur_dict["fcontext"]:
if self.cur_dict["fcontext"][(path, file_class)]["action"] == "-d":
continue
@@ -1222,7 +1226,7 @@ class SELinuxGui():
if b in self.cur_dict["boolean"]:
active = self.cur_dict["boolean"][b]['active']
desc = sepolicy.boolean_desc(b)
- self.boolean_initial_data_insert(b, desc , active)
+ self.boolean_initial_data_insert(b, desc, active)
def boolean_initial_data_insert(self, val, desc, active):
# Insert data from data source into tree
@@ -1350,9 +1354,9 @@ class SELinuxGui():
elif ipage == APP_PAGE:
self.treeview = self.application_files_treeview
category = _("application")
- self.add_button.set_tooltip_text(_("Add new %(TYPE)s file path for '%(DOMAIN)s' domains.") % { "TYPE": category, "DOMAIN": self.application})
- self.delete_button.set_tooltip_text(_("Delete %(TYPE)s file paths for '%(DOMAIN)s' domain.") % { "TYPE": category, "DOMAIN": self.application})
- self.modify_button.set_tooltip_text(_("Modify %(TYPE)s file path for '%(DOMAIN)s' domain. Only bolded items in the list can be selected, this indicates they were modified previously.") % { "TYPE": category, "DOMAIN": self.application})
+ self.add_button.set_tooltip_text(_("Add new %(TYPE)s file path for '%(DOMAIN)s' domains.") % {"TYPE": category, "DOMAIN": self.application})
+ self.delete_button.set_tooltip_text(_("Delete %(TYPE)s file paths for '%(DOMAIN)s' domain.") % {"TYPE": category, "DOMAIN": self.application})
+ self.modify_button.set_tooltip_text(_("Modify %(TYPE)s file path for '%(DOMAIN)s' domain. Only bolded items in the list can be selected, this indicates they were modified previously.") % {"TYPE": category, "DOMAIN": self.application})
if self.network_radio_button.get_active():
self.add_modify_delete_box.show()
@@ -1428,11 +1432,11 @@ class SELinuxGui():
self.treesort = self.treeview.get_model()
self.treefilter = self.treesort.get_model()
self.liststore = self.treefilter.get_model()
- for x in range(0,self.liststore.get_n_columns()):
+ for x in range(0, self.liststore.get_n_columns()):
col = self.treeview.get_column(x)
if col:
cell = col.get_cells()[0]
- if isinstance(cell,Gtk.CellRendererText):
+ if isinstance(cell, Gtk.CellRendererText):
self.liststore.set_sort_func(x, self.stripsort, None)
self.treeview.get_selection().unselect_all()
self.modify_button.set_sensitive(False)
@@ -1441,7 +1445,7 @@ class SELinuxGui():
sort_column, _ = model.get_sort_column_id()
val1 = self.unmarkup(model.get_value(row1, sort_column))
val2 = self.unmarkup(model.get_value(row2, sort_column))
- return cmp(val1,val2)
+ return cmp(val1, val2)
def display_more_detail(self, windows, path):
it = self.boolean_filter.get_iter(path)
@@ -1449,7 +1453,7 @@ class SELinuxGui():
self.boolean_more_detail_tree_data_set.clear()
self.boolean_more_detail_window.set_title(_("Boolean %s Allow Rules") % self.boolean_liststore.get_value(it, 2))
- blist = sepolicy.get_boolean_rules(self.application,self.boolean_liststore.get_value(it, 2));
+ blist = sepolicy.get_boolean_rules(self.application, self.boolean_liststore.get_value(it, 2))
for b in blist:
self.display_more_detail_init(b["source"], b["target"], b["class"], b["permlist"])
self.show_popup(self.boolean_more_detail_window)
@@ -1461,14 +1465,14 @@ class SELinuxGui():
def add_button_clicked(self, *args):
self.modify = False
if self.opage == NETWORK_PAGE:
- self.popup_network_label.set_text((_("Add Network Port for %s. Ports will be created when update is applied."))% self.application)
- self.network_popup_window.set_title((_("Add Network Port for %s"))% self.application)
+ self.popup_network_label.set_text((_("Add Network Port for %s. Ports will be created when update is applied.")) % self.application)
+ self.network_popup_window.set_title((_("Add Network Port for %s")) % self.application)
self.init_network_dialog(args)
return
if self.opage == FILES_PAGE:
- self.popup_files_label.set_text((_("Add File Labeling for %s. File labels will be created when update is applied."))% self.application)
- self.files_popup_window.set_title((_("Add File Labeling for %s"))% self.application)
+ self.popup_files_label.set_text((_("Add File Labeling for %s. File labels will be created when update is applied.")) % self.application)
+ self.files_popup_window.set_title((_("Add File Labeling for %s")) % self.application)
self.init_files_dialog(args)
ipage = self.inner_notebook_files.get_current_page()
if ipage == EXE_PAGE:
@@ -1520,8 +1524,8 @@ class SELinuxGui():
self.modify_button_network_clicked(args)
if self.opage == FILES_PAGE:
- self.popup_files_label.set_text((_("Modify File Labeling for %s. File labels will be created when update is applied."))% self.application)
- self.files_popup_window.set_title((_("Add File Labeling for %s"))% self.application)
+ self.popup_files_label.set_text((_("Modify File Labeling for %s. File labels will be created when update is applied.")) % self.application)
+ self.files_popup_window.set_title((_("Add File Labeling for %s")) % self.application)
self.delete_old_item = None
self.init_files_dialog(args)
self.modify = True
@@ -1572,26 +1576,26 @@ class SELinuxGui():
if self.opage == USER_PAGE:
self.user_init_dialog(args)
- self.user_name_entry.set_text(self.user_liststore.get_value(iter,0))
- self.user_mls_level_entry.set_text(self.user_liststore.get_value(iter,2))
- self.user_mls_entry.set_text(self.user_liststore.get_value(iter,3))
- self.combo_set_active_text(self.user_roles_combobox, self.user_liststore.get_value(iter,1))
+ self.user_name_entry.set_text(self.user_liststore.get_value(iter, 0))
+ self.user_mls_level_entry.set_text(self.user_liststore.get_value(iter, 2))
+ self.user_mls_entry.set_text(self.user_liststore.get_value(iter, 3))
+ self.combo_set_active_text(self.user_roles_combobox, self.user_liststore.get_value(iter, 1))
self.user_label.set_text((_("Modify SELinux User Role. SELinux user roles will be modified when update is applied.")))
self.user_popup_window.set_title(_("Modify SELinux Users"))
self.show_popup(self.user_popup_window)
if self.opage == LOGIN_PAGE:
self.login_init_dialog(args)
- self.login_name_entry.set_text(self.login_liststore.get_value(iter,0))
- self.login_mls_entry.set_text(self.login_liststore.get_value(iter,2))
- self.combo_set_active_text(self.login_seuser_combobox, self.login_liststore.get_value(iter,1))
+ self.login_name_entry.set_text(self.login_liststore.get_value(iter, 0))
+ self.login_mls_entry.set_text(self.login_liststore.get_value(iter, 2))
+ self.combo_set_active_text(self.login_seuser_combobox, self.login_liststore.get_value(iter, 1))
self.login_label.set_text((_("Modify Login Mapping. Login Mapping will be modified when Update is applied.")))
self.login_popup_window.set_title(_("Modify Login Mapping"))
self.show_popup(self.login_popup_window)
if self.opage == FILE_EQUIV_PAGE:
- self.file_equiv_source_entry.set_text(self.file_equiv_liststore.get_value(iter,0))
- self.file_equiv_dest_entry.set_text(self.file_equiv_liststore.get_value(iter,1))
+ self.file_equiv_source_entry.set_text(self.file_equiv_liststore.get_value(iter, 0))
+ self.file_equiv_dest_entry.set_text(self.file_equiv_liststore.get_value(iter, 1))
self.file_equiv_label.set_text((_("Modify File Equivalency Mapping. Mapping will be created when update is applied.")))
self.file_equiv_popup_window.set_title(_("Modify SELinux File Equivalency"))
self.clear_entry = True
@@ -1608,9 +1612,9 @@ class SELinuxGui():
if domain == None:
return
if domain.endswith("_script_t"):
- split_char="_script_t"
+ split_char = "_script_t"
else:
- split_char="_t"
+ split_char = "_t"
return domain.split(split_char)[0]
def exclude_type(self, type, exclude_list):
@@ -1678,8 +1682,8 @@ class SELinuxGui():
self.modify_button.set_sensitive(False)
return
- self.popup_network_label.set_text((_("Modify Network Port for %s. Ports will be created when update is applied."))% self.application)
- self.network_popup_window.set_title((_("Modify Network Port for %s"))% self.application)
+ self.popup_network_label.set_text((_("Modify Network Port for %s. Ports will be created when update is applied.")) % self.application)
+ self.network_popup_window.set_title((_("Modify Network Port for %s")) % self.application)
self.delete_old_item = None
self.init_network_dialog(args)
operation = "Modify"
@@ -1713,7 +1717,7 @@ class SELinuxGui():
port_types = []
for k in netd.keys():
- for t,ports in netd[k]:
+ for t, ports in netd[k]:
if t not in port_types + ["port_t", "unreserved_port_t"]:
if t.endswith("_type"):
continue
@@ -1813,9 +1817,10 @@ class SELinuxGui():
def on_show_modified_only(self, checkbutton):
length = self.liststore.get_n_columns()
+
def dup_row(row):
l = []
- for i in range(0,length):
+ for i in range(0, length):
l.append(row[i])
return l
@@ -1838,7 +1843,7 @@ class SELinuxGui():
if ipage == APP_PAGE:
return self.application_files_initialize(self.application)
for row in self.liststore:
- if (row[0],row[2]) in self.cust_dict["fcontext"]:
+ if (row[0], row[2]) in self.cust_dict["fcontext"]:
append_list.append(row)
if self.opage == NETWORK_PAGE:
@@ -1875,7 +1880,7 @@ class SELinuxGui():
self.liststore.clear()
for row in append_list:
iter = self.liststore.append()
- for i in range(0,length):
+ for i in range(0, length):
self.liststore.set_value(iter, i, row[i])
def init_modified_files_liststore(self, tree, app, ipage, operation, path, fclass, ftype):
@@ -1927,20 +1932,20 @@ class SELinuxGui():
name = self.login_name_entry.get_text()
if self.modify:
iter = self.get_selected_iter()
- oldname = self.login_liststore.get_value(iter,0)
- oldseuser = self.login_liststore.get_value(iter,1)
- oldrange = self.login_liststore.get_value(iter,2)
- self.liststore.set_value(iter,0,oldname)
- self.liststore.set_value(iter,1,oldseuser)
- self.liststore.set_value(iter,2,oldrange)
- self.cur_dict["login"][name] = { "action": "-m", "range": mls_range, "seuser": seuser, "oldrange": oldrange, "oldseuser": oldseuser, "oldname": oldname }
+ oldname = self.login_liststore.get_value(iter, 0)
+ oldseuser = self.login_liststore.get_value(iter, 1)
+ oldrange = self.login_liststore.get_value(iter, 2)
+ self.liststore.set_value(iter, 0, oldname)
+ self.liststore.set_value(iter, 1, oldseuser)
+ self.liststore.set_value(iter, 2, oldrange)
+ self.cur_dict["login"][name] = {"action": "-m", "range": mls_range, "seuser": seuser, "oldrange": oldrange, "oldseuser": oldseuser, "oldname": oldname}
else:
iter = self.liststore.append(None)
- self.cur_dict["login"][name] = { "action": "-a", "range": mls_range, "seuser": seuser }
+ self.cur_dict["login"][name] = {"action": "-a", "range": mls_range, "seuser": seuser}
- self.liststore.set_value(iter,0,name)
- self.liststore.set_value(iter,1,seuser)
- self.liststore.set_value(iter,2, mls_range)
+ self.liststore.set_value(iter, 0, name)
+ self.liststore.set_value(iter, 1, seuser)
+ self.liststore.set_value(iter, 2, mls_range)
self.new_updates()
@@ -1952,18 +1957,18 @@ class SELinuxGui():
name = self.user_name_entry.get_text()
if self.modify:
iter = self.get_selected_iter()
- oldname = self.user_liststore.get_value(iter,0)
- oldroles = self.user_liststore.get_value(iter,1)
- oldlevel = self.user_liststore.get_value(iter,1)
- oldrange = self.user_liststore.get_value(iter,3)
- self.liststore.set_value(iter,0,oldname)
- self.liststore.set_value(iter,1,oldroles)
- self.liststore.set_value(iter,2,oldlevel)
- self.liststore.set_value(iter,3,oldrange)
- self.cur_dict["user"][name] = { "action": "-m", "range": mls_range, "level": level, "role":roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname }
+ oldname = self.user_liststore.get_value(iter, 0)
+ oldroles = self.user_liststore.get_value(iter, 1)
+ oldlevel = self.user_liststore.get_value(iter, 1)
+ oldrange = self.user_liststore.get_value(iter, 3)
+ self.liststore.set_value(iter, 0, oldname)
+ self.liststore.set_value(iter, 1, oldroles)
+ self.liststore.set_value(iter, 2, oldlevel)
+ self.liststore.set_value(iter, 3, oldrange)
+ self.cur_dict["user"][name] = {"action": "-m", "range": mls_range, "level": level, "role": roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname}
else:
iter = self.liststore.append(None)
- self.cur_dict["user"][name] = { "action": "-a", "range": mls_range, "level": level, "role": roles}
+ self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles}
self.liststore.set_value(iter, 0, name)
self.liststore.set_value(iter, 1, roles)
@@ -1978,14 +1983,14 @@ class SELinuxGui():
src = self.file_equiv_source_entry.get_text()
if self.modify:
iter = self.get_selected_iter()
- olddest = self.unmarkup(self.liststore.set_value(iter,0))
- oldsrc = self.unmarkup(self.liststore.set_value(iter,1))
- self.cur_dict["fcontext-equiv"][dest] = { "action": "-m", "src": src, "oldsrc": oldsrc, "olddest": olddest }
+ olddest = self.unmarkup(self.liststore.set_value(iter, 0))
+ oldsrc = self.unmarkup(self.liststore.set_value(iter, 1))
+ self.cur_dict["fcontext-equiv"][dest] = {"action": "-m", "src": src, "oldsrc": oldsrc, "olddest": olddest}
else:
iter = self.liststore.append(None)
- self.cur_dict["fcontext-equiv"][dest] = { "action": "-a", "src": src }
- self.liststore.set_value(iter,0,self.markup(dest))
- self.liststore.set_value(iter,1,self.markup(src))
+ self.cur_dict["fcontext-equiv"][dest] = {"action": "-a", "src": src}
+ self.liststore.set_value(iter, 0, self.markup(dest))
+ self.liststore.set_value(iter, 1, self.markup(src))
def update_to_files(self, *args):
self.close_popup()
@@ -2004,10 +2009,10 @@ class SELinuxGui():
oldpath = self.unmark(self.liststore.get_value(iter, 0))
setype = self.unmark(self.liststore.set_value(iter, 1))
oldtclass = self.liststore.get_value(iter, 2)
- self.cur_dict["fcontext"][(path, tclass)] = { "action": "-m", "type": setype, "oldtype": oldsetype, "oldmls": oldmls, "oldclass": oldclass }
+ self.cur_dict["fcontext"][(path, tclass)] = {"action": "-m", "type": setype, "oldtype": oldsetype, "oldmls": oldmls, "oldclass": oldclass}
else:
iter = self.liststore.append(None)
- self.cur_dict["fcontext"][(path, tclass)] = { "action": "-a", "type": setype }
+ self.cur_dict["fcontext"][(path, tclass)] = {"action": "-a", "type": setype}
self.liststore.set_value(iter, 0, self.markup(path))
self.liststore.set_value(iter, 1, self.markup(setype))
self.liststore.set_value(iter, 2, self.markup(tclass))
@@ -2034,10 +2039,10 @@ class SELinuxGui():
oldports = self.unmark(self.liststore.get_value(iter, 0))
oldprotocol = self.unmark(self.liststore.get_value(iter, 1))
oldsetype = self.unmark(self.liststore.set_value(iter, 2))
- self.cur_dict["port"][(ports, protocol)] = { "action": "-m", "type": setype, "mls": mls, "oldtype": oldsetype, "oldmls": oldmls, "oldprotocol": oldprotocol, "oldports": oldports }
+ self.cur_dict["port"][(ports, protocol)] = {"action": "-m", "type": setype, "mls": mls, "oldtype": oldsetype, "oldmls": oldmls, "oldprotocol": oldprotocol, "oldports": oldports}
else:
iter = self.liststore.append(None)
- self.cur_dict["port"][(ports, protocol)] = { "action": "-a", "type": setype, "mls": mls}
+ self.cur_dict["port"][(ports, protocol)] = {"action": "-a", "type": setype, "mls": mls}
self.liststore.set_value(iter, 0, ports)
self.liststore.set_value(iter, 1, protocol)
self.liststore.set_value(iter, 2, setype)
@@ -2053,7 +2058,7 @@ class SELinuxGui():
if self.opage == NETWORK_PAGE:
self.network_delete_liststore.clear()
port_dict = self.cust_dict["port"]
- for ports,protocol in port_dict:
+ for ports, protocol in port_dict:
setype = port_dict[(ports, protocol)]["type"]
iter = self.network_delete_liststore.append()
self.network_delete_liststore.set_value(iter, 1, ports)
@@ -2065,7 +2070,7 @@ class SELinuxGui():
if self.opage == FILES_PAGE:
self.files_delete_liststore.clear()
fcontext_dict = self.cust_dict["fcontext"]
- for path,tclass in fcontext_dict:
+ for path, tclass in fcontext_dict:
setype = fcontext_dict[(path, tclass)]["type"]
iter = self.files_delete_liststore.append()
self.files_delete_liststore.set_value(iter, 1, path)
@@ -2117,23 +2122,23 @@ class SELinuxGui():
if self.opage == NETWORK_PAGE:
for delete in self.network_delete_liststore:
if delete[0]:
- self.cur_dict["port"][(delete[1], delete[2])] = { "action": "-d", "type": delete[3] }
+ self.cur_dict["port"][(delete[1], delete[2])] = {"action": "-d", "type": delete[3]}
if self.opage == FILES_PAGE:
for delete in self.files_delete_liststore:
if delete[0]:
- self.cur_dict["fcontext"][(delete[1], reverse_file_type_str[delete[3]])] = { "action": "-d", "type": delete[2] }
+ self.cur_dict["fcontext"][(delete[1], reverse_file_type_str[delete[3]])] = {"action": "-d", "type": delete[2]}
if self.opage == USER_PAGE:
for delete in self.user_delete_liststore:
if delete[0]:
- self.cur_dict["user"][delete[1]] = { "action": "-d" , "role": delete[2], "range": delete[4] }
+ self.cur_dict["user"][delete[1]] = {"action": "-d", "role": delete[2], "range": delete[4]}
if self.opage == LOGIN_PAGE:
for delete in self.login_delete_liststore:
if delete[0]:
- self.cur_dict["login"][delete[2]] = { "action": "-d", "login":delete[2], "seuser":delete[1], "range":delete[3] }
+ self.cur_dict["login"][delete[2]] = {"action": "-d", "login": delete[2], "seuser": delete[1], "range": delete[3]}
if self.opage == FILE_EQUIV_PAGE:
for delete in self.file_equiv_delete_liststore:
if delete[0]:
- self.cur_dict["fcontext-equiv"][delete[1]] = { "action": "-d", "src" : delete[2] }
+ self.cur_dict["fcontext-equiv"][delete[1]] = {"action": "-d", "src": delete[2]}
self.new_updates()
def on_save_delete_file_equiv_clicked(self, *args):
@@ -2150,7 +2155,7 @@ class SELinuxGui():
iter = liststore.get_iter(ctr)
liststore.remove(iter)
return
- ctr+=1
+ ctr += 1
def on_toggle(self, cell, path, model):
if not path:
@@ -2163,7 +2168,7 @@ class SELinuxGui():
if name in self.cur_dict["boolean"]:
del(self.cur_dict["boolean"][name])
else:
- self.cur_dict["boolean"][name] = {"active":active}
+ self.cur_dict["boolean"][name] = {"active": active}
self.new_updates()
def get_advanced_filter_data(self, entry, *args):
@@ -2183,60 +2188,60 @@ class SELinuxGui():
operation = self.cur_dict["boolean"][bools]["action"]
iter = self.update_treestore.append(None)
self.update_treestore.set_value(iter, 0, True)
- self.update_treestore.set_value(iter, 1, sepolicy.boolean_desc(bools))
+ self.update_treestore.set_value(iter, 1, sepolicy.boolean_desc(bools))
self.update_treestore.set_value(iter, 2, action[self.cur_dict["boolean"][bools]['active']])
self.update_treestore.set_value(iter, 3, True)
niter = self.update_treestore.append(iter)
- self.update_treestore.set_value(niter, 1, (_("SELinux name: %s"))% bools)
+ self.update_treestore.set_value(niter, 1, (_("SELinux name: %s")) % bools)
self.update_treestore.set_value(niter, 3, False)
- for path,tclass in self.cur_dict["fcontext"]:
- operation = self.cur_dict["fcontext"][(path,tclass)]["action"]
- setype = self.cur_dict["fcontext"][(path,tclass)]["type"]
+ for path, tclass in self.cur_dict["fcontext"]:
+ operation = self.cur_dict["fcontext"][(path, tclass)]["action"]
+ setype = self.cur_dict["fcontext"][(path, tclass)]["type"]
iter = self.update_treestore.append(None)
self.update_treestore.set_value(iter, 0, True)
self.update_treestore.set_value(iter, 2, operation)
self.update_treestore.set_value(iter, 0, True)
if operation == "-a":
- self.update_treestore.set_value(iter, 1, (_("Add file labeling for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Add file labeling for %s")) % self.application)
if operation == "-d":
- self.update_treestore.set_value(iter, 1, (_("Delete file labeling for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Delete file labeling for %s")) % self.application)
if operation == "-m":
- self.update_treestore.set_value(iter, 1, (_("Modify file labeling for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Modify file labeling for %s")) % self.application)
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("File path: %s"))% path)
+ self.update_treestore.set_value(niter, 1, (_("File path: %s")) % path)
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("File class: %s"))% sepolicy.file_type_str[tclass])
+ self.update_treestore.set_value(niter, 1, (_("File class: %s")) % sepolicy.file_type_str[tclass])
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s"))% setype)
+ self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s")) % setype)
- for port,protocol in self.cur_dict["port"]:
- operation = self.cur_dict["port"][(port,protocol)]["action"]
+ for port, protocol in self.cur_dict["port"]:
+ operation = self.cur_dict["port"][(port, protocol)]["action"]
iter = self.update_treestore.append(None)
self.update_treestore.set_value(iter, 0, True)
self.update_treestore.set_value(iter, 2, operation)
self.update_treestore.set_value(iter, 3, True)
if operation == "-a":
- self.update_treestore.set_value(iter, 1, (_("Add ports for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Add ports for %s")) % self.application)
if operation == "-d":
- self.update_treestore.set_value(iter, 1, (_("Delete ports for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Delete ports for %s")) % self.application)
if operation == "-m":
- self.update_treestore.set_value(iter, 1, (_("Modify ports for %s"))% self.application)
+ self.update_treestore.set_value(iter, 1, (_("Modify ports for %s")) % self.application)
niter = self.update_treestore.append(iter)
- self.update_treestore.set_value(niter, 1, (_("Network ports: %s"))% port)
+ self.update_treestore.set_value(niter, 1, (_("Network ports: %s")) % port)
self.update_treestore.set_value(niter, 3, False)
niter = self.update_treestore.append(iter)
- self.update_treestore.set_value(niter, 1, (_("Network protocol: %s"))% protocol)
+ self.update_treestore.set_value(niter, 1, (_("Network protocol: %s")) % protocol)
self.update_treestore.set_value(niter, 3, False)
setype = self.cur_dict["port"][(port, protocol)]["type"]
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s"))% setype)
+ self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s")) % setype)
for user in self.cur_dict["user"]:
operation = self.cur_dict["user"][user]["action"]
@@ -2252,7 +2257,7 @@ class SELinuxGui():
self.update_treestore.set_value(iter, 1, _("Modify user"))
niter = self.update_treestore.append(iter)
- self.update_treestore.set_value(niter, 1, (_("SELinux User : %s"))% user)
+ self.update_treestore.set_value(niter, 1, (_("SELinux User : %s")) % user)
self.update_treestore.set_value(niter, 3, False)
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
@@ -2278,7 +2283,7 @@ class SELinuxGui():
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("Login Name : %s"))% login)
+ self.update_treestore.set_value(niter, 1, (_("Login Name : %s")) % login)
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
seuser = self.cur_dict["login"][login]["seuser"]
@@ -2303,7 +2308,7 @@ class SELinuxGui():
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
- self.update_treestore.set_value(niter, 1, (_("File path : %s"))% path)
+ self.update_treestore.set_value(niter, 1, (_("File path : %s")) % path)
niter = self.update_treestore.append(iter)
self.update_treestore.set_value(niter, 3, False)
src = self.cur_dict["fcontext-equiv"][path]["src"]
@@ -2394,7 +2399,7 @@ class SELinuxGui():
if iter != None:
if self.liststore.get_value(iter, 4) == False:
iterlist.append(iter)
- ctr +=1
+ ctr += 1
for iters in iterlist:
self.liststore.remove(iters)
@@ -2409,8 +2414,8 @@ class SELinuxGui():
def fix_mislabeled(self, path):
cur = selinux.getfilecon(path)[1].split(":")[2]
- con = selinux.matchpathcon(path,0)[1].split(":")[2]
- if self.verify(_("Run restorecon on %(PATH)s to change its type from %(CUR_CONTEXT)s to the default %(DEF_CONTEXT)s?") % {"PATH":path, "CUR_CONTEXT": cur, "DEF_CONTEXT": con}, title="restorecon dialog") == Gtk.ResponseType.YES:
+ con = selinux.matchpathcon(path, 0)[1].split(":")[2]
+ if self.verify(_("Run restorecon on %(PATH)s to change its type from %(CUR_CONTEXT)s to the default %(DEF_CONTEXT)s?") % {"PATH": path, "CUR_CONTEXT": cur, "DEF_CONTEXT": con}, title="restorecon dialog") == Gtk.ResponseType.YES:
self.dbus.restorecon(path)
self.application_selected()
@@ -2511,8 +2516,8 @@ class SELinuxGui():
def revert_data(self):
ctr = 0
- remove_list=[]
- update_buffer = ""
+ remove_list = []
+ update_buffer = ""
for items in self.update_treestore:
if not self.update_treestore[ctr][0]:
remove_list.append(ctr)
@@ -2562,7 +2567,7 @@ class SELinuxGui():
# From entry_point = 0 to the number of keys in the dic
for exe in entrypoints:
if len(entrypoints[exe]):
- file_class = entrypoints[exe][1]
+ file_class = entrypoints[exe][1]
for path in entrypoints[exe][0]:
iter = self.advanced_search_liststore.append()
self.advanced_search_liststore.set_value(iter, 1, domain)
@@ -2597,7 +2602,7 @@ class SELinuxGui():
def set_enforce_text(self, value):
if value:
- self.status_bar.push(self.context_id, _("System Status: Enforcing"))
+ self.status_bar.push(self.context_id, _("System Status: Enforcing"))
else:
self.status_bar.push(self.context_id, _("System Status: Permissive"))
self.current_status_permissive.set_active(True)
@@ -2622,7 +2627,7 @@ class SELinuxGui():
path = self.files_path_entry.get_text()
if self.recursive_path_toggle.get_active():
if not path.endswith("(/.*)?"):
- self.files_path_entry.set_text(path+"(/.*)?")
+ self.files_path_entry.set_text(path + "(/.*)?")
elif path.endswith("(/.*)?"):
path = path.split("(/.*)?")[0]
self.files_path_entry.set_text(path)
@@ -2709,9 +2714,9 @@ class SELinuxGui():
def init_dictionary(self, dic, app, ipage, operation, p, q, ftype, mls, changed, old):
if (app, ipage, operation) not in dic:
- dic[app, ipage, operation] = {}
+ dic[app, ipage, operation] = {}
if (p, q) not in dic[app, ipage, operation]:
- dic[app, ipage, operation][p, q] = {'type': ftype, 'mls': mls, 'changed': changed, 'old': old}
+ dic[app, ipage, operation][p, q] = {'type': ftype, 'mls': mls, 'changed': changed, 'old': old}
def translate_bool(self, b):
b = b.split('-')[1]
@@ -2765,7 +2770,7 @@ class SELinuxGui():
self.window.get_window().set_cursor(self.ready_cursor)
self.idle_func()
- def verify(self, message, title="" ):
+ def verify(self, message, title=""):
dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
Gtk.ButtonsType.YES_NO,
message)
diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
index bbabb3b0..69078b0a 100644
--- a/policycoreutils/sepolicy/sepolicy/interface.py
+++ b/policycoreutils/sepolicy/sepolicy/interface.py
@@ -21,17 +21,18 @@
# 02111-1307 USA
#
#
-import re, sys
+import re
+import sys
import sepolicy
ADMIN_TRANSITION_INTERFACE = "_admin$"
USER_TRANSITION_INTERFACE = "_role$"
-__all__ = [ 'get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user' ,'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test' ]
+__all__ = ['get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user', 'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test']
##
## I18N
##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -40,11 +41,12 @@ try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
unicode=False,
- codeset = 'utf-8')
+ codeset='utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
+
def get_interfaces_from_xml(path):
""" Get all interfaces from given xml file"""
interfaces_list = []
@@ -65,6 +67,7 @@ def get_all_interfaces(path=""):
return all_interfaces
+
def get_admin(path=""):
""" Get all domains with an admin interface from installed policy."""
""" If xml_path is specified, func returns an admin interface from specified xml file"""
@@ -86,6 +89,7 @@ def get_admin(path=""):
return admin_list
+
def get_user(path=""):
""" Get all domains with SELinux user role interface"""
""" If xml_path is specified, func returns an user role interface from specified xml file"""
@@ -111,6 +115,8 @@ def get_user(path=""):
return trans_list
interface_dict = None
+
+
def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
global interface_dict
import os
@@ -126,7 +132,7 @@ def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
<layer name="admin">
"""
xml_path += path
- xml_path +="""
+ xml_path += """
</layer>
</policy>
"""
@@ -141,23 +147,25 @@ def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
for i in m.getiterator('interface'):
for e in i.findall("param"):
param_list.append(e.get('name'))
- interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"interface"]
+ interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "interface"]
param_list = []
for i in m.getiterator('template'):
for e in i.findall("param"):
param_list.append(e.get('name'))
- interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"template"]
+ interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "template"]
param_list = []
except IOError, e:
pass
return interface_dict
-def get_interface_format_text(interface,path = "/usr/share/selinux/devel/policy.xml"):
+
+def get_interface_format_text(interface, path="/usr/share/selinux/devel/policy.xml"):
idict = get_interface_dict(path)
interface_text = "%s(%s) %s" % (interface, ", ".join(idict[interface][0]), " ".join(idict[interface][1].split("\n")))
return interface_text
+
def get_interface_compile_format_text(interfaces_dict, interface):
from templates import test_module
param_tmp = []
@@ -167,20 +175,23 @@ def get_interface_compile_format_text(interfaces_dict, interface):
return interface_text
+
def generate_compile_te(interface, idict, name="compiletest"):
from templates import test_module
te = ""
- te += re.sub("TEMPLATETYPE", name, test_module.te_test_module )
- te += get_interface_compile_format_text(idict,interface)
+ te += re.sub("TEMPLATETYPE", name, test_module.te_test_module)
+ te += get_interface_compile_format_text(idict, interface)
return te
+
def get_xml_file(if_file):
""" Returns xml format of interfaces for given .if policy file"""
- import os, commands
- basedir = os.path.dirname(if_file)+"/"
+ import os
+ import commands
+ basedir = os.path.dirname(if_file) + "/"
filename = os.path.basename(if_file).split(".")[0]
- rc, output=commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir+filename)
+ rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
if rc != 0:
sys.stderr.write("\n Could not proceed selected interface file.\n")
sys.stderr.write("\n%s" % output)
@@ -188,12 +199,14 @@ def get_xml_file(if_file):
else:
return output
-def interface_compile_test(interface, path = "/usr/share/selinux/devel/policy.xml"):
- exclude_interfaces = ["userdom","kernel","corenet","files", "dev"]
+
+def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"):
+ exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
exclude_interface_type = ["template"]
- import commands, os
- policy_files = {'pp':"compiletest.pp", 'te':"compiletest.te", 'fc':"compiletest.fc", 'if':"compiletest.if"}
+ import commands
+ import os
+ policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
idict = get_interface_dict(path)
if not (interface.split("_")[0] in exclude_interfaces or idict[interface][2] in exclude_interface_type):
@@ -202,7 +215,7 @@ def interface_compile_test(interface, path = "/usr/share/selinux/devel/policy.xm
fd = open(policy_files['te'], "w")
fd.write(generate_compile_te(interface, idict))
fd.close()
- rc, output=commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'] )
+ rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
if rc != 0:
sys.stderr.write(output)
sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
index ba15b2c3..7de2f80d 100755
--- a/policycoreutils/sepolicy/sepolicy/manpage.py
+++ b/policycoreutils/sepolicy/sepolicy/manpage.py
@@ -22,7 +22,7 @@
# 02111-1307 USA
#
#
-__all__ = [ 'ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_domains' ]
+__all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_domains']
import string
import argparse
@@ -31,176 +31,193 @@ import sepolicy
from sepolicy import *
import commands
-import sys, os, re, time
+import sys
+import os
+import re
+import time
-equiv_dict={ "smbd" : [ "samba" ], "httpd" : [ "apache" ], "virtd" : [ "virt", "libvirt", "svirt", "svirt_tcg", "svirt_lxc_t", "svirt_lxc_net_t" ], "named" : [ "bind" ], "fsdaemon" : [ "smartmon" ], "mdadm" : [ "raid" ] }
+equiv_dict = {"smbd": ["samba"], "httpd": ["apache"], "virtd": ["virt", "libvirt", "svirt", "svirt_tcg", "svirt_lxc_t", "svirt_lxc_net_t"], "named": ["bind"], "fsdaemon": ["smartmon"], "mdadm": ["raid"]}
-equiv_dirs=[ "/var" ]
+equiv_dirs = ["/var"]
modules_dict = None
-def gen_modules_dict(path = "/usr/share/selinux/devel/policy.xml"):
- global modules_dict
- if modules_dict:
- return modules_dict
-
- import xml.etree.ElementTree
- modules_dict = {}
- try:
- tree = xml.etree.ElementTree.fromstring(policy_xml(path))
- for l in tree.findall("layer"):
- for m in l.findall("module"):
- name = m.get("name")
- if name == "user" or name == "unconfined":
- continue
- if name == "unprivuser":
- name = "user"
- if name == "unconfineduser":
- name = "unconfined"
- for b in m.findall("summary"):
- modules_dict[name] = b.text
- except IOError, e:
- pass
- return modules_dict
+
+
+def gen_modules_dict(path="/usr/share/selinux/devel/policy.xml"):
+ global modules_dict
+ if modules_dict:
+ return modules_dict
+
+ import xml.etree.ElementTree
+ modules_dict = {}
+ try:
+ tree = xml.etree.ElementTree.fromstring(policy_xml(path))
+ for l in tree.findall("layer"):
+ for m in l.findall("module"):
+ name = m.get("name")
+ if name == "user" or name == "unconfined":
+ continue
+ if name == "unprivuser":
+ name = "user"
+ if name == "unconfineduser":
+ name = "unconfined"
+ for b in m.findall("summary"):
+ modules_dict[name] = b.text
+ except IOError, e:
+ pass
+ return modules_dict
users = None
users_range = None
+
+
def get_all_users_info():
- global users
- global users_range
- if users and users_range:
- return users, users_range
-
- users = []
- users_range ={}
- allusers = []
- allusers_info = info(USER)
-
- for d in allusers_info:
- allusers.append(d['name'])
- users_range[d['name'].split("_")[0]] = d['range']
-
- for u in allusers:
- if u not in [ "system_u", "root", "unconfined_u" ]:
- users.append(u.replace("_u",""))
- users.sort()
- return users, users_range
+ global users
+ global users_range
+ if users and users_range:
+ return users, users_range
+
+ users = []
+ users_range = {}
+ allusers = []
+ allusers_info = info(USER)
+
+ for d in allusers_info:
+ allusers.append(d['name'])
+ users_range[d['name'].split("_")[0]] = d['range']
+
+ for u in allusers:
+ if u not in ["system_u", "root", "unconfined_u"]:
+ users.append(u.replace("_u", ""))
+ users.sort()
+ return users, users_range
all_entrypoints = None
+
+
def get_entrypoints():
- global all_entrypoints
- if not all_entrypoints:
- all_entrypoints = sepolicy.info(sepolicy.ATTRIBUTE,"entry_type")[0]["types"]
- return all_entrypoints
+ global all_entrypoints
+ if not all_entrypoints:
+ all_entrypoints = sepolicy.info(sepolicy.ATTRIBUTE, "entry_type")[0]["types"]
+ return all_entrypoints
domains = None
+
+
def gen_domains():
- global domains
- if domains:
- return domains
- domains = []
- for d in get_all_domains():
- found = False
- domain = d[:-2]
+ global domains
+ if domains:
+ return domains
+ domains = []
+ for d in get_all_domains():
+ found = False
+ domain = d[:-2]
# if domain + "_exec_t" not in get_entrypoints():
# continue
- if domain in domains:
- continue
- domains.append(domain)
+ if domain in domains:
+ continue
+ domains.append(domain)
- for role in get_all_roles():
- if role[:-2] in domains or role == "system_r":
- continue
- domains.append(role[:-2])
+ for role in get_all_roles():
+ if role[:-2] in domains or role == "system_r":
+ continue
+ domains.append(role[:-2])
- domains.sort()
- return domains
+ domains.sort()
+ return domains
types = None
+
+
def _gen_types():
- global types
- if types:
- return types
- all_types = sepolicy.info(sepolicy.TYPE)
- types = {}
- for rec in all_types:
- try:
- types[rec["name"]] = rec["attributes"]
- except:
- types[rec["name"]] = []
- return types
-
-def prettyprint(f,trim):
+ global types
+ if types:
+ return types
+ all_types = sepolicy.info(sepolicy.TYPE)
+ types = {}
+ for rec in all_types:
+ try:
+ types[rec["name"]] = rec["attributes"]
+ except:
+ types[rec["name"]] = []
+ return types
+
+
+def prettyprint(f, trim):
return " ".join(f[:-len(trim)].split("_"))
# for HTML man pages
manpage_domains = []
manpage_roles = []
-fedora_releases = ["Fedora17","Fedora18"]
-rhel_releases = ["RHEL6","RHEL7"]
+fedora_releases = ["Fedora17", "Fedora18"]
+rhel_releases = ["RHEL6", "RHEL7"]
+
def get_alphabet_manpages(manpage_list):
- alphabet_manpages = dict.fromkeys(string.ascii_letters, [])
- for i in string.ascii_letters:
- temp = []
- for j in manpage_list:
- if j.split("/")[-1][0] == i:
- temp.append(j.split("/")[-1])
+ alphabet_manpages = dict.fromkeys(string.ascii_letters, [])
+ for i in string.ascii_letters:
+ temp = []
+ for j in manpage_list:
+ if j.split("/")[-1][0] == i:
+ temp.append(j.split("/")[-1])
- alphabet_manpages[i] = temp
+ alphabet_manpages[i] = temp
- return alphabet_manpages
+ return alphabet_manpages
+
+
+def convert_manpage_to_html(html_manpage, manpage):
+ rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
+ if rc == 0:
+ print html_manpage, " has been created"
+ fd = open(html_manpage, 'w')
+ fd.write(output)
+ fd.close()
-def convert_manpage_to_html(html_manpage,manpage):
- rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
- if rc == 0:
- print html_manpage, " has been created"
- fd = open(html_manpage,'w')
- fd.write(output)
- fd.close()
class HTMLManPages:
- """
- Generate a HHTML Manpages on an given SELinux domains
- """
-
- def __init__(self, manpage_roles, manpage_domains, path, os_version):
- self.manpage_roles = get_alphabet_manpages(manpage_roles)
- self.manpage_domains = get_alphabet_manpages(manpage_domains)
- self.os_version = os_version
- self.old_path = path + "/"
- self.new_path = self.old_path + self.os_version+"/"
-
- if self.os_version in fedora_releases or rhel_releases:
- self.__gen_html_manpages()
- else:
- print("SELinux HTML man pages can not be generated for this %s" % os_version)
- exit(1)
-
- def __gen_html_manpages(self):
- self._write_html_manpage()
- self._gen_index()
- self._gen_body()
- self._gen_css()
-
- def _write_html_manpage(self):
- if not os.path.isdir(self.new_path):
- os.mkdir(self.new_path)
-
- for domain in self.manpage_domains.values():
- if len(domain):
- for d in domain:
- convert_manpage_to_html((self.new_path+d.split("_selinux")[0]+".html"),self.old_path+d)
-
- for role in self.manpage_roles.values():
- if len(role):
- for r in role:
- convert_manpage_to_html((self.new_path+r.split("_selinux")[0]+".html"),self.old_path+r)
-
-
- def _gen_index(self):
- index = self.old_path+"index.html"
- fd = open(index,'w')
- fd.write("""
+
+ """
+ Generate a HHTML Manpages on an given SELinux domains
+ """
+
+ def __init__(self, manpage_roles, manpage_domains, path, os_version):
+ self.manpage_roles = get_alphabet_manpages(manpage_roles)
+ self.manpage_domains = get_alphabet_manpages(manpage_domains)
+ self.os_version = os_version
+ self.old_path = path + "/"
+ self.new_path = self.old_path + self.os_version + "/"
+
+ if self.os_version in fedora_releases or rhel_releases:
+ self.__gen_html_manpages()
+ else:
+ print("SELinux HTML man pages can not be generated for this %s" % os_version)
+ exit(1)
+
+ def __gen_html_manpages(self):
+ self._write_html_manpage()
+ self._gen_index()
+ self._gen_body()
+ self._gen_css()
+
+ def _write_html_manpage(self):
+ if not os.path.isdir(self.new_path):
+ os.mkdir(self.new_path)
+
+ for domain in self.manpage_domains.values():
+ if len(domain):
+ for d in domain:
+ convert_manpage_to_html((self.new_path + d.split("_selinux")[0] + ".html"), self.old_path + d)
+
+ for role in self.manpage_roles.values():
+ if len(role):
+ for r in role:
+ convert_manpage_to_html((self.new_path + r.split("_selinux")[0] + ".html"), self.old_path + r)
+
+ def _gen_index(self):
+ index = self.old_path + "index.html"
+ fd = open(index, 'w')
+ fd.write("""
<html>
<head>
<link rel=stylesheet type="text/css" href="style.css" title="style">
@@ -219,11 +236,11 @@ Fedora or Red Hat Enterprise Linux Man Pages.</h2>
</tr></table>
<pre>
""")
- for f in fedora_releases:
- fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (f,f,f,f))
+ for f in fedora_releases:
+ fd.write("""
+<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (f, f, f, f))
- fd.write("""
+ fd.write("""
</pre>
<hr>
<h3>RHEL</h3>
@@ -233,20 +250,20 @@ Fedora or Red Hat Enterprise Linux Man Pages.</h2>
</tr></table>
<pre>
""")
- for r in rhel_releases:
- fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (r,r,r,r))
+ for r in rhel_releases:
+ fd.write("""
+<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (r, r, r, r))
- fd.write("""
+ fd.write("""
</pre>
""")
- fd.close()
- print("%s has been created") % index
+ fd.close()
+ print("%s has been created") % index
- def _gen_body(self):
- html = self.new_path+self.os_version+".html"
- fd = open(html,'w')
- fd.write("""
+ def _gen_body(self):
+ html = self.new_path + self.os_version + ".html"
+ fd = open(html, 'w')
+ fd.write("""
<html>
<head>
<link rel=stylesheet type="text/css" href="../style.css" title="style">
@@ -259,65 +276,65 @@ Fedora or Red Hat Enterprise Linux Man Pages.</h2>
<td valign="middle">
<h3>SELinux roles</h3>
""")
- for letter in self.manpage_roles:
- if len(self.manpage_roles[letter]):
- fd.write("""
+ for letter in self.manpage_roles:
+ if len(self.manpage_roles[letter]):
+ fd.write("""
<a href=#%s_role>%s</a>"""
- % (letter,letter))
+ % (letter, letter))
- fd.write("""
+ fd.write("""
</td>
</tr></table>
<pre>
""")
- rolename_body = ""
- for letter in self.manpage_roles:
- if len(self.manpage_roles[letter]):
- rolename_body += "<p>"
- for r in self.manpage_roles[letter]:
- rolename = r.split("_selinux")[0]
- rolename_body += "<a name=%s_role></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter,rolename,rolename,rolename)
-
- fd.write("""%s
+ rolename_body = ""
+ for letter in self.manpage_roles:
+ if len(self.manpage_roles[letter]):
+ rolename_body += "<p>"
+ for r in self.manpage_roles[letter]:
+ rolename = r.split("_selinux")[0]
+ rolename_body += "<a name=%s_role></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter, rolename, rolename, rolename)
+
+ fd.write("""%s
</pre>
<hr>
<table><tr>
<td valign="middle">
<h3>SELinux domains</h3>"""
-% rolename_body)
+ % rolename_body)
- for letter in self.manpage_domains:
- if len(self.manpage_domains[letter]):
- fd.write("""
+ for letter in self.manpage_domains:
+ if len(self.manpage_domains[letter]):
+ fd.write("""
<a href=#%s_domain>%s</a>
- """ % (letter,letter))
+ """ % (letter, letter))
- fd.write("""
+ fd.write("""
</td>
</tr></table>
<pre>
""")
- domainname_body = ""
- for letter in self.manpage_domains:
- if len(self.manpage_domains[letter]):
- domainname_body += "<p>"
- for r in self.manpage_domains[letter]:
- domainname = r.split("_selinux")[0]
- domainname_body += "<a name=%s_domain></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter,domainname,domainname,domainname)
-
- fd.write("""%s
+ domainname_body = ""
+ for letter in self.manpage_domains:
+ if len(self.manpage_domains[letter]):
+ domainname_body += "<p>"
+ for r in self.manpage_domains[letter]:
+ domainname = r.split("_selinux")[0]
+ domainname_body += "<a name=%s_domain></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter, domainname, domainname, domainname)
+
+ fd.write("""%s
</pre>
</body>
</html>
""" % domainname_body)
- fd.close()
- print("%s has been created") % html
+ fd.close()
+ print("%s has been created") % html
- def _gen_css(self):
- style_css = self.old_path+"style.css"
- fd = open(style_css,'w')
- fd.write("""
+ def _gen_css(self):
+ style_css = self.old_path + "style.css"
+ fd = open(style_css, 'w')
+ fd.write("""
html, body {
background-color: #fcfcfc;
font-family: arial, sans-serif;
@@ -374,159 +391,161 @@ pre.code {
}
""")
- fd.close()
- print("%s has been created") % style_css
+ fd.close()
+ print("%s has been created") % style_css
+
class ManPage:
+
"""
- Generate a Manpage on an SELinux domain in the specified path
+ Generate a Manpage on an SELinux domain in the specified path
"""
modules_dict = None
enabled_str = ["Disabled", "Enabled"]
- def __init__(self, domainname, path = "/tmp", root="/", source_files = False ,html = False):
- self.html = html
- self.source_files = source_files
- self.root = root
- self.portrecs = gen_port_dict()[0]
- self.domains = gen_domains()
- self.all_domains = get_all_domains()
- self.all_attributes = get_all_attributes()
- self.all_bools = get_all_bools()
- self.all_port_types = get_all_port_types()
- self.all_roles = get_all_roles()
- self.all_users = get_all_users_info()[0]
- self.all_users_range = get_all_users_info()[1]
- self.all_file_types = get_all_file_types()
- self.role_allows = get_all_role_allows()
- self.types = _gen_types()
-
- if self.source_files:
- self.fcpath = self.root + "file_contexts"
- else:
- self.fcpath = self.root + selinux.selinux_file_context_path()
-
- self.fcdict = get_fcdict(self.fcpath)
-
- if not os.path.exists(path):
- os.makedirs(path)
-
- self.path = path
-
- if self.source_files:
- self.xmlpath = self.root + "policy.xml"
- else:
- self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml"
- self.booleans_dict = gen_bool_dict(self.xmlpath)
+ def __init__(self, domainname, path="/tmp", root="/", source_files=False, html=False):
+ self.html = html
+ self.source_files = source_files
+ self.root = root
+ self.portrecs = gen_port_dict()[0]
+ self.domains = gen_domains()
+ self.all_domains = get_all_domains()
+ self.all_attributes = get_all_attributes()
+ self.all_bools = get_all_bools()
+ self.all_port_types = get_all_port_types()
+ self.all_roles = get_all_roles()
+ self.all_users = get_all_users_info()[0]
+ self.all_users_range = get_all_users_info()[1]
+ self.all_file_types = get_all_file_types()
+ self.role_allows = get_all_role_allows()
+ self.types = _gen_types()
+
+ if self.source_files:
+ self.fcpath = self.root + "file_contexts"
+ else:
+ self.fcpath = self.root + selinux.selinux_file_context_path()
+
+ self.fcdict = get_fcdict(self.fcpath)
+
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+ self.path = path
+
+ if self.source_files:
+ self.xmlpath = self.root + "policy.xml"
+ else:
+ self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml"
+ self.booleans_dict = gen_bool_dict(self.xmlpath)
self.domainname, self.short_name = gen_short_name(domainname)
- self.type = self.domainname + "_t"
- self._gen_bools()
- self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname)
- self.fd = open(self.man_page_path, 'w')
- if self.domainname + "_r" in self.all_roles:
- self.__gen_user_man_page()
- if self.html:
- manpage_roles.append(self.man_page_path)
- else:
- if self.html:
- manpage_domains.append(self.man_page_path)
- self.__gen_man_page()
- self.fd.close()
-
- for k in equiv_dict.keys():
- if k == self.domainname:
- for alias in equiv_dict[k]:
- self.__gen_man_page_link(alias)
+ self.type = self.domainname + "_t"
+ self._gen_bools()
+ self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname)
+ self.fd = open(self.man_page_path, 'w')
+ if self.domainname + "_r" in self.all_roles:
+ self.__gen_user_man_page()
+ if self.html:
+ manpage_roles.append(self.man_page_path)
+ else:
+ if self.html:
+ manpage_domains.append(self.man_page_path)
+ self.__gen_man_page()
+ self.fd.close()
+
+ for k in equiv_dict.keys():
+ if k == self.domainname:
+ for alias in equiv_dict[k]:
+ self.__gen_man_page_link(alias)
def _gen_bools(self):
- self.bools=[]
- self.domainbools=[]
- types = [self.type]
- if self.domainname in equiv_dict:
- for t in equiv_dict[self.domainname]:
- if t + "_t" in self.all_domains:
- types.append(t+"_t")
-
- for t in types:
- domainbools, bools = get_bools(t)
- self.bools += bools
- self.domainbools += domainbools
-
- self.bools.sort()
- self.domainbools.sort()
+ self.bools = []
+ self.domainbools = []
+ types = [self.type]
+ if self.domainname in equiv_dict:
+ for t in equiv_dict[self.domainname]:
+ if t + "_t" in self.all_domains:
+ types.append(t + "_t")
+
+ for t in types:
+ domainbools, bools = get_bools(t)
+ self.bools += bools
+ self.domainbools += domainbools
+
+ self.bools.sort()
+ self.domainbools.sort()
def get_man_page_path(self):
- return self.man_page_path
+ return self.man_page_path
def __gen_user_man_page(self):
- self.role = self.domainname + "_r"
- if not self.modules_dict:
- self.modules_dict = gen_modules_dict(self.xmlpath)
-
- try:
- self.desc = self.modules_dict[self.domainname]
- except:
- self.desc = "%s user role" % self.domainname
-
- if self.domainname in self.all_users:
- self.attributes = sepolicy.info(sepolicy.TYPE,(self.type))[0]["attributes"]
- self._user_header()
- self._user_attribute()
- self._can_sudo()
- self._xwindows_login()
- # until a new policy build with login_userdomain attribute
- #self.terminal_login()
- self._network()
- self._booleans()
- self._home_exec()
- self._transitions()
- else:
- self._role_header()
- self._booleans()
-
- self._port_types()
- self._writes()
- self._footer()
+ self.role = self.domainname + "_r"
+ if not self.modules_dict:
+ self.modules_dict = gen_modules_dict(self.xmlpath)
+
+ try:
+ self.desc = self.modules_dict[self.domainname]
+ except:
+ self.desc = "%s user role" % self.domainname
+
+ if self.domainname in self.all_users:
+ self.attributes = sepolicy.info(sepolicy.TYPE, (self.type))[0]["attributes"]
+ self._user_header()
+ self._user_attribute()
+ self._can_sudo()
+ self._xwindows_login()
+ # until a new policy build with login_userdomain attribute
+ #self.terminal_login()
+ self._network()
+ self._booleans()
+ self._home_exec()
+ self._transitions()
+ else:
+ self._role_header()
+ self._booleans()
+
+ self._port_types()
+ self._writes()
+ self._footer()
def __gen_man_page_link(self, alias):
- path = "%s/%s_selinux.8" % (self.path, alias)
- self.fd = open("%s/%s_selinux.8" % (self.path, alias), 'w')
- self.fd.write(".so man8/%s_selinux.8" % self.domainname)
- self.fd.close()
- print path
+ path = "%s/%s_selinux.8" % (self.path, alias)
+ self.fd = open("%s/%s_selinux.8" % (self.path, alias), 'w')
+ self.fd.write(".so man8/%s_selinux.8" % self.domainname)
+ self.fd.close()
+ print path
def __gen_man_page(self):
- self.anon_list = []
-
- self.attributes = {}
- self.ptypes = []
- self._get_ptypes()
-
- for domain_type in self.ptypes:
- self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE,("%s") % domain_type)[0]["attributes"]
-
- self._header()
- self._entrypoints()
- self._process_types()
- self._booleans()
- self._nsswitch_domain()
- self._port_types()
- self._writes()
- self._file_context()
- self._public_content()
- self._footer()
+ self.anon_list = []
+
+ self.attributes = {}
+ self.ptypes = []
+ self._get_ptypes()
+
+ for domain_type in self.ptypes:
+ self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE, ("%s") % domain_type)[0]["attributes"]
+
+ self._header()
+ self._entrypoints()
+ self._process_types()
+ self._booleans()
+ self._nsswitch_domain()
+ self._port_types()
+ self._writes()
+ self._file_context()
+ self._public_content()
+ self._footer()
def _get_ptypes(self):
- for f in self.all_domains:
- if f.startswith(self.short_name) or f.startswith(self.domainname):
- self.ptypes.append(f)
+ for f in self.all_domains:
+ if f.startswith(self.short_name) or f.startswith(self.domainname):
+ self.ptypes.append(f)
def _header(self):
- self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"'
- % {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")})
- self.fd.write(r"""
+ self.fd.write('.TH "%(domainname)s_selinux" "8" "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"'
+ % {'domainname': self.domainname, 'date': time.strftime("%y-%m-%d")})
+ self.fd.write(r"""
.SH "NAME"
%(domainname)s_selinux \- Security Enhanced Linux Policy for the %(domainname)s processes
.SH "DESCRIPTION"
@@ -539,24 +558,23 @@ For example:
.B ps -eZ | grep %(domainname)s_t
-""" % {'domainname':self.domainname})
-
+""" % {'domainname': self.domainname})
def _format_boolean_desc(self, b):
- desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
- if desc[-1] == ".":
- desc = desc[:-1]
- return desc
+ desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
+ if desc[-1] == ".":
+ desc = desc[:-1]
+ return desc
def _gen_bool_text(self):
- booltext = ""
- for b, enabled in self.domainbools + self.bools:
- if b.endswith("anon_write") and b not in self.anon_list:
- self.anon_list.append(b)
- else:
- if b not in self.booleans_dict:
- continue
- booltext += """
+ booltext = ""
+ for b, enabled in self.domainbools + self.bools:
+ if b.endswith("anon_write") and b not in self.anon_list:
+ self.anon_list.append(b)
+ else:
+ if b not in self.booleans_dict:
+ continue
+ booltext += """
.PP
If you want to %s, you must turn on the %s boolean. %s by default.
@@ -565,48 +583,48 @@ If you want to %s, you must turn on the %s boolean. %s by default.
.EE
""" % (self._format_boolean_desc(b), b, self.enabled_str[enabled], b)
- return booltext
+ return booltext
def _booleans(self):
- self.booltext = self._gen_bool_text()
+ self.booltext = self._gen_bool_text()
- if self.booltext != "":
- self.fd.write("""
+ if self.booltext != "":
+ self.fd.write("""
.SH BOOLEANS
SELinux policy is customizable based on least access required. %s policy is extremely flexible and has several booleans that allow you to manipulate the policy and run %s with the tightest access possible.
""" % (self.domainname, self.domainname))
- self.fd.write(self.booltext)
+ self.fd.write(self.booltext)
def _nsswitch_domain(self):
- nsswitch_types = []
- nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled']
- nsswitchbooltext = ""
- for k in self.attributes.keys():
- if "nsswitch_domain" in self.attributes[k]:
- nsswitch_types.append(k)
-
- if len(nsswitch_types):
- self.fd.write("""
+ nsswitch_types = []
+ nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled']
+ nsswitchbooltext = ""
+ for k in self.attributes.keys():
+ if "nsswitch_domain" in self.attributes[k]:
+ nsswitch_types.append(k)
+
+ if len(nsswitch_types):
+ self.fd.write("""
.SH NSSWITCH DOMAIN
""")
- for b in nsswitch_booleans:
- nsswitchbooltext += """
+ for b in nsswitch_booleans:
+ nsswitchbooltext += """
.PP
If you want to %s for the %s, you must turn on the %s boolean.
.EX
.B setsebool -P %s 1
.EE
-""" % (self._format_boolean_desc(b),(", ".join(nsswitch_types)), b, b)
+""" % (self._format_boolean_desc(b), (", ".join(nsswitch_types)), b, b)
- self.fd.write(nsswitchbooltext)
+ self.fd.write(nsswitchbooltext)
def _process_types(self):
- if len(self.ptypes) == 0:
- return
- self.fd.write(r"""
+ if len(self.ptypes) == 0:
+ return
+ self.fd.write(r"""
.SH PROCESS TYPES
SELinux defines process types (domains) for each process running on the system
.PP
@@ -616,27 +634,27 @@ Policy governs the access confined processes have to files.
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
.PP
The following process types are defined for %(domainname)s:
-""" % {'domainname':self.domainname})
- self.fd.write("""
+""" % {'domainname': self.domainname})
+ self.fd.write("""
.EX
.B %s
.EE""" % ", ".join(self.ptypes))
- self.fd.write("""
+ self.fd.write("""
.PP
Note:
.B semanage permissive -a %(domainname)s_t
can be used to make the process type %(domainname)s_t permissive. SELinux does not deny access to permissive process types, but the AVC (SELinux denials) messages are still generated.
-""" % {'domainname':self.domainname})
+""" % {'domainname': self.domainname})
def _port_types(self):
- self.ports = []
- for f in self.all_port_types:
+ self.ports = []
+ for f in self.all_port_types:
if f.startswith(self.short_name) or f.startswith(self.domainname):
- self.ports.append(f)
+ self.ports.append(f)
- if len(self.ports) == 0:
- return
- self.fd.write("""
+ if len(self.ports) == 0:
+ return
+ self.fd.write("""
.SH PORT TYPES
SELinux defines port types to represent TCP and UDP ports.
.PP
@@ -648,10 +666,10 @@ You can see the types associated with a port by using the following command:
Policy governs the access confined processes have to these ports.
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
.PP
-The following port types are defined for %(domainname)s:""" % {'domainname':self.domainname})
+The following port types are defined for %(domainname)s:""" % {'domainname': self.domainname})
- for p in self.ports:
- self.fd.write("""
+ for p in self.ports:
+ self.fd.write("""
.EX
.TP 5
@@ -659,49 +677,49 @@ The following port types are defined for %(domainname)s:""" % {'domainname':self
.TP 10
.EE
""" % p)
- once = True
- for prot in ( "tcp", "udp" ):
- if (p,prot) in self.portrecs:
- if once:
- self.fd.write("""
+ once = True
+ for prot in ("tcp", "udp"):
+ if (p, prot) in self.portrecs:
+ if once:
+ self.fd.write("""
Default Defined Ports:""")
- once = False
- self.fd.write(r"""
+ once = False
+ self.fd.write(r"""
%s %s
-.EE""" % (prot, ",".join(self.portrecs[(p,prot)])))
+.EE""" % (prot, ",".join(self.portrecs[(p, prot)])))
def _file_context(self):
- flist=[]
- mpaths=[]
- for f in self.all_file_types:
- if f.startswith(self.domainname):
- flist.append(f)
- if f in self.fcdict:
- mpaths = mpaths + self.fcdict[f]["regex"]
- if len(mpaths) == 0:
- return
- mpaths.sort()
- mdirs={}
- for mp in mpaths:
- found = False
- for md in mdirs:
- if mp.startswith(md):
- mdirs[md].append(mp)
- found = True
- break
- if not found:
- for e in equiv_dirs:
- if mp.startswith(e) and mp.endswith('(/.*)?'):
- mdirs[mp[:-6]] = []
- break
-
- equiv = []
- for m in mdirs:
- if len(mdirs[m]) > 0:
- equiv.append(m)
-
- self.fd.write(r"""
+ flist = []
+ mpaths = []
+ for f in self.all_file_types:
+ if f.startswith(self.domainname):
+ flist.append(f)
+ if f in self.fcdict:
+ mpaths = mpaths + self.fcdict[f]["regex"]
+ if len(mpaths) == 0:
+ return
+ mpaths.sort()
+ mdirs = {}
+ for mp in mpaths:
+ found = False
+ for md in mdirs:
+ if mp.startswith(md):
+ mdirs[md].append(mp)
+ found = True
+ break
+ if not found:
+ for e in equiv_dirs:
+ if mp.startswith(e) and mp.endswith('(/.*)?'):
+ mdirs[mp[:-6]] = []
+ break
+
+ equiv = []
+ for m in mdirs:
+ if len(mdirs[m]) > 0:
+ equiv.append(m)
+
+ self.fd.write(r"""
.SH FILE CONTEXTS
SELinux requires files to have an extended attribute to define the file type.
.PP
@@ -710,15 +728,15 @@ You can see the context of a file using the \fB\-Z\fP option to \fBls\bP
Policy governs the access confined processes have to these files.
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
.PP
-""" % {'domainname':self.domainname})
+""" % {'domainname': self.domainname})
- if len(equiv) > 0:
- self.fd.write(r"""
+ if len(equiv) > 0:
+ self.fd.write(r"""
.PP
.B EQUIVALENCE DIRECTORIES
""")
- for e in equiv:
- self.fd.write(r"""
+ for e in equiv:
+ self.fd.write(r"""
.PP
%(domainname)s policy stores data with multiple different file context types under the %(equiv)s directory. If you would like to store the data in a different directory you can use the semanage command to create an equivalence mapping. If you wanted to store this data under the /srv dirctory you would execute the following command:
.PP
@@ -726,9 +744,9 @@ SELinux %(domainname)s policy is very flexible allowing users to setup their %(d
.br
.B restorecon -R -v /srv/%(alt)s
.PP
-""" % {'domainname':self.domainname, 'equiv': e, 'alt': e.split('/')[-1] })
+""" % {'domainname': self.domainname, 'equiv': e, 'alt': e.split('/')[-1] })
- self.fd.write(r"""
+ self.fd.write(r"""
.PP
.B STANDARD FILE CONTEXT
@@ -740,13 +758,13 @@ store files with these types in a diffent paths, you need to execute the semanag
.B restorecon -R -v /srv/my%(domainname)s_content
Note: SELinux often uses regular expressions to specify labels that match multiple files.
-""" % {'domainname':self.domainname, "type":flist[0] })
+""" % {'domainname': self.domainname, "type": flist[0] })
- self.fd.write(r"""
+ self.fd.write(r"""
.I The following file types are defined for %(domainname)s:
-""" % {'domainname':self.domainname})
- for f in flist:
- self.fd.write("""
+""" % {'domainname': self.domainname})
+ for f in flist:
+ self.fd.write("""
.EX
.PP
@@ -756,19 +774,19 @@ Note: SELinux often uses regular expressions to specify labels that match multip
- %s
""" % ( f, sepolicy.get_description(f)))
- if f in self.fcdict:
- plural = ""
- if len(self.fcdict[f]["regex"]) > 1:
- plural = "s"
- self.fd.write("""
+ if f in self.fcdict:
+ plural = ""
+ if len(self.fcdict[f]["regex"]) > 1:
+ plural = "s"
+ self.fd.write("""
.br
.TP 5
Path%s:
%s""" % (plural, self.fcdict[f]["regex"][0]))
- for x in self.fcdict[f]["regex"][1:]:
- self.fd.write(", %s" % x)
+ for x in self.fcdict[f]["regex"][1:]:
+ self.fd.write(", %s" % x)
- self.fd.write("""
+ self.fd.write("""
.PP
Note: File context can be temporarily modified with the chcon command. If you want to permanently change the file context you need to use the
@@ -779,19 +797,19 @@ to apply the labels.
""")
def _see_also(self):
- ret = ""
- for d in self.domains:
- if d == self.domainname:
- continue
- if d.startswith(self.short_name):
- ret += ", %s_selinux(8)" % d
- if d.startswith(self.domainname + "_"):
- ret += ", %s_selinux(8)" % d
- self.fd.write(ret)
+ ret = ""
+ for d in self.domains:
+ if d == self.domainname:
+ continue
+ if d.startswith(self.short_name):
+ ret += ", %s_selinux(8)" % d
+ if d.startswith(self.domainname + "_"):
+ ret += ", %s_selinux(8)" % d
+ self.fd.write(ret)
def _public_content(self):
- if len(self.anon_list) > 0:
- self.fd.write("""
+ if len(self.anon_list) > 0:
+ self.fd.write("""
.SH SHARING FILES
If you want to share files with multiple domains (Apache, FTP, rsync, Samba), you can set a file context of public_content_t and public_content_rw_t. These context allow any of the above domains to read the content. If you want a particular domain to write to the public_content_rw_t domain, you must set the appropriate boolean.
.TP
@@ -811,10 +829,10 @@ semanage fcontext -a -t public_content_rw_t "/var/%(domainname)s/incoming(/.*)?"
.B restorecon -F -R -v /var/%(domainname)s/incoming
.br
.B setsebool -P %(domainname)s_anon_write 1
-""" % {'domainname':self.domainname})
- for b in self.anon_list:
- desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
- self.fd.write("""
+""" % {'domainname': self.domainname})
+ for b in self.anon_list:
+ desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
+ self.fd.write("""
.PP
If you want to %s, you must turn on the %s boolean.
@@ -824,7 +842,7 @@ If you want to %s, you must turn on the %s boolean.
""" % (desc, b, b))
def _footer(self):
- self.fd.write("""
+ self.fd.write("""
.SH "COMMANDS"
.B semanage fcontext
can also be used to manipulate default file context mappings.
@@ -836,19 +854,19 @@ can also be used to manipulate whether or not a process type is permissive.
can also be used to enable/disable/install/remove policy modules.
""")
- if len(self.ports) > 0:
- self.fd.write("""
+ if len(self.ports) > 0:
+ self.fd.write("""
.B semanage port
can also be used to manipulate the port definitions
""")
- if self.booltext != "":
- self.fd.write("""
+ if self.booltext != "":
+ self.fd.write("""
.B semanage boolean
can also be used to manipulate the booleans
""")
- self.fd.write("""
+ self.fd.write("""
.PP
.B system-config-selinux
is a GUI tool available to customize SELinux policy settings.
@@ -861,102 +879,102 @@ This manual page was auto-generated using
selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)
""" % (self.domainname))
- if self.booltext != "":
- self.fd.write(", setsebool(8)")
+ if self.booltext != "":
+ self.fd.write(", setsebool(8)")
- self._see_also()
+ self._see_also()
def _valid_write(self, check, attributes):
- if check in [ self.type, "domain" ]:
- return False
- if check.endswith("_t"):
- for a in attributes:
- if a in self.types[check]:
- return False
- return True
+ if check in [self.type, "domain"]:
+ return False
+ if check.endswith("_t"):
+ for a in attributes:
+ if a in self.types[check]:
+ return False
+ return True
def _entrypoints(self):
- try:
- entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['entrypoint'], 'class':'file'}))
- except:
- return
+ try:
+ entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['entrypoint'], 'class': 'file'}))
+ except:
+ return
- self.fd.write ("""
+ self.fd.write ("""
.SH "ENTRYPOINTS"
""")
- if len(entrypoints) > 1:
- entrypoints_str = "\\fB%s\\fP file types" % ", ".join(entrypoints)
- else:
- entrypoints_str = "\\fB%s\\fP file type" % entrypoints[0]
+ if len(entrypoints) > 1:
+ entrypoints_str = "\\fB%s\\fP file types" % ", ".join(entrypoints)
+ else:
+ entrypoints_str = "\\fB%s\\fP file type" % entrypoints[0]
- self.fd.write ("""
+ self.fd.write ("""
The %s_t SELinux type can be entered via the %s.
The default entrypoint paths for the %s_t domain are the following:
-""" % (self.domainname, entrypoints_str, self.domainname))
- if "bin_t" in entrypoints:
- entrypoints.remove("bin_t")
- self.fd.write ("""
+""" % (self.domainname, entrypoints_str, self.domainname))
+ if "bin_t" in entrypoints:
+ entrypoints.remove("bin_t")
+ self.fd.write ("""
All executeables with the default executable label, usually stored in /usr/bin and /usr/sbin.""")
- paths=[]
- for entrypoint in entrypoints:
- if entrypoint in self.fcdict:
- paths += self.fcdict[entrypoint]["regex"]
+ paths = []
+ for entrypoint in entrypoints:
+ if entrypoint in self.fcdict:
+ paths += self.fcdict[entrypoint]["regex"]
- self.fd.write("""
+ self.fd.write("""
%s""" % ", ".join(paths))
def _writes(self):
- permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type, 'permlist':['open', 'write'], 'class':'file'})
- if permlist == None or len(permlist) == 0:
- return
-
- all_writes = []
- attributes = ["proc_type", "sysctl_type"]
- for i in permlist:
- if not i['target'].endswith("_t"):
- attributes.append(i['target'])
-
- for i in permlist:
- if self._valid_write(i['target'],attributes):
- if i['target'] not in all_writes:
- all_writes.append(i['target'])
-
- if len(all_writes) == 0:
- return
- self.fd.write ("""
+ permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['open', 'write'], 'class': 'file'})
+ if permlist == None or len(permlist) == 0:
+ return
+
+ all_writes = []
+ attributes = ["proc_type", "sysctl_type"]
+ for i in permlist:
+ if not i['target'].endswith("_t"):
+ attributes.append(i['target'])
+
+ for i in permlist:
+ if self._valid_write(i['target'], attributes):
+ if i['target'] not in all_writes:
+ all_writes.append(i['target'])
+
+ if len(all_writes) == 0:
+ return
+ self.fd.write ("""
.SH "MANAGED FILES"
""")
- self.fd.write ("""
+ self.fd.write ("""
The SELinux process type %s_t can manage files labeled with the following file types. The paths listed are the default paths for these file types. Note the processes UID still need to have DAC permissions.
-""" % self.domainname)
+""" % self.domainname)
- all_writes.sort()
- if "file_type" in all_writes:
- all_writes = [ "file_type" ]
- for f in all_writes:
- self.fd.write("""
+ all_writes.sort()
+ if "file_type" in all_writes:
+ all_writes = ["file_type"]
+ for f in all_writes:
+ self.fd.write("""
.br
.B %s
""" % f)
- if f in self.fcdict:
- for path in self.fcdict[f]["regex"]:
- self.fd.write("""\t%s
+ if f in self.fcdict:
+ for path in self.fcdict[f]["regex"]:
+ self.fd.write("""\t%s
.br
""" % path)
def _get_users_range(self):
- if self.domainname in self.all_users_range:
- return self.all_users_range[self.domainname]
- return "s0"
+ if self.domainname in self.all_users_range:
+ return self.all_users_range[self.domainname]
+ return "s0"
def _user_header(self):
- self.fd.write('.TH "%(type)s_selinux" "8" "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"'
- % {'type':self.domainname})
+ self.fd.write('.TH "%(type)s_selinux" "8" "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"'
+ % {'type': self.domainname})
- self.fd.write(r"""
+ self.fd.write(r"""
.SH "NAME"
%(user)s_u \- \fB%(desc)s\fP - Security Enhanced Linux Policy
@@ -987,39 +1005,39 @@ If you wanted to change the default user mapping to use the %(user)s_u user, you
.B semanage login -m -s %(user)s_u __default__
-""" % {'desc': self.desc, 'type':self.type, 'user':self.domainname,'range':self._get_users_range()})
+""" % {'desc': self.desc, 'type': self.type, 'user': self.domainname, 'range': self._get_users_range()})
- if "login_userdomain" in self.attributes and "login_userdomain" in self.all_attributes:
- self.fd.write("""
+ if "login_userdomain" in self.attributes and "login_userdomain" in self.all_attributes:
+ self.fd.write("""
If you want to map the one Linux user (joe) to the SELinux user %(user)s, you would execute:
.B $ semanage login -a -s %(user)s_u joe
-""" % {'user':self.domainname})
+""" % {'user': self.domainname})
def _can_sudo(self):
- sudotype = "%s_sudo_t" % self.domainname
- self.fd.write("""
+ sudotype = "%s_sudo_t" % self.domainname
+ self.fd.write("""
.SH SUDO
""")
- if sudotype in self.types:
- role = self.domainname + "_r"
- self.fd.write("""
+ if sudotype in self.types:
+ role = self.domainname + "_r"
+ self.fd.write("""
The SELinux user %(user)s can execute sudo.
You can set up sudo to allow %(user)s to transition to an administrative domain:
Add one or more of the following record to sudoers using visudo.
-""" % { 'user':self.domainname } )
- for adminrole in self.role_allows[role]:
- self.fd.write("""
+""" % { 'user': self.domainname } )
+ for adminrole in self.role_allows[role]:
+ self.fd.write("""
USERNAME ALL=(ALL) ROLE=%(admin)s_r TYPE=%(admin)s_t COMMAND
.br
sudo will run COMMAND as %(user)s_u:%(admin)s_r:%(admin)s_t:LEVEL
-""" % {'admin':adminrole[:-2], 'user':self.domainname } )
+""" % {'admin': adminrole[:-2], 'user': self.domainname } )
- self.fd.write("""
+ self.fd.write("""
You might also need to add one or more of these new roles to your SELinux user record.
List the SELinux roles your SELinux user can reach by executing:
@@ -1032,105 +1050,105 @@ Modify the roles list and add %(user)s_r to this list.
For more details you can see semanage man page.
-""" % {'user':self.domainname, "roles": " ".join([role] + self.role_allows[role]) } )
- else:
- self.fd.write("""
+""" % {'user': self.domainname, "roles": " ".join([role] + self.role_allows[role]) } )
+ else:
+ self.fd.write("""
The SELinux type %s_t is not allowed to execute sudo.
""" % self.domainname)
def _user_attribute(self):
- self.fd.write("""
+ self.fd.write("""
.SH USER DESCRIPTION
""")
- if "unconfined_usertype" in self.attributes:
- self.fd.write("""
+ if "unconfined_usertype" in self.attributes:
+ self.fd.write("""
The SELinux user %s_u is an unconfined user. It means that a mapped Linux user to this SELinux user is supposed to be allow all actions.
""" % self.domainname)
- if "unpriv_userdomain" in self.attributes:
- self.fd.write("""
+ if "unpriv_userdomain" in self.attributes:
+ self.fd.write("""
The SELinux user %s_u is defined in policy as a unprivileged user. SELinux prevents unprivileged users from doing administration tasks without transitioning to a different role.
""" % self.domainname)
- if "admindomain" in self.attributes:
- self.fd.write("""
+ if "admindomain" in self.attributes:
+ self.fd.write("""
The SELinux user %s_u is an admin user. It means that a mapped Linux user to this SELinux user is intended for administrative actions. Usually this is assigned to a root Linux user.
""" % self.domainname)
def _xwindows_login(self):
- if "x_domain" in self.all_attributes:
- self.fd.write("""
+ if "x_domain" in self.all_attributes:
+ self.fd.write("""
.SH X WINDOWS LOGIN
""")
- if "x_domain" in self.attributes:
- self.fd.write("""
+ if "x_domain" in self.attributes:
+ self.fd.write("""
The SELinux user %s_u is able to X Windows login.
""" % self.domainname)
- else:
- self.fd.write("""
+ else:
+ self.fd.write("""
The SELinux user %s_u is not able to X Windows login.
""" % self.domainname)
def _terminal_login(self):
- if "login_userdomain" in self.all_attributes:
- self.fd.write("""
+ if "login_userdomain" in self.all_attributes:
+ self.fd.write("""
.SH TERMINAL LOGIN
""")
- if "login_userdomain" in self.attributes:
- self.fd.write("""
+ if "login_userdomain" in self.attributes:
+ self.fd.write("""
The SELinux user %s_u is able to terminal login.
""" % self.domainname)
- else:
- self.fd.write("""
+ else:
+ self.fd.write("""
The SELinux user %s_u is not able to terminal login.
""" % self.domainname)
def _network(self):
from sepolicy import network
- self.fd.write("""
+ self.fd.write("""
.SH NETWORK
""")
- for net in ("tcp", "udp"):
- portdict = network.get_network_connect(self.type, net, "name_bind")
- if len(portdict) > 0:
- self.fd.write("""
+ for net in ("tcp", "udp"):
+ portdict = network.get_network_connect(self.type, net, "name_bind")
+ if len(portdict) > 0:
+ self.fd.write("""
.TP
The SELinux user %s_u is able to listen on the following %s ports.
""" % (self.domainname, net))
- for p in portdict:
- for t, ports in portdict[p]:
- self.fd.write("""
+ for p in portdict:
+ for t, ports in portdict[p]:
+ self.fd.write("""
.B %s
""" % ",".join(ports))
- portdict = network.get_network_connect(self.type, "tcp", "name_connect")
- if len(portdict) > 0:
- self.fd.write("""
+ portdict = network.get_network_connect(self.type, "tcp", "name_connect")
+ if len(portdict) > 0:
+ self.fd.write("""
.TP
The SELinux user %s_u is able to connect to the following tcp ports.
""" % (self.domainname))
- for p in portdict:
- for t, ports in portdict[p]:
- self.fd.write("""
+ for p in portdict:
+ for t, ports in portdict[p]:
+ self.fd.write("""
.B %s
""" % ",".join(ports))
def _home_exec(self):
- permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,'target':'user_home_type', 'class':'file', 'permlist':['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']})
- self.fd.write("""
+ permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'target': 'user_home_type', 'class': 'file', 'permlist': ['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']})
+ self.fd.write("""
.SH HOME_EXEC
""" )
- if permlist is not None:
- self.fd.write("""
+ if permlist is not None:
+ self.fd.write("""
The SELinux user %s_u is able execute home content files.
""" % self.domainname)
- else:
- self.fd.write("""
+ else:
+ self.fd.write("""
The SELinux user %s_u is not able execute home content files.
""" % self.domainname)
def _transitions(self):
- self.fd.write(r"""
+ self.fd.write(r"""
.SH TRANSITIONS
Three things can happen when %(type)s attempts to execute a program.
@@ -1153,13 +1171,13 @@ Execute the following to see the types that the SELinux user %(type)s can execut
.B $ search -A -s %(type)s -c process -p transition
-""" % {'user':self.domainname, 'type':self.type})
+""" % {'user': self.domainname, 'type': self.type})
def _role_header(self):
- self.fd.write('.TH "%(user)s_selinux" "8" "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"'
- % {'user':self.domainname})
+ self.fd.write('.TH "%(user)s_selinux" "8" "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"'
+ % {'user': self.domainname})
- self.fd.write(r"""
+ self.fd.write(r"""
.SH "NAME"
%(user)s_r \- \fB%(desc)s\fP - Security Enhanced Linux Policy
@@ -1200,17 +1218,17 @@ You need to add %(user)s_r to the staff_u user. You could setup the staff_u use
.B $ semanage user -m -R 'staff_r system_r %(user)s_r' staff_u
-""" % {'desc': self.desc, 'user':self.domainname})
- troles = []
- for i in self.role_allows:
- if self.domainname +"_r" in self.role_allows[i]:
- troles.append(i)
- if len(troles) > 0:
- plural = ""
- if len(troles) > 1:
- plural = "s"
-
- self.fd.write("""
+""" % {'desc': self.desc, 'user': self.domainname})
+ troles = []
+ for i in self.role_allows:
+ if self.domainname + "_r" in self.role_allows[i]:
+ troles.append(i)
+ if len(troles) > 0:
+ plural = ""
+ if len(troles) > 1:
+ plural = "s"
+
+ self.fd.write("""
SELinux policy also controls which roles can transition to a different role.
You can list these rules using the following command.
diff --git a/policycoreutils/sepolicy/sepolicy/network.py b/policycoreutils/sepolicy/sepolicy/network.py
index 3a75d7cc..1ca31586 100755
--- a/policycoreutils/sepolicy/sepolicy/network.py
+++ b/policycoreutils/sepolicy/sepolicy/network.py
@@ -1,5 +1,5 @@
#! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat
+# Copyright (C) 2012 Red Hat
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,30 +16,31 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
+#
import sepolicy
-search=sepolicy.search
-info=sepolicy.info
+search = sepolicy.search
+info = sepolicy.info
+
def get_types(src, tclass, perm):
- allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
- nlist=[]
+ allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
+ nlist = []
if allows:
for i in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):
if i not in nlist:
nlist.append(i)
return nlist
-
+
def get_network_connect(src, protocol, perm):
portrecs, portrecsbynum = sepolicy.gen_port_dict()
- d={}
+ d = {}
tlist = get_types(src, "%s_socket" % protocol, [perm])
if len(tlist) > 0:
- d[(src,protocol,perm)] = []
+ d[(src, protocol, perm)] = []
for i in tlist:
if i == "ephemeral_port_type":
if "unreserved_port_type" in tlist:
@@ -51,18 +52,18 @@ def get_network_connect(src, protocol, perm):
if "port_t" in tlist:
continue
if i == "port_t":
- d[(src,protocol,perm)].append((i, ["all ports with out defined types"]))
+ d[(src, protocol, perm)].append((i, ["all ports with out defined types"]))
if i == "port_type":
- d[(src,protocol,perm)].append((i, ["all ports"]))
+ d[(src, protocol, perm)].append((i, ["all ports"]))
elif i == "unreserved_port_type":
- d[(src,protocol,perm)].append((i, ["all ports > 1024"]))
+ d[(src, protocol, perm)].append((i, ["all ports > 1024"]))
elif i == "reserved_port_type":
- d[(src,protocol,perm)].append((i, ["all ports < 1024"]))
+ d[(src, protocol, perm)].append((i, ["all ports < 1024"]))
elif i == "rpc_port_type":
- d[(src,protocol,perm)].append((i, ["all ports > 500 and < 1024"]))
+ d[(src, protocol, perm)].append((i, ["all ports > 500 and < 1024"]))
else:
try:
- d[(src,protocol,perm)].append((i, portrecs[(i, protocol)]))
+ d[(src, protocol, perm)].append((i, portrecs[(i, protocol)]))
except KeyError:
pass
return d
diff --git a/policycoreutils/sepolicy/sepolicy/sedbus.py b/policycoreutils/sepolicy/sepolicy/sedbus.py
index c6645ef9..6055294a 100644
--- a/policycoreutils/sepolicy/sepolicy/sedbus.py
+++ b/policycoreutils/sepolicy/sepolicy/sedbus.py
@@ -4,49 +4,51 @@ import dbus.service
import dbus.mainloop.glib
from slip.dbus import polkit
+
class SELinuxDBus (object):
- def __init__ (self):
+
+ def __init__(self):
self.bus = dbus.SystemBus()
self.dbus_object = self.bus.get_object("org.selinux", "/org/selinux/object")
@polkit.enable_proxy
- def semanage (self, buf):
- ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
+ def semanage(self, buf):
+ ret = self.dbus_object.semanage(buf, dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
- def restorecon (self, path):
- ret = self.dbus_object.restorecon(path, dbus_interface = "org.selinux")
+ def restorecon(self, path):
+ ret = self.dbus_object.restorecon(path, dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
- def setenforce (self, value):
- ret = self.dbus_object.setenforce(value, dbus_interface = "org.selinux")
+ def setenforce(self, value):
+ ret = self.dbus_object.setenforce(value, dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
- def customized (self):
- ret = self.dbus_object.customized(dbus_interface = "org.selinux")
+ def customized(self):
+ ret = self.dbus_object.customized(dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
- def semodule_list (self):
- ret = self.dbus_object.semodule_list(dbus_interface = "org.selinux")
+ def semodule_list(self):
+ ret = self.dbus_object.semodule_list(dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
def relabel_on_boot(self, value):
- ret = self.dbus_object.relabel_on_boot(value, dbus_interface = "org.selinux")
+ ret = self.dbus_object.relabel_on_boot(value, dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
def change_default_mode(self, value):
- ret = self.dbus_object.change_default_mode(value, dbus_interface = "org.selinux")
+ ret = self.dbus_object.change_default_mode(value, dbus_interface="org.selinux")
return ret
@polkit.enable_proxy
def change_default_policy(self, value):
- ret = self.dbus_object.change_default_policy(value, dbus_interface = "org.selinux")
+ ret = self.dbus_object.change_default_policy(value, dbus_interface="org.selinux")
return ret
if __name__ == "__main__":
diff --git a/policycoreutils/sepolicy/sepolicy/transition.py b/policycoreutils/sepolicy/sepolicy/transition.py
index 11834c7b..15b0eb1e 100755
--- a/policycoreutils/sepolicy/sepolicy/transition.py
+++ b/policycoreutils/sepolicy/sepolicy/transition.py
@@ -1,5 +1,5 @@
#! /usr/bin/python -Es
-# Copyright (C) 2011 Red Hat
+# Copyright (C) 2011 Red Hat
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,31 +16,34 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# 02111-1307 USA
#
-#
+#
import sepolicy
-search=sepolicy.search
-info=sepolicy.info
-__all__ = [ 'setrans', ]
+search = sepolicy.search
+info = sepolicy.info
+__all__ = ['setrans', ]
+
def _entrypoint(src):
- trans=search([sepolicy.ALLOW],{sepolicy.SOURCE:src})
+ trans = search([sepolicy.ALLOW], {sepolicy.SOURCE: src})
return map(lambda y: y[sepolicy.TARGET], filter(lambda x: "entrypoint" in x[sepolicy.PERMS], trans))
-
+
def _get_trans(src):
- return search([sepolicy.TRANSITION],{sepolicy.SOURCE:src, sepolicy.CLASS:"process"})
+ return search([sepolicy.TRANSITION], {sepolicy.SOURCE: src, sepolicy.CLASS: "process"})
+
class setrans:
+
def __init__(self, source, dest=None):
self.seen = []
self.sdict = {}
- self.source=source
- self.dest=dest
+ self.source = source
+ self.dest = dest
self._process(self.source)
-
+
def _process(self, source):
if source in self.sdict:
return self.sdict[source]
@@ -53,10 +56,10 @@ class setrans:
self.sdict[source]["map"] = trans
else:
self.sdict[source]["map"] = map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans))
- self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest,source] , trans))
+ self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest, source], trans))
for s in self.sdict[source]["child"]:
self._process(s)
-
+
def out(self, name, header=""):
buf = ""
if name in self.seen:
@@ -65,7 +68,7 @@ class setrans:
if "map" in self.sdict[name]:
for t in self.sdict[name]["map"]:
- cond=sepolicy.get_conditionals(t["source"], t["transtype"],"process",["transition"])
+ cond = sepolicy.get_conditionals(t["source"], t["transtype"], "process", ["transition"])
if cond:
buf += "%s%s @ %s --> %s %s\n" % (header, t["source"], t["target"], t["transtype"], sepolicy.get_conditionals_format_text(cond))
else:
@@ -73,7 +76,7 @@ class setrans:
if "child" in self.sdict[name]:
for x in self.sdict[name]["child"]:
- buf+= self.out(x, "%s%s ... " % (header, name))
+ buf += self.out(x, "%s%s ... " % (header, name))
return buf
def output(self):
diff --git a/policycoreutils/sepolicy/setup.py b/policycoreutils/sepolicy/setup.py
index d8e2d64d..e74e68d4 100644
--- a/policycoreutils/sepolicy/setup.py
+++ b/policycoreutils/sepolicy/setup.py
@@ -4,9 +4,9 @@
# Author: Dan Walsh <dwalsh@redhat.com>
import os
from distutils.core import setup, Extension
-policy = Extension("sepolicy._policy",
+policy = Extension("sepolicy._policy",
libraries=["apol", "qpol"],
- sources=[ "policy.c", "info.c", "search.c"]
-)
+ sources=["policy.c", "info.c", "search.c"]
+ )
-setup(name = "sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy':['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})
+setup(name="sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy': ['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})
diff --git a/policycoreutils/sepolicy/test_sepolicy.py b/policycoreutils/sepolicy/test_sepolicy.py
index aef799ff..e7bad44f 100644
--- a/policycoreutils/sepolicy/test_sepolicy.py
+++ b/policycoreutils/sepolicy/test_sepolicy.py
@@ -1,11 +1,16 @@
-import unittest, os, shutil
+import unittest
+import os
+import shutil
from tempfile import mkdtemp
from subprocess import Popen, PIPE
+
class SepolicyTests(unittest.TestCase):
+
def assertDenied(self, err):
self.assert_('Permission denied' in err,
'"Permission denied" not found in %r' % err)
+
def assertNotFound(self, err):
self.assert_('not found' in err,
'"not found" not found in %r' % err)
@@ -16,96 +21,96 @@ class SepolicyTests(unittest.TestCase):
def assertSuccess(self, status, err):
self.assert_(status == 0,
- '"sepolicy should have succeeded for this test %r' % err)
+ '"sepolicy should have succeeded for this test %r' % err)
def test_man_domain(self):
"Verify sepolicy manpage -d works"
- p = Popen(['sepolicy', 'manpage', '-d', 'httpd_t'], stdout = PIPE)
+ p = Popen(['sepolicy', 'manpage', '-d', 'httpd_t'], stdout=PIPE)
out, err = p.communicate()
print out, err
self.assertSuccess(p.returncode, err)
def test_man_all(self):
"Verify sepolicy manpage -a works"
- p = Popen(['sepolicy', 'manpage', '-a'], stdout = PIPE)
+ p = Popen(['sepolicy', 'manpage', '-a'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_network_l(self):
"Verify sepolicy network -l works"
- p = Popen(['sepolicy', 'network', '-l'], stdout = PIPE)
+ p = Popen(['sepolicy', 'network', '-l'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_network_t(self):
"Verify sepolicy network -t works"
- p = Popen(['sepolicy', 'network', '-t', 'http_port_t'], stdout = PIPE)
+ p = Popen(['sepolicy', 'network', '-t', 'http_port_t'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_network_p(self):
"Verify sepolicy network -p works"
- p = Popen(['sepolicy', 'network', '-p', '80'], stdout = PIPE)
+ p = Popen(['sepolicy', 'network', '-p', '80'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_network_d(self):
"Verify sepolicy network -d works"
- p = Popen(['sepolicy', 'network', '-d', 'httpd_t'], stdout = PIPE)
+ p = Popen(['sepolicy', 'network', '-d', 'httpd_t'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_transition_s(self):
"Verify sepolicy transition -l works"
- p = Popen(['sepolicy', 'transition', '-s', 'httpd_t'], stdout = PIPE)
+ p = Popen(['sepolicy', 'transition', '-s', 'httpd_t'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_transition_t(self):
"Verify sepolicy transition -t works"
- p = Popen(['sepolicy', 'transition', '-s', 'httpd_t', '-t', 'sendmail_t'], stdout = PIPE)
+ p = Popen(['sepolicy', 'transition', '-s', 'httpd_t', '-t', 'sendmail_t'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_booleans_a(self):
"Verify sepolicy booleans -a works"
- p = Popen(['sepolicy', 'booleans', '-a'], stdout = PIPE)
+ p = Popen(['sepolicy', 'booleans', '-a'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_booleans_b_alias(self):
"Verify sepolicy booleans -b works"
- p = Popen(['sepolicy', 'booleans', '-b', 'allow_ypbind'], stdout = PIPE)
+ p = Popen(['sepolicy', 'booleans', '-b', 'allow_ypbind'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_booleans_b(self):
"Verify sepolicy booleans -b works"
- p = Popen(['sepolicy', 'booleans', '-b', 'nis_enabled'], stdout = PIPE)
+ p = Popen(['sepolicy', 'booleans', '-b', 'nis_enabled'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_interface_l(self):
"Verify sepolicy interface -l works"
- p = Popen(['sepolicy', 'interface', '-l'], stdout = PIPE)
+ p = Popen(['sepolicy', 'interface', '-l'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_interface_a(self):
"Verify sepolicy interface -a works"
- p = Popen(['sepolicy', 'interface', '-a'], stdout = PIPE)
+ p = Popen(['sepolicy', 'interface', '-a'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_interface_p(self):
"Verify sepolicy interface -u works"
- p = Popen(['sepolicy', 'interface', '-u'], stdout = PIPE)
+ p = Popen(['sepolicy', 'interface', '-u'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
def test_interface_ci(self):
"Verify sepolicy interface -c -i works"
- p = Popen(['sepolicy', 'interface', '-c', '-i', 'apache_admin'], stdout = PIPE)
+ p = Popen(['sepolicy', 'interface', '-c', '-i', 'apache_admin'], stdout=PIPE)
out, err = p.communicate()
self.assertSuccess(p.returncode, err)
diff --git a/secilc/Android.mk b/secilc/Android.mk
index ef584e7e..3dd90233 100644
--- a/secilc/Android.mk
+++ b/secilc/Android.mk
@@ -5,7 +5,6 @@ common_src_files := secilc.c
common_cflags := \
-Wall -Wshadow -O2 \
-pipe -fno-strict-aliasing \
- -Wno-return-type
ifeq ($(HOST_OS), darwin)
common_cflags += -DDARWIN
diff --git a/secilc/ChangeLog b/secilc/ChangeLog
index e69de29b..eec3454e 100644
--- a/secilc/ChangeLog
+++ b/secilc/ChangeLog
@@ -0,0 +1,6 @@
+ * Add documentation and examples for extended avrules, from Steve Lawrence
+ * Added neverallow and bounds checking test policies, from James Carter
+ * Remove uses of -Wno-return-type, from Dan Albert.
+
+2.4 2015-02-02
+ * Initial release.
diff --git a/secilc/docs/cil_access_vector_rules.xml b/secilc/docs/cil_access_vector_rules.xml
index d3ce0959..985fc3dc 100644
--- a/secilc/docs/cil_access_vector_rules.xml
+++ b/secilc/docs/cil_access_vector_rules.xml
@@ -276,4 +276,176 @@
</programlisting>
</sect2>
+ <sect2 id="allowx">
+ <title>allowx</title>
+ <para>Specifies the access allowed between a source and target type using extended permissions. Unlike the <literal><link linkend="allow">allow</link></literal> statement, the statements <literal><link linkend="validatetrans">validatetrans</link></literal>, <literal><link linkend="mlsvalidatetrans">mlsvalidatetrans</link></literal>, <literal><link linkend="constrain">constrain</link></literal>, and <literal><link linkend="mlsconstrain">mlsconstrain</link></literal> do not limit accesses granted by <literal><link linkend="allowx">allowx</link></literal>.</para>
+ <para><emphasis role="bold">Rule definition:</emphasis></para>
+ <programlisting><![CDATA[(allowx source_id target_id|self permissionx_id)]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2.25 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal><link linkend="allowx">allowx</link></literal></para>
+ </entry>
+ <entry>
+ <para>The <literal><link linkend="allowx">allowx</link></literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>source_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal>, or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>target_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal>, or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>permissionx_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+
+ <para><emphasis role="bold">Examples:</emphasis></para>
+ <para>These examples show a selection of possible permutations of <literal><link linkend="allowx">allowx</link></literal> rules:</para>
+ <programlisting><![CDATA[
+(allowx type_1 type_2 (ioctl tcp_socket (range 0x2000 0x20FF)))
+
+(permissionx ioctl_nodebug (ioctl udp_socket (not (range 0x4000 0x4010))))
+(allowx type_3 type_4 ioctl_nodebug)
+]]>
+
+ </programlisting>
+ </sect2>
+
+ <sect2 id="auditallowx">
+ <title>auditallowx</title>
+ <para>Audit the access rights defined if there is a valid <literal><link linkend="allowx">allowx</link></literal> rule. It does NOT allow access, it only audits the event.</para>
+ <para><emphasis role="bold">Rule definition:</emphasis></para>
+ <programlisting><![CDATA[(auditallowx source_id target_id|self permissionx_id)]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2.25 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal><link linkend="auditallowx">auditallowx</link></literal></para>
+ </entry>
+ <entry>
+ <para>The <literal><link linkend="auditallowx">auditallowx</link></literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>source_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>target_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>permissionx_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+
+ <para><emphasis role="bold">Examples:</emphasis></para>
+ <para>This example will log an audit event whenever the corresponding <literal><link linkend="allowx">allowx</link></literal> rule grants access to the specified extended permissions:</para>
+ <programlisting><![CDATA[
+(allowx type_1 type_2 (ioctl tcp_socket (range 0x2000 0x20FF)))
+
+(auditallowx type_1 type_2 (ioctl tcp_socket (range 0x2005 0x2010)))
+]]>
+ </programlisting>
+ </sect2>
+
+ <sect2 id="dontauditx">
+ <title>dontauditx</title>
+ <para>Do not audit the access rights defined when access denied. This stops excessive log entries for known events.</para>
+ <para>Note that these rules can be omitted by the CIL compiler command line parameter <literal>-D</literal> or <literal>--disable-dontaudit</literal> flags.</para>
+ <para><emphasis role="bold">Rule definition:</emphasis></para>
+ <programlisting><![CDATA[(dontauditx source_id target_id|self permissionx_id)]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2.25 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal><link linkend="dontauditx">dontauditx</link></literal></para>
+ </entry>
+ <entry>
+ <para>The <literal><link linkend="dontauditx">dontauditx</link></literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>source_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>target_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+ <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>permissionx_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+
+ <para><emphasis role="bold">Examples:</emphasis></para>
+ <para>This example will not audit the denied access:</para>
+ <programlisting><![CDATA[
+(dontauditx type_1 type_2 (ioctl tcp_socket (range 0x3000 0x30FF)))
+]]>
+ </programlisting>
+ </sect2>
+
</sect1>
diff --git a/secilc/docs/cil_class_and_permission_statements.xml b/secilc/docs/cil_class_and_permission_statements.xml
index 25929b1d..2926d7c3 100644
--- a/secilc/docs/cil_class_and_permission_statements.xml
+++ b/secilc/docs/cil_class_and_permission_statements.xml
@@ -490,4 +490,99 @@
</programlisting>
</sect2>
+ <sect2 id="permissionx">
+ <title>permissionx</title>
+ <para>Defines a named extended permission, which can be used in the <literal><link linkend="allowx">allowx</link></literal>, <literal><link linkend="auditallowx">auditallowx</link></literal>, and <literal><link linkend="dontauditx">dontauditx</link></literal> statements.</para>
+ <para><emphasis role="bold">Statement definition:</emphasis></para>
+ <programlisting><![CDATA[(permissionx permissionx_id (kind class_id (permission ... | expr ...)))]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2.25 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal><link linkend="permissionx">permissionx</link></literal></para>
+ </entry>
+ <entry>
+ <para>The <literal><link linkend="permissionx">permissionx</link></literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>kind</literal></para>
+ </entry>
+ <entry>
+ <para>A keyword specifying how to interpret the extended permission values. Must be one of:</para>
+ <para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth=".5 in"/>
+ <colspec colwidth="*"/>
+ <thead>
+ <row>
+ <entry align="center">
+ <para><emphasis role="bold">kind</emphasis></para>
+ </entry>
+ <entry align="center">
+ <para><emphasis role="bold">description</emphasis></para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>ioctl</para>
+ </entry>
+ <entry>
+ <para>Permissions define a whitelist of ioctl values. Permission values must range from <literal>0x0000</literal> to <literal>0xFFFF</literal>, inclusive.</para>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>class_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously declared <literal><link linkend="class">class</link></literal> identifier.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>permission</literal></para>
+ </entry>
+ <entry>
+ <para>One or more numeric values, specified in decimal, or hexadecimal if prefixed with 0x, or octal if prefixed with 0. Values are interpreted based on the value of <literal>kind</literal>.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>expr</literal></para>
+ </entry>
+ <entry>
+ <para>An expression, with valid operators and syntax:</para>
+ <simpara><literal> (range (permission ...) (permission ...))</literal></simpara>
+ <simpara><literal> (and (permission ...) (permission ...))</literal></simpara>
+ <simpara><literal> (or (permission ...) (permission ...))</literal></simpara>
+ <simpara><literal> (xor (permission ...) (permission ...))</literal></simpara>
+ <simpara><literal> (not (permission ...))</literal></simpara>
+ <simpara><literal> (all)</literal></simpara>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+ <para><emphasis role="bold">Examples:</emphasis></para>
+ <programlisting><![CDATA[
+(permissionx ioctl_1 (ioctl tcp_socket (0x2000 0x3000 0x4000)))
+(permissionx ioctl_2 (ioctl tcp_socket (range 0x6000 0x60FF)))
+(permissionx ioctl_3 (ioctl tcp_socket (and (range 0x8000 0x90FF) (not (range 0x8100 0x82FF)))))
+]]>
+ </programlisting>
+ </sect2>
+
</sect1>
diff --git a/secilc/docs/cil_constraint_statements.xml b/secilc/docs/cil_constraint_statements.xml
index 6f5d9c60..8ef16427 100644
--- a/secilc/docs/cil_constraint_statements.xml
+++ b/secilc/docs/cil_constraint_statements.xml
@@ -51,7 +51,7 @@
<simpara>and:</simpara>
<simpara><literal> op : eq neq</literal></simpara>
<simpara><literal> role_op : eq neq dom domby incomp</literal></simpara>
- <simpara><literal> user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+ <simpara><literal> user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
<simpara><literal> role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
<simpara><literal> type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
</entry>
@@ -154,7 +154,7 @@
<simpara>and:</simpara>
<simpara><literal> op : eq neq</literal></simpara>
<simpara><literal> role_op : eq neq dom domby incomp</literal></simpara>
- <simpara><literal> user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+ <simpara><literal> user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
<simpara><literal> role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
<simpara><literal> type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
</entry>
@@ -236,7 +236,7 @@
<simpara>and:</simpara>
<simpara><literal> op : eq neq</literal></simpara>
<simpara><literal> mls_role_op : eq neq dom domby incomp</literal></simpara>
- <simpara><literal> user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+ <simpara><literal> user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
<simpara><literal> role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
<simpara><literal> type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
</entry>
@@ -332,7 +332,7 @@
<simpara>and:</simpara>
<simpara><literal> op : eq neq</literal></simpara>
<simpara><literal> mls_role_op : eq neq dom domby incomp</literal></simpara>
- <simpara><literal> user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+ <simpara><literal> user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
<simpara><literal> role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
<simpara><literal> type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
</entry>
diff --git a/secilc/docs/cil_container_statements.xml b/secilc/docs/cil_container_statements.xml
index 6bdd1ab5..3e3d2f69 100644
--- a/secilc/docs/cil_container_statements.xml
+++ b/secilc/docs/cil_container_statements.xml
@@ -241,19 +241,30 @@
<para><literal><link linkend="allow">allow</link></literal></para>
</entry>
<entry>
+ <para><literal><link linkend="allowx">allowx</link></literal></para>
+ </entry>
+ <entry>
<para><literal><link linkend="auditallow">auditallow</link></literal></para>
</entry>
<entry>
+ <para><literal><link linkend="auditallowx">auditallowx</link></literal></para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para><literal><link linkend="booleanif">booleanif</link></literal></para>
</entry>
<entry>
<para><literal><link linkend="dontaudit">dontaudit</link></literal></para>
</entry>
- </row>
- <row>
+ <entry>
+ <para><literal><link linkend="dontauditx">dontauditx</link></literal></para>
+ </entry>
<entry>
<para><literal><link linkend="typepermissive">typepermissive</link></literal></para>
</entry>
+ </row>
+ <row>
<entry>
<para><literal><link linkend="rangetransition">rangetransition</link></literal></para>
</entry>
@@ -263,11 +274,11 @@
<entry>
<para><literal><link linkend="roleallow">roleallow</link></literal></para>
</entry>
- </row>
- <row>
<entry>
<para><literal><link linkend="roleattribute">roleattribute</link></literal></para>
</entry>
+ </row>
+ <row>
<entry>
<para><literal><link linkend="roletransition">roletransition</link></literal></para>
</entry>
@@ -277,11 +288,11 @@
<entry>
<para><literal><link linkend="typealias">typealias</link></literal></para>
</entry>
- </row>
- <row>
<entry>
<para><literal><link linkend="typeattribute">typeattribute</link></literal></para>
</entry>
+ </row>
+ <row>
<entry>
<para><literal><link linkend="typechange">typechange</link></literal></para>
</entry>
diff --git a/secilc/docs/cil_user_statements.xml b/secilc/docs/cil_user_statements.xml
index 9fa1a51a..38a7d6e0 100644
--- a/secilc/docs/cil_user_statements.xml
+++ b/secilc/docs/cil_user_statements.xml
@@ -66,7 +66,7 @@
<para><literal>user_id</literal></para>
</entry>
<entry>
- <para>A previously declared SELinux <literal><link linkend="user">user</link></literal> identifier.</para>
+ <para>A previously declared SELinux <literal><link linkend="user">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifier.</para>
</entry>
</row>
<row>
@@ -91,6 +91,114 @@
</programlisting>
</sect2>
+ <sect2 id="userattribute">
+ <title>userattribute</title>
+ <para>Declares a user attribute identifier in the current namespace. The identifier may have zero or more <literal><link linkend="user">user</link></literal> and <literal><link linkend="userattribute">userattribute</link></literal> identifiers associated to it via the <literal><link linkend="userattributeset">userattributeset</link></literal> statement.</para>
+ <para><emphasis role="bold">Statement definition:</emphasis></para>
+ <programlisting><![CDATA[(userattribute userattribute_id)]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal>userattribute</literal></para>
+ </entry>
+ <entry>
+ <para>The <literal>userattribute</literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>userattribute_id</literal></para>
+ </entry>
+ <entry>
+ <para>The <literal>userattribute</literal> identifier.</para>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+
+ <para><emphasis role="bold">Example:</emphasis></para>
+ <para>This example will declare a user attribute <literal>users.user_holder</literal> that will have an empty set:</para>
+ <programlisting><![CDATA[
+(block users
+ (userattribute user_holder)
+)]]>
+ </programlisting>
+ </sect2>
+
+ <sect2 id="userattributeset">
+ <title>userattributeset</title>
+ <para>Allows the association of one or more previously declared <literal><link linkend="user">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifiers to a <literal><link linkend="userattribute">userattribute</link></literal> identifier. Expressions may be used to refine the associations as shown in the examples.</para>
+ <para><emphasis role="bold">Statement definition:</emphasis></para>
+ <programlisting><![CDATA[(userattributeset userattribute_id (user_id ... | expr ...))]]></programlisting>
+ <para><emphasis role="bold">Where:</emphasis></para>
+ <informaltable frame="all">
+ <tgroup cols="2">
+ <colspec colwidth="2 *"/>
+ <colspec colwidth="6 *"/>
+ <tbody>
+ <row>
+ <entry>
+ <para><literal>userattributeset</literal></para>
+ </entry>
+ <entry>
+ <para>The <literal>userattributeset</literal> keyword.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>userattribute_id</literal></para>
+ </entry>
+ <entry>
+ <para>A single previously declared <literal><link linkend="roleattribute">userattribute</link></literal> identifier.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>user_id</literal></para>
+ </entry>
+ <entry>
+ <para>Zero or more previously declared <literal><link linkend="role">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifiers.</para>
+ <para>Note that there must be at least one <literal>user_id</literal> or <literal>expr</literal> parameter declared.</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para><literal>expr</literal></para>
+ </entry>
+ <entry>
+ <para>Zero or more <literal>expr</literal>'s, the valid operators and syntax are:</para>
+ <simpara><literal> (and (user_id ...) (user_id ...))</literal></simpara>
+ <simpara><literal> (or (user_id ...) (user_id ...))</literal></simpara>
+ <simpara><literal> (xor (user_id ...) (user_id ...))</literal></simpara>
+ <simpara><literal> (not (user_id ...))</literal></simpara>
+ <simpara><literal> (all)</literal></simpara>
+ </entry>
+ </row>
+ </tbody></tgroup>
+ </informaltable>
+
+ <para><emphasis role="bold">Example:</emphasis></para>
+ <para>This example will declare three users and two user attributes, then associate all the users to them as shown:</para>
+ <programlisting><![CDATA[
+(block users
+ (user user_1)
+ (user user_2)
+ (user user_3)
+
+ (userattribute user_holder)
+ (userattributeset user_holder (user_1 user_2 user_3))
+
+ (userattribute user_holder_all)
+ (userattributeset user_holder_all (all))
+)]]>
+ </programlisting>
+ </sect2>
+
<sect2 id="userlevel">
<title>userlevel</title>
<para>Associates a previously declared <literal><link linkend="user">user</link></literal> identifier with a previously declared <literal><link linkend="level">level</link></literal> identifier. The <literal><link linkend="level">level</link></literal> may be named or anonymous.</para>
diff --git a/secilc/test/bounds.cil b/secilc/test/bounds.cil
new file mode 100644
index 00000000..e72560e8
--- /dev/null
+++ b/secilc/test/bounds.cil
@@ -0,0 +1,241 @@
+(class CLASS (PERM))
+(classorder (CLASS))
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(type TYPE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(allow TYPE self (CLASS (PERM)))
+(roletype ROLE TYPE)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
+
+(class c1 (p1a p1b p1c))
+(class c2 (p2a p2b p2c))
+(class c3 (p3a p3b p3c))
+
+(classorder (CLASS c1 c2 c3))
+
+(classpermission cp1)
+(classpermissionset cp1 (c1 (p1a p1b)))
+(classpermissionset cp1 (c2 (p2a)))
+
+(classmap cm1 (mp1))
+(classmapping cm1 mp1
+ (c1 (p1a)))
+
+(boolean b_b1 false)
+(boolean b_b2 false)
+(boolean b_b3 false)
+
+
+(type b_ta)
+(type b_tb)
+(type b_tc)
+(type b_td)
+
+
+;; All of these rules should pass the bounds check
+(type b_t1)
+(type b_t1_c)
+(typebounds b_t1 b_t1_c)
+
+(allow b_t1 self (CLASS (PERM)))
+(allow b_t1_c self (CLASS (PERM)))
+(allow b_t1 b_ta (CLASS (PERM)))
+(allow b_t1_c b_ta (CLASS (PERM)))
+(allow b_ta b_t1 (CLASS (PERM)))
+(allow b_ta b_t1_c (CLASS (PERM)))
+
+(booleanif b_b1
+ (false
+ (allow b_t1 b_tb (CLASS (PERM)))
+ (allow b_t1_c b_tb (CLASS (PERM)))
+ (allow b_tb b_t1 (CLASS (PERM)))
+ (allow b_tb b_t1_c (CLASS (PERM)))))
+
+(allow b_t1 b_tc (CLASS (PERM)))
+(allow b_tc b_t1 (CLASS (PERM)))
+(booleanif b_b2
+ (false
+ (allow b_t1_c b_tc (CLASS (PERM)))
+ (allow b_tc b_t1_c (CLASS (PERM)))))
+
+(allow b_t1_c b_td (CLASS (PERM)))
+(allow b_td b_t1_c (CLASS (PERM)))
+(booleanif b_b3
+ (true
+ (allow b_t1 b_td (CLASS (PERM)))
+ (allow b_td b_t1 (CLASS (PERM))))
+ (false
+ (allow b_t1 b_td (CLASS (PERM)))
+ (allow b_td b_t1 (CLASS (PERM)))))
+
+
+;; All of these rules should pass the bounds check
+(type b_t2)
+(type b_t2_c)
+(typebounds b_t2 b_t2_c)
+(typeattribute b_a2)
+(typeattribute b_a2_c)
+(typeattributeset b_a2 b_t2)
+(typeattributeset b_a2_c b_t2_c)
+
+(allow b_a2 self (CLASS (PERM)))
+(allow b_a2_c self (CLASS (PERM)))
+(allow b_a2 b_ta (CLASS (PERM)))
+(allow b_a2_c b_ta (CLASS (PERM)))
+(allow b_ta b_a2 (CLASS (PERM)))
+(allow b_ta b_a2_c (CLASS (PERM)))
+
+(booleanif b_b1
+ (false
+ (allow b_a2 b_tb (CLASS (PERM)))
+ (allow b_a2_c b_tb (CLASS (PERM)))
+ (allow b_tb b_a2 (CLASS (PERM)))
+ (allow b_tb b_a2_c (CLASS (PERM)))))
+
+(allow b_a2 b_tc (CLASS (PERM)))
+(allow b_tc b_a2 (CLASS (PERM)))
+(booleanif b_b2
+ (false
+ (allow b_a2_c b_tc (CLASS (PERM)))
+ (allow b_tc b_a2_c (CLASS (PERM)))))
+
+(allow b_a2_c b_td (CLASS (PERM)))
+(allow b_td b_a2_c (CLASS (PERM)))
+(booleanif b_b3
+ (true
+ (allow b_a2 b_td (CLASS (PERM)))
+ (allow b_td b_a2 (CLASS (PERM))))
+ (false
+ (allow b_a2 b_td (CLASS (PERM)))
+ (allow b_td b_a2 (CLASS (PERM)))))
+
+
+;; All of these rules should fail the bounds check
+(type b_t3)
+(type b_t3_c)
+(typebounds b_t3 b_t3_c)
+
+(allow b_t3 self (CLASS (PERM)))
+(allow b_t3_c self (c1 (p1a)))
+(allow b_t3 b_ta (CLASS (PERM)))
+(allow b_t3_c b_ta (c1 (p1a)))
+(allow b_ta b_t3 (CLASS (PERM)))
+(allow b_ta b_t3_c (c1 (p1a)))
+
+(booleanif b_b1
+ (false
+ (allow b_t3_c b_tb (c1 (p1a)))
+ (allow b_tb b_t3_c (c1 (p1a)))))
+
+(booleanif b_b2
+ (true
+ (allow b_t3_c b_tc (c1 (p1a)))
+ (allow b_tc b_t3_c (c1 (p1a))))
+ (false
+ (allow b_t3 b_tc (c1 (p1a)))
+ (allow b_tc b_t3 (c1 (p1a)))))
+
+(allow b_t3_c b_td (c1 (p1a)))
+(allow b_td b_t3_c (c1 (p1a)))
+(booleanif b_b3
+ (false
+ (allow b_t3 b_td (c1 (p1a)))
+ (allow b_td b_t3 (c1 (p1a)))))
+
+
+;; All of these rules should fail the bounds check
+(type b_t4)
+(type b_t4_c)
+(typebounds b_t4 b_t4_c)
+(typeattribute b_a4)
+(typeattribute b_a4_c)
+(typeattributeset b_a4 b_t4)
+(typeattributeset b_a4_c b_t4_c)
+
+(allow b_a4 self (CLASS (PERM)))
+(allow b_a4_c self (c1 (p1a)))
+(allow b_a4 b_ta (CLASS (PERM)))
+(allow b_a4_c b_ta (c1 (p1a)))
+(allow b_ta b_a4 (CLASS (PERM)))
+(allow b_ta b_a4_c (c1 (p1a)))
+
+(booleanif b_b1
+ (false
+ (allow b_a4_c b_tb (c1 (p1a)))
+ (allow b_tb b_a4_c (c1 (p1a)))))
+
+(booleanif b_b2
+ (true
+ (allow b_a4_c b_tc (c1 (p1a)))
+ (allow b_tc b_a4_c (c1 (p1a))))
+ (false
+ (allow b_a4 b_tc (c1 (p1a)))
+ (allow b_tc b_a4 (c1 (p1a)))))
+
+(allow b_a4_c b_td (c1 (p1a)))
+(allow b_td b_a4_c (c1 (p1a)))
+(booleanif b_b3
+ (false
+ (allow b_a4 b_td (c1 (p1a)))
+ (allow b_td b_a4 (c1 (p1a)))))
+
+
+;; Marked rules should fail, all others should pass
+(type b_t5)
+(type b_t5_c)
+(typebounds b_t5 b_t5_c)
+
+(allow b_t5 b_ta cp1)
+(allow b_t5_c b_ta (c1 (p1a)))
+(allow b_t5_c b_ta (c2 (p2a)))
+(allow b_t5_c b_ta (c2 (p2b))) ;; Fail
+(allow b_t5_c b_ta (c3 (p3a))) ;; Fail
+
+(allow b_t5 b_tb (c1 (p1a p1b)))
+(allow b_t5 b_tb (c2 (p2a)))
+(allow b_t5_c b_tb cp1)
+
+(allow b_t5 b_tc (cm1 (mp1)))
+(allow b_t5_c b_tc (c1 (p1a)))
+(allow b_t5_c b_tc (c1 (p1b))) ;; Fail
+(allow b_t5_c b_tc (c2 (p2a))) ;; Fail
+
+(allow b_t5 b_tc (c1 (p1a)))
+(allow b_t5_c b_tc (cm1 (mp1)))
+
+
+;; Marked rules should fail, all others should pass
+(type b_t6a)
+(type b_t6a_c)
+(type b_t6b)
+(type b_t6b_c)
+(typebounds b_t6a b_t6a_c)
+(typebounds b_t6b b_t6b_c)
+
+(allow b_t6a b_t6b (CLASS (PERM)))
+(allow b_t6a_c b_t6b_c (CLASS (PERM)))
+
+;; Needs: (allow b_t6a b_t6b (c1 (p1a)))
+(allow b_t6a_c b_t6b (c1 (p1a))) ;; Fail
+(allow b_t6a_c b_t6b_c (c1 (p1a))) ;; Fail
+
+;; Needs: (allow b_t6a b_t6b (c2 (p2a)))
+(allow b_t6a b_t6b_c (c2 (p2a))) ;; Fail
+(allow b_t6a_c b_t6b (c2 (p2a))) ;; Fail
+(allow b_t6a_c b_t6b_c (c2 (p2a)))
+
+;; Needs: (allow b_t6a b_t6b (c3 (p3c)))
+(allow b_t6a b_t6b (c3 (p3a p3b)))
+(allow b_t6a b_t6b_c (c3 (p3b p3c))) ;; Fail
+(allow b_t6a_c b_t6b (c3 (p3a p3c))) ;; Fail
+(allow b_t6a_c b_t6b_c (c3 (p3a p3b p3c))) ;; Fail
diff --git a/secilc/test/neverallow.cil b/secilc/test/neverallow.cil
new file mode 100644
index 00000000..63515589
--- /dev/null
+++ b/secilc/test/neverallow.cil
@@ -0,0 +1,79 @@
+(class CLASS (PERM))
+(classorder (CLASS))
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(type TYPE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(allow TYPE self (CLASS (PERM)))
+(roletype ROLE TYPE)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
+
+(class c1 (p1a p1b p1c))
+(class c2 (p2a p2b p2c))
+(class c3 (p3a p3b p3c))
+
+(classorder (CLASS c1 c2 c3))
+
+(classpermission cp1)
+(classpermissionset cp1 (c1 (p1a p1b)))
+(classpermissionset cp1 (c2 (p2a)))
+
+(classmap cm1 (mp1))
+(classmapping cm1 mp1
+ (c1 (p1a)))
+
+(type t1)
+(type t2)
+(type t3)
+(type t4)
+(type t5)
+(type t6)
+(type t7)
+
+(typeattribute a1)
+(typeattribute a2)
+(typeattribute a3)
+(typeattribute a4)
+(typeattribute a5)
+(typeattribute a6)
+
+(typeattributeset a1 (t1 t2 t3 t4 t5))
+(typeattributeset a2 (t1 t2))
+(typeattributeset a3 (t3 t4))
+(typeattributeset a4 (t2 t3))
+(typeattributeset a5 (t5 t6))
+(typeattributeset a6 (t6 t7))
+
+(neverallow t1 t2 (c1 (p1a p1b)))
+(allow t1 t2 (c1 (p1a)))
+
+(neverallow t3 t4 (cm1 (mp1)))
+(allow t3 t4 (c1 (p1a)))
+
+(neverallow t5 t6 cp1)
+(allow t5 t6 (c1 (p1b)))
+(allow t5 t6 (c2 (p2a)))
+
+(neverallow a1 self (CLASS (PERM)))
+(allow t1 t1 (CLASS (PERM)))
+(allow t2 self (CLASS (PERM)))
+(allow a3 self (CLASS (PERM)))
+(allow a2 a4 (CLASS (PERM)))
+
+(neverallow a5 a6 (CLASS (PERM)))
+(allow t5 t7 (CLASS (PERM)))
+(allow t6 self (CLASS (PERM)))
+
+;; Should not call these violations
+(allow a1 self (c1 (p1a)))
+(allow a2 a3 (CLASS (PERM)))
+(allow t5 t6 (c2 (p2b)))
diff --git a/secilc/test/policy.cil b/secilc/test/policy.cil
index 25c85458..69103d14 100644
--- a/secilc/test/policy.cil
+++ b/secilc/test/policy.cil
@@ -91,6 +91,9 @@
;;(allow console_t console_device_t file_rw)
(allow console_t console_device_t (files (read)))
+ (permissionx ioctl_test (ioctl files (and (range 0x1600 0x19FF) (not (range 0x1750 0x175F)))))
+ (allowx console_t console_device_t ioctl_test)
+
(boolean secure_mode false)
(boolean console_login true)
@@ -114,9 +117,6 @@
(typealias sbin_t)
(typealiasactual sbin_t bin_t)
(typepermissive device_t)
- (typebounds device_t bin_t)
- ;;(typebounds bin_t kernel_t) ;; This statement and the next can be used
- ;;(typebounds kernel_t device_t) ;; to verify that circular bounds can be found
(typemember device_t bin_t file exec_t)
(typetransition device_t console_t files console_device_t)
@@ -124,7 +124,9 @@
(roleattribute foo_role)
(roleattribute bar_role)
(roleattribute baz_role)
+ (roleattribute foo_role_a)
(roleattributeset exec_role (or user_r system_r))
+ (roleattributeset foo_role_a (baz_r user_r system_r))
(roleattributeset foo_role (and exec_role system_r))
(roleattributeset bar_role (xor exec_role foo_role))
(roleattributeset baz_role (not user_r))
@@ -194,6 +196,7 @@
(role system_r)
(role user_r)
+ (role baz_r)
(roletype system_r bin_t)
(roletype system_r kernel_t)
@@ -203,17 +206,32 @@
(roletype exec_role bin_t)
(roletype exec_role exec_type)
(roleallow system_r user_r)
- (rolebounds system_r user_r)
(roletransition system_r bin_t file user_r)
(userrole foo_u foo_role)
(userlevel foo_u low)
+
+ (userattribute ua1)
+ (userattribute ua2)
+ (userattribute ua3)
+ (userattribute ua4)
+ (userattributeset ua1 (user_u system_u))
+ (userattributeset ua2 (foo_u system_u))
+ (userattributeset ua3 (and ua1 ua2))
+ (user u5)
+ (user u6)
+ (userlevel u5 low)
+ (userlevel u6 low)
+ (userrange u5 low_high)
+ (userrange u6 low_high)
+ (userattributeset ua4 (u5 u6))
+ (userrole ua4 foo_role_a)
+
(userrange foo_u low_high)
(userrole system_u system_r)
(userlevel system_u low)
(userrange system_u low_high)
- (userbounds system_u user_u)
(userrole user_u user_r)
(userlevel user_u (s0 (range c0 c2)))
@@ -255,7 +273,7 @@
(constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
(constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
- (constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 u2) ) )
+ (constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 ua4) ) )
(constrain (file (open)) (dom r1 r2))
(constrain (file (open)) (domby r1 r2))
(constrain (file (open)) (incomp r1 r2))
@@ -286,6 +304,7 @@
(macro all ((type x))
(allow x bin_t (policy.file (execute)))
+ (allowx x bin_t (ioctl policy.file (range 0x1000 0x11FF)))
)
(call all (bin_t))
diff --git a/sepolgen/ChangeLog b/sepolgen/ChangeLog
index d2756bcb..3d598524 100644
--- a/sepolgen/ChangeLog
+++ b/sepolgen/ChangeLog
@@ -1,3 +1,8 @@
+ * Reset line numbers when parsing files, from Nicolas Iooss.
+ * Convert cmp functions to key functions, from Robert Kuska.
+ * Decode output from Popen in Python3, from Robert Kuska.
+ * Comment constraint rules in output, from Miroslav Grepl via Petr Lautrbach.
+ * Add support for python3, from Robert Kuska.
* Add device tree ocontext nodes to Xen policy, from Daniel De Graaf.
1.2.2 2015-02-02
diff --git a/sepolgen/src/sepolgen/access.py b/sepolgen/src/sepolgen/access.py
index cf132104..1f89ecde 100644
--- a/sepolgen/src/sepolgen/access.py
+++ b/sepolgen/src/sepolgen/access.py
@@ -31,7 +31,9 @@ and sets of that access (AccessVectorSet). These objects are used in Madison
in a variety of ways, but they are the fundamental representation of access.
"""
-import refpolicy
+from . import refpolicy
+from . import util
+
from selinux import audit2why
def is_idparam(id):
@@ -51,7 +53,7 @@ def is_idparam(id):
else:
return False
-class AccessVector:
+class AccessVector(util.Comparison):
"""
An access vector is the basic unit of access in SELinux.
@@ -88,6 +90,9 @@ class AccessVector:
self.audit_msgs = []
self.type = audit2why.TERULE
self.data = []
+ # when implementing __eq__ also __hash__ is needed on py2
+ # if object is muttable __hash__ should be None
+ self.__hash__ = None
# The direction of the information flow represented by this
# access vector - used for matching
@@ -133,23 +138,19 @@ class AccessVector:
return "allow %s %s:%s %s;" % (self.src_type, self.tgt_type,
self.obj_class, self.perms.to_space_str())
- def __cmp__(self, other):
- if self.src_type != other.src_type:
- return cmp(self.src_type, other.src_type)
- if self.tgt_type != other.tgt_type:
- return cmp(self.tgt_type, other.tgt_type)
- if self.obj_class != self.obj_class:
- return cmp(self.obj_class, other.obj_class)
- if len(self.perms) != len(other.perms):
- return cmp(len(self.perms), len(other.perms))
- x = list(self.perms)
- x.sort()
- y = list(other.perms)
- y.sort()
- for pa, pb in zip(x, y):
- if pa != pb:
- return cmp(pa, pb)
- return 0
+ def _compare(self, other, method):
+ try:
+ x = list(self.perms)
+ a = (self.src_type, self.tgt_type, self.obj_class, x)
+ y = list(other.perms)
+ x.sort()
+ y.sort()
+ b = (other.src_type, other.tgt_type, other.obj_class, y)
+ return method(a, b)
+ except (AttributeError, TypeError):
+ # trying to compare to foreign type
+ return NotImplemented
+
def avrule_to_access_vectors(avrule):
"""Convert an avrule into a list of access vectors.
@@ -262,7 +263,7 @@ class AccessVectorSet:
tgt = self.src.setdefault(src_type, { })
cls = tgt.setdefault(tgt_type, { })
- if cls.has_key((obj_class, avc_type)):
+ if (obj_class, avc_type) in cls:
access = cls[obj_class, avc_type]
else:
access = AccessVector()
@@ -293,7 +294,7 @@ def avs_extract_types(avs):
def avs_extract_obj_perms(avs):
perms = { }
for av in avs:
- if perms.has_key(av.obj_class):
+ if av.obj_class in perms:
s = perms[av.obj_class]
else:
s = refpolicy.IdSet()
@@ -321,7 +322,7 @@ class RoleTypeSet:
return len(self.role_types.keys())
def add(self, role, type):
- if self.role_types.has_key(role):
+ if role in self.role_types:
role_type = self.role_types[role]
else:
role_type = refpolicy.RoleType()
diff --git a/sepolgen/src/sepolgen/audit.py b/sepolgen/src/sepolgen/audit.py
index 56919be7..724d3ea6 100644
--- a/sepolgen/src/sepolgen/audit.py
+++ b/sepolgen/src/sepolgen/audit.py
@@ -17,11 +17,12 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
-import refpolicy
-import access
import re
import sys
+from . import refpolicy
+from . import access
+from . import util
# Convenience functions
def get_audit_boot_msgs():
@@ -42,6 +43,8 @@ def get_audit_boot_msgs():
boottime = time.strftime("%X", s)
output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR", "-ts", bootdate, boottime],
stdout=subprocess.PIPE).communicate()[0]
+ if util.PY3:
+ output = util.decode_input(output)
return output
def get_audit_msgs():
@@ -55,6 +58,8 @@ def get_audit_msgs():
import subprocess
output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR"],
stdout=subprocess.PIPE).communicate()[0]
+ if util.PY3:
+ output = util.decode_input(output)
return output
def get_dmesg_msgs():
@@ -66,6 +71,8 @@ def get_dmesg_msgs():
import subprocess
output = subprocess.Popen(["/bin/dmesg"],
stdout=subprocess.PIPE).communicate()[0]
+ if util.PY3:
+ output = util.decode_input(output)
return output
# Classes representing audit messages
@@ -430,7 +437,7 @@ class AuditParser:
# Group by audit header
if msg.header != "":
- if self.by_header.has_key(msg.header):
+ if msg.header in self.by_header:
self.by_header[msg.header].append(msg)
else:
self.by_header[msg.header] = [msg]
diff --git a/sepolgen/src/sepolgen/classperms.py b/sepolgen/src/sepolgen/classperms.py
index c925dee1..f4fd8996 100644
--- a/sepolgen/src/sepolgen/classperms.py
+++ b/sepolgen/src/sepolgen/classperms.py
@@ -49,10 +49,10 @@ def t_NAME(t):
return t
def t_error(t):
- print "Illegal character '%s'" % t.value[0]
+ print("Illegal character '%s'" % t.value[0])
t.skip(1)
-import lex
+from . import lex
lex.lex()
def p_statements(p):
@@ -90,9 +90,9 @@ def p_names(p):
p[0] = [p[1]] + p[2]
def p_error(p):
- print "Syntax error on line %d %s [type=%s]" % (p.lineno, p.value, p.type)
+ print("Syntax error on line %d %s [type=%s]" % (p.lineno, p.value, p.type))
-import yacc
+from . import yacc
yacc.yacc()
@@ -112,5 +112,5 @@ test2 = """define(`all_filesystem_perms',`{ mount remount unmount getattr relabe
define(`all_security_perms',`{ compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot }')
"""
result = yacc.parse(txt)
-print result
+print(result)
diff --git a/sepolgen/src/sepolgen/defaults.py b/sepolgen/src/sepolgen/defaults.py
index 218bc7c4..95910639 100644
--- a/sepolgen/src/sepolgen/defaults.py
+++ b/sepolgen/src/sepolgen/defaults.py
@@ -36,14 +36,14 @@ class PathChoooser(object):
if ignore.match(line): continue
mo = consider.match(line)
if not mo:
- raise ValueError, "%s:%d: line is not in key = value format" % (pathname, lineno+1)
+ raise ValueError("%s:%d: line is not in key = value format" % (pathname, lineno+1))
self.config[mo.group(1)] = mo.group(2)
# We're only exporting one useful function, so why not be a function
def __call__(self, testfilename, pathset="SELINUX_DEVEL_PATH"):
paths = self.config.get(pathset, None)
if paths is None:
- raise ValueError, "%s was not in %s" % (pathset, self.config_pathname)
+ raise ValueError("%s was not in %s" % (pathset, self.config_pathname))
paths = paths.split(":")
for p in paths:
target = os.path.join(p, testfilename)
diff --git a/sepolgen/src/sepolgen/interfaces.py b/sepolgen/src/sepolgen/interfaces.py
index 88a6dc30..0b688bfd 100644
--- a/sepolgen/src/sepolgen/interfaces.py
+++ b/sepolgen/src/sepolgen/interfaces.py
@@ -21,15 +21,15 @@
Classes for representing and manipulating interfaces.
"""
-import access
-import refpolicy
+import copy
import itertools
-import objectmodel
-import matching
-from sepolgeni18n import _
+from . import access
+from . import refpolicy
+from . import objectmodel
+from . import matching
+from .sepolgeni18n import _
-import copy
class Param:
"""
@@ -276,7 +276,7 @@ class InterfaceVector:
if attributes:
for typeattribute in interface.typeattributes():
for attr in typeattribute.attributes:
- if not attributes.attributes.has_key(attr):
+ if attr not in attributes.attributes:
# print "missing attribute " + attr
continue
attr_vec = attributes.attributes[attr]
diff --git a/sepolgen/src/sepolgen/lex.py b/sepolgen/src/sepolgen/lex.py
index c1493665..c13acef0 100644
--- a/sepolgen/src/sepolgen/lex.py
+++ b/sepolgen/src/sepolgen/lex.py
@@ -26,18 +26,21 @@ __version__ = "2.2"
import re, sys, types
+from . import util
+import collections
+
+
# Regular expression used to match valid token names
_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$')
-# Available instance types. This is used when lexers are defined by a class.
-# It's a little funky because I want to preserve backwards compatibility
-# with Python 2.0 where types.ObjectType is undefined.
+# Available instance types. This is used when parsers are defined by a class.
+# In Python3 the InstanceType and ObjectType are no more, they've passed, ceased
+# to be, they are ex-classes along with old-style classes
try:
_INSTANCETYPE = (types.InstanceType, types.ObjectType)
except AttributeError:
- _INSTANCETYPE = types.InstanceType
- class object: pass # Note: needed if no new-style classes present
+ _INSTANCETYPE = object
# Exception thrown when invalid token encountered and no default error
# handler is defined.
@@ -172,7 +175,7 @@ class Lexer:
# readtab() - Read lexer information from a tab file
# ------------------------------------------------------------
def readtab(self,tabfile,fdict):
- exec "import %s as lextab" % tabfile
+ exec("import %s as lextab" % tabfile)
self.lextokens = lextab._lextokens
self.lexreflags = lextab._lexreflags
self.lexliterals = lextab._lexliterals
@@ -197,8 +200,8 @@ class Lexer:
# input() - Push a new string into the lexer
# ------------------------------------------------------------
def input(self,s):
- if not (isinstance(s,types.StringType) or isinstance(s,types.UnicodeType)):
- raise ValueError, "Expected a string"
+ if not (isinstance(s,util.bytes_type) or isinstance(s, util.string_type)):
+ raise ValueError("Expected a string")
self.lexdata = s
self.lexpos = 0
self.lexlen = len(s)
@@ -207,8 +210,8 @@ class Lexer:
# begin() - Changes the lexing state
# ------------------------------------------------------------
def begin(self,state):
- if not self.lexstatere.has_key(state):
- raise ValueError, "Undefined state"
+ if state not in self.lexstatere:
+ raise ValueError("Undefined state")
self.lexre = self.lexstatere[state]
self.lexretext = self.lexstateretext[state]
self.lexignore = self.lexstateignore.get(state,"")
@@ -286,7 +289,7 @@ class Lexer:
break
# if func not callable, it means it's an ignored token
- if not callable(func):
+ if not isinstance(func, collections.Callable):
break
# If token is processed by a function, call it
@@ -299,9 +302,9 @@ class Lexer:
# Verify type of the token. If not in the token map, raise an error
if not self.lexoptimize:
- if not self.lextokens.has_key(newtok.type):
- raise LexError, ("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
- func.func_code.co_filename, func.func_code.co_firstlineno,
+ if newtok.type not in self.lextokens:
+ raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
+ func.__code__.co_filename, func.__code__.co_firstlineno,
func.__name__, newtok.type),lexdata[lexpos:])
return newtok
@@ -329,17 +332,17 @@ class Lexer:
newtok = self.lexerrorf(tok)
if lexpos == self.lexpos:
# Error method didn't change text position at all. This is an error.
- raise LexError, ("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
+ raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
lexpos = self.lexpos
if not newtok: continue
return newtok
self.lexpos = lexpos
- raise LexError, ("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
+ raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
self.lexpos = lexpos + 1
if self.lexdata is None:
- raise RuntimeError, "No input string given with input()"
+ raise RuntimeError("No input string given with input()")
return None
# -----------------------------------------------------------------------------
@@ -377,7 +380,7 @@ def _validate_file(filename):
if not prev:
counthash[name] = linen
else:
- print "%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev)
+ print("%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev))
noerror = 0
linen += 1
return noerror
@@ -439,12 +442,12 @@ def _form_master_re(relist,reflags,ldict):
# callback function to carry out the action
if f.find("ignore_") > 0:
lexindexfunc[i] = (None,None)
- print "IGNORE", f
+ print("IGNORE", f)
else:
lexindexfunc[i] = (None, f[2:])
return [(lexre,lexindexfunc)],[regex]
- except Exception,e:
+ except Exception as e:
m = int(len(relist)/2)
if m == 0: m = 1
llist, lre = _form_master_re(relist[:m],reflags,ldict)
@@ -464,7 +467,7 @@ def _statetoken(s,names):
nonstate = 1
parts = s.split("_")
for i in range(1,len(parts)):
- if not names.has_key(parts[i]) and parts[i] != 'ANY': break
+ if parts[i] not in names and parts[i] != 'ANY': break
if i > 1:
states = tuple(parts[1:i])
else:
@@ -507,7 +510,7 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
for (i,v) in _items:
ldict[i] = v
else:
- raise ValueError,"Expected a module or instance"
+ raise ValueError("Expected a module or instance")
lexobj.lexmodule = module
else:
@@ -542,61 +545,64 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
literals = ldict.get("literals","")
if not tokens:
- raise SyntaxError,"lex: module does not define 'tokens'"
- if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
- raise SyntaxError,"lex: tokens must be a list or tuple."
+ raise SyntaxError("lex: module does not define 'tokens'")
+ if not (isinstance(tokens,list) or isinstance(tokens,tuple)):
+ raise SyntaxError("lex: tokens must be a list or tuple.")
# Build a dictionary of valid token names
lexobj.lextokens = { }
if not optimize:
for n in tokens:
if not _is_identifier.match(n):
- print "lex: Bad token name '%s'" % n
+ print("lex: Bad token name '%s'" % n)
error = 1
- if warn and lexobj.lextokens.has_key(n):
- print "lex: Warning. Token '%s' multiply defined." % n
+ if warn and n in lexobj.lextokens:
+ print("lex: Warning. Token '%s' multiply defined." % n)
lexobj.lextokens[n] = None
else:
for n in tokens: lexobj.lextokens[n] = None
if debug:
- print "lex: tokens = '%s'" % lexobj.lextokens.keys()
+ print("lex: tokens = '%s'" % list(lexobj.lextokens.keys()))
try:
for c in literals:
- if not (isinstance(c,types.StringType) or isinstance(c,types.UnicodeType)) or len(c) > 1:
- print "lex: Invalid literal %s. Must be a single character" % repr(c)
+ if not (isinstance(c,util.bytes_type) or isinstance(c, util.string_type)) or len(c) > 1:
+ print("lex: Invalid literal %s. Must be a single character" % repr(c))
error = 1
continue
except TypeError:
- print "lex: Invalid literals specification. literals must be a sequence of characters."
+ print("lex: Invalid literals specification. literals must be a sequence of characters.")
error = 1
lexobj.lexliterals = literals
# Build statemap
if states:
- if not (isinstance(states,types.TupleType) or isinstance(states,types.ListType)):
- print "lex: states must be defined as a tuple or list."
+ if not (isinstance(states,tuple) or isinstance(states,list)):
+ print("lex: states must be defined as a tuple or list.")
error = 1
else:
for s in states:
- if not isinstance(s,types.TupleType) or len(s) != 2:
- print "lex: invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')" % repr(s)
+ if not isinstance(s,tuple) or len(s) != 2:
+ print("lex: invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')" % repr(s))
error = 1
continue
name, statetype = s
- if not isinstance(name,types.StringType):
- print "lex: state name %s must be a string" % repr(name)
+ if isinstance(name, util.string_type):
+ original_name = name
+ name = util.encode_input(name)
+ if not isinstance(name,util.bytes_type) or len(original_name) != len(name):
+ print("lex: state name %s must be a byte string" % repr(original_name))
error = 1
continue
if not (statetype == 'inclusive' or statetype == 'exclusive'):
- print "lex: state type for state %s must be 'inclusive' or 'exclusive'" % name
+ print("lex: state type for state %s must be 'inclusive' or 'exclusive'" % name)
error = 1
continue
- if stateinfo.has_key(name):
- print "lex: state '%s' already defined." % name
+ if name in stateinfo:
+ print("lex: state '%s' already defined." % name)
error = 1
continue
stateinfo[name] = statetype
@@ -618,28 +624,28 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
errorf = { } # Error functions by state
if len(tsymbols) == 0:
- raise SyntaxError,"lex: no rules of the form t_rulename are defined."
+ raise SyntaxError("lex: no rules of the form t_rulename are defined.")
for f in tsymbols:
t = ldict[f]
states, tokname = _statetoken(f,stateinfo)
toknames[f] = tokname
- if callable(t):
+ if isinstance(t, collections.Callable):
for s in states: funcsym[s].append((f,t))
- elif (isinstance(t, types.StringType) or isinstance(t,types.UnicodeType)):
+ elif (isinstance(t, util.bytes_type) or isinstance(t,util.string_type)):
for s in states: strsym[s].append((f,t))
else:
- print "lex: %s not defined as a function or string" % f
+ print("lex: %s not defined as a function or string" % f)
error = 1
# Sort the functions by line number
for f in funcsym.values():
- f.sort(lambda x,y: cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno))
+ f.sort(key=lambda x: x[1].__code__.co_firstlineno)
# Sort the strings by regular expression length
for s in strsym.values():
- s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
+ s.sort(key=lambda x: len(x[1]))
regexs = { }
@@ -649,31 +655,31 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
# Add rules defined by functions first
for fname, f in funcsym[state]:
- line = f.func_code.co_firstlineno
- file = f.func_code.co_filename
+ line = f.__code__.co_firstlineno
+ file = f.__code__.co_filename
files[file] = None
tokname = toknames[fname]
ismethod = isinstance(f, types.MethodType)
if not optimize:
- nargs = f.func_code.co_argcount
+ nargs = f.__code__.co_argcount
if ismethod:
reqargs = 2
else:
reqargs = 1
if nargs > reqargs:
- print "%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__)
+ print("%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__))
error = 1
continue
if nargs < reqargs:
- print "%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__)
+ print("%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__))
error = 1
continue
if tokname == 'ignore':
- print "%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__)
+ print("%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__))
error = 1
continue
@@ -686,25 +692,25 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
try:
c = re.compile("(?P<%s>%s)" % (f.__name__,f.__doc__), re.VERBOSE | reflags)
if c.match(""):
- print "%s:%d: Regular expression for rule '%s' matches empty string." % (file,line,f.__name__)
+ print("%s:%d: Regular expression for rule '%s' matches empty string." % (file,line,f.__name__))
error = 1
continue
- except re.error,e:
- print "%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e)
+ except re.error as e:
+ print("%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e))
if '#' in f.__doc__:
- print "%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'." % (file,line, f.__name__)
+ print("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'." % (file,line, f.__name__))
error = 1
continue
if debug:
- print "lex: Adding rule %s -> '%s' (state '%s')" % (f.__name__,f.__doc__, state)
+ print("lex: Adding rule %s -> '%s' (state '%s')" % (f.__name__,f.__doc__, state))
# Okay. The regular expression seemed okay. Let's append it to the master regular
# expression we're building
regex_list.append("(?P<%s>%s)" % (f.__name__,f.__doc__))
else:
- print "%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__)
+ print("%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__))
# Now add all of the simple rules
for name,r in strsym[state]:
@@ -716,34 +722,34 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
if not optimize:
if tokname == 'error':
- raise SyntaxError,"lex: Rule '%s' must be defined as a function" % name
+ raise SyntaxError("lex: Rule '%s' must be defined as a function" % name)
error = 1
continue
- if not lexobj.lextokens.has_key(tokname) and tokname.find("ignore_") < 0:
- print "lex: Rule '%s' defined for an unspecified token %s." % (name,tokname)
+ if tokname not in lexobj.lextokens and tokname.find("ignore_") < 0:
+ print("lex: Rule '%s' defined for an unspecified token %s." % (name,tokname))
error = 1
continue
try:
c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | reflags)
if (c.match("")):
- print "lex: Regular expression for rule '%s' matches empty string." % name
+ print("lex: Regular expression for rule '%s' matches empty string." % name)
error = 1
continue
- except re.error,e:
- print "lex: Invalid regular expression for rule '%s'. %s" % (name,e)
+ except re.error as e:
+ print("lex: Invalid regular expression for rule '%s'. %s" % (name,e))
if '#' in r:
- print "lex: Make sure '#' in rule '%s' is escaped with '\\#'." % name
+ print("lex: Make sure '#' in rule '%s' is escaped with '\\#'." % name)
error = 1
continue
if debug:
- print "lex: Adding rule %s -> '%s' (state '%s')" % (name,r,state)
+ print("lex: Adding rule %s -> '%s' (state '%s')" % (name,r,state))
regex_list.append("(?P<%s>%s)" % (name,r))
if not regex_list:
- print "lex: No rules defined for state '%s'" % state
+ print("lex: No rules defined for state '%s'" % state)
error = 1
regexs[state] = regex_list
@@ -755,7 +761,7 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
error = 1
if error:
- raise SyntaxError,"lex: Unable to build lexer."
+ raise SyntaxError("lex: Unable to build lexer.")
# From this point forward, we're reasonably confident that we can build the lexer.
# No more errors will be generated, but there might be some warning messages.
@@ -768,7 +774,7 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
lexobj.lexstateretext[state] = re_text
if debug:
for i in range(len(re_text)):
- print "lex: state '%s'. regex[%d] = '%s'" % (state, i, re_text[i])
+ print("lex: state '%s'. regex[%d] = '%s'" % (state, i, re_text[i]))
# For inclusive states, we need to add the INITIAL state
for state,type in stateinfo.items():
@@ -788,19 +794,19 @@ def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,now
lexobj.lexstateerrorf = errorf
lexobj.lexerrorf = errorf.get("INITIAL",None)
if warn and not lexobj.lexerrorf:
- print "lex: Warning. no t_error rule is defined."
+ print("lex: Warning. no t_error rule is defined.")
# Check state information for ignore and error rules
for s,stype in stateinfo.items():
if stype == 'exclusive':
- if warn and not errorf.has_key(s):
- print "lex: Warning. no error rule is defined for exclusive state '%s'" % s
- if warn and not ignore.has_key(s) and lexobj.lexignore:
- print "lex: Warning. no ignore rule is defined for exclusive state '%s'" % s
+ if warn and s not in errorf:
+ print("lex: Warning. no error rule is defined for exclusive state '%s'" % s)
+ if warn and s not in ignore and lexobj.lexignore:
+ print("lex: Warning. no ignore rule is defined for exclusive state '%s'" % s)
elif stype == 'inclusive':
- if not errorf.has_key(s):
+ if s not in errorf:
errorf[s] = errorf.get("INITIAL",None)
- if not ignore.has_key(s):
+ if s not in ignore:
ignore[s] = ignore.get("INITIAL","")
@@ -829,7 +835,7 @@ def runmain(lexer=None,data=None):
data = f.read()
f.close()
except IndexError:
- print "Reading from standard input (type EOF to end):"
+ print("Reading from standard input (type EOF to end):")
data = sys.stdin.read()
if lexer:
@@ -845,7 +851,7 @@ def runmain(lexer=None,data=None):
while 1:
tok = _token()
if not tok: break
- print "(%s,%r,%d,%d)" % (tok.type, tok.value, tok.lineno,tok.lexpos)
+ print("(%s,%r,%d,%d)" % (tok.type, tok.value, tok.lineno,tok.lexpos))
# -----------------------------------------------------------------------------
diff --git a/sepolgen/src/sepolgen/matching.py b/sepolgen/src/sepolgen/matching.py
index d56dd92d..6f86359d 100644
--- a/sepolgen/src/sepolgen/matching.py
+++ b/sepolgen/src/sepolgen/matching.py
@@ -21,33 +21,30 @@
Classes and algorithms for matching requested access to access vectors.
"""
-import access
-import objectmodel
import itertools
-class Match:
+from . import access
+from . import objectmodel
+from . import util
+
+
+class Match(util.Comparison):
def __init__(self, interface=None, dist=0):
self.interface = interface
self.dist = dist
self.info_dir_change = False
-
- def __cmp__(self, other):
- if self.dist == other.dist:
- if self.info_dir_change:
- if other.info_dir_change:
- return 0
- else:
- return 1
- else:
- if other.info_dir_change:
- return -1
- else:
- return 0
- else:
- if self.dist < other.dist:
- return -1
- else:
- return 1
+ # when implementing __eq__ also __hash__ is needed on py2
+ # if object is muttable __hash__ should be None
+ self.__hash__ = None
+
+ def _compare(self, other, method):
+ try:
+ a = (self.dist, self.info_dir_change)
+ b = (other.dist, other.info_dir_change)
+ return method(a, b)
+ except (AttributeError, TypeError):
+ # trying to compare to foreign type
+ return NotImplemented
class MatchList:
DEFAULT_THRESHOLD = 150
diff --git a/sepolgen/src/sepolgen/module.py b/sepolgen/src/sepolgen/module.py
index 7fc94434..c09676aa 100644
--- a/sepolgen/src/sepolgen/module.py
+++ b/sepolgen/src/sepolgen/module.py
@@ -22,18 +22,21 @@ Utilities for dealing with the compilation of modules and creation
of module tress.
"""
-import defaults
-
-import selinux
-
import re
import tempfile
-import commands
+try:
+ from subprocess import getstatusoutput
+except ImportError:
+ from commands import getstatusoutput
import os
import os.path
-import subprocess
import shutil
+import selinux
+
+from . import defaults
+
+
def is_valid_name(modname):
"""Check that a module name is valid.
"""
@@ -130,7 +133,7 @@ class ModuleCompiler:
def run(self, command):
self.o(command)
- rc, output = commands.getstatusoutput(command)
+ rc, output = getstatusoutput(command)
self.o(output)
return rc
diff --git a/sepolgen/src/sepolgen/objectmodel.py b/sepolgen/src/sepolgen/objectmodel.py
index 88c8a1f4..d05d721f 100644
--- a/sepolgen/src/sepolgen/objectmodel.py
+++ b/sepolgen/src/sepolgen/objectmodel.py
@@ -118,7 +118,7 @@ class PermMappings:
continue
if fields[0] == "class":
c = fields[1]
- if self.classes.has_key(c):
+ if c in self.classes:
raise ValueError("duplicate class in perm map")
self.classes[c] = { }
cur = self.classes[c]
diff --git a/sepolgen/src/sepolgen/output.py b/sepolgen/src/sepolgen/output.py
index 739452db..7a83aee4 100644
--- a/sepolgen/src/sepolgen/output.py
+++ b/sepolgen/src/sepolgen/output.py
@@ -27,8 +27,12 @@ generating policy. This keeps the semantic / syntactic issues
cleanly separated from the formatting issues.
"""
-import refpolicy
-import util
+from . import refpolicy
+from . import util
+
+if util.PY3:
+ from .util import cmp
+
class ModuleWriter:
def __init__(self):
@@ -127,7 +131,7 @@ def sort_filter(module):
rules = []
rules.extend(node.avrules())
rules.extend(node.interface_calls())
- rules.sort(rule_cmp)
+ rules.sort(key=util.cmp_to_key(rule_cmp))
cur = None
sep_rules = []
@@ -151,7 +155,7 @@ def sort_filter(module):
ras = []
ras.extend(node.role_types())
- ras.sort(role_type_cmp)
+ ras.sort(key=util.cmp_to_key(role_type_cmp))
if len(ras):
comment = refpolicy.Comment()
comment.lines.append("============= ROLES ==============")
diff --git a/sepolgen/src/sepolgen/policygen.py b/sepolgen/src/sepolgen/policygen.py
index 5f385775..4438a110 100644
--- a/sepolgen/src/sepolgen/policygen.py
+++ b/sepolgen/src/sepolgen/policygen.py
@@ -24,17 +24,20 @@ classes and algorithms for the generation of SELinux policy.
import itertools
import textwrap
-import refpolicy
-import objectmodel
-import access
-import interfaces
-import matching
import selinux.audit2why as audit2why
try:
from setools import *
except:
pass
+from . import refpolicy
+from . import objectmodel
+from . import access
+from . import interfaces
+from . import matching
+from . import util
+if util.PY3:
+ from .util import cmp
# Constants for the level of explanation from the generation
# routines
NO_EXPLANATION = 0
@@ -167,14 +170,14 @@ class PolicyGenerator:
if av.type == audit2why.BOOLEAN:
if len(av.data) > 1:
- rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n# %s" % ", ".join(map(lambda x: x[0], av.data))
+ rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n# %s" % ", ".join([x[0] for x in av.data])
else:
rule.comment += "\n#!!!! This avc can be allowed using the boolean '%s'" % av.data[0][0]
if av.type == audit2why.CONSTRAINT:
rule.comment += "\n#!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access."
rule.comment += "\n#Constraint rule: "
- rule.comment += "\n\t" + av.data[0]
+ rule.comment += "\n#\t" + av.data[0]
for reason in av.data[1:]:
rule.comment += "\n#\tPossible cause is the source %s and target %s are different." % reason
@@ -186,7 +189,7 @@ class PolicyGenerator:
self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"]
types=[]
- for i in map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})):
+ for i in [x[TCONTEXT] for x in sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})]:
if i not in self.domains:
types.append(i)
if len(types) == 1:
@@ -296,7 +299,7 @@ def call_interface(interface, av):
elif params[i].type == refpolicy.OBJ_CLASS:
ifcall.args.append(av.obj_class)
else:
- print params[i].type
+ print(params[i].type)
assert(0)
assert(len(ifcall.args) > 0)
diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py
index 83542d3e..3132c6fe 100644
--- a/sepolgen/src/sepolgen/refparser.py
+++ b/sepolgen/src/sepolgen/refparser.py
@@ -34,12 +34,11 @@ import os
import re
import traceback
-import refpolicy
-import access
-import defaults
-
-import lex
-import yacc
+from . import access
+from . import defaults
+from . import lex
+from . import refpolicy
+from . import yacc
# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#
@@ -269,7 +268,7 @@ def t_comment(t):
t.lexer.lineno += 1
def t_error(t):
- print "Illegal character '%s'" % t.value[0]
+ print("Illegal character '%s'" % t.value[0])
t.skip(1)
def t_newline(t):
@@ -971,7 +970,7 @@ def p_optional_semi(p):
def p_error(tok):
global error, parse_file, success, parser
error = "%s: Syntax error on line %d %s [type=%s]" % (parse_file, tok.lineno, tok.value, tok.type)
- print error
+ print(error)
success = False
def prep_spt(spt):
@@ -1004,11 +1003,12 @@ def parse(text, module=None, support=None, debug=False):
create_globals(module, support, debug)
global error, parser, lexer, success
+ lexer.lineno = 1
success = True
try:
parser.parse(text, debug=debug, lexer=lexer)
- except Exception, e:
+ except Exception as e:
parser = None
lexer = None
error = "internal parser error: %s" % str(e) + "\n" + traceback.format_exc()
@@ -1041,7 +1041,7 @@ def list_headers(root):
def parse_headers(root, output=None, expand=True, debug=False):
- import util
+ from . import util
headers = refpolicy.Headers()
@@ -1075,9 +1075,9 @@ def parse_headers(root, output=None, expand=True, debug=False):
fd.close()
parse_file = f
parse(txt, module, spt, debug)
- except IOError, e:
+ except IOError as e:
return
- except ValueError, e:
+ except ValueError as e:
raise ValueError("error parsing file %s: %s" % (f, str(e)))
spt = None
@@ -1113,7 +1113,7 @@ def parse_headers(root, output=None, expand=True, debug=False):
parse_file(x[1], m, spt)
else:
parse_file(x[1], m)
- except ValueError, e:
+ except ValueError as e:
o(str(e) + "\n")
failures.append(x[1])
continue
diff --git a/sepolgen/src/sepolgen/refpolicy.py b/sepolgen/src/sepolgen/refpolicy.py
index b8ed5c19..737f9562 100644
--- a/sepolgen/src/sepolgen/refpolicy.py
+++ b/sepolgen/src/sepolgen/refpolicy.py
@@ -18,7 +18,6 @@
#
import string
-import itertools
import selinux
# OVERVIEW
@@ -85,53 +84,53 @@ class Node(PolicyBase):
# Top level nodes
def nodes(self):
- return itertools.ifilter(lambda x: isinstance(x, Node), walktree(self))
+ return filter(lambda x: isinstance(x, Node), walktree(self))
def modules(self):
- return itertools.ifilter(lambda x: isinstance(x, Module), walktree(self))
+ return filter(lambda x: isinstance(x, Module), walktree(self))
def interfaces(self):
- return itertools.ifilter(lambda x: isinstance(x, Interface), walktree(self))
+ return filter(lambda x: isinstance(x, Interface), walktree(self))
def templates(self):
- return itertools.ifilter(lambda x: isinstance(x, Template), walktree(self))
+ return filter(lambda x: isinstance(x, Template), walktree(self))
def support_macros(self):
- return itertools.ifilter(lambda x: isinstance(x, SupportMacros), walktree(self))
+ return filter(lambda x: isinstance(x, SupportMacros), walktree(self))
# Common policy statements
def module_declarations(self):
- return itertools.ifilter(lambda x: isinstance(x, ModuleDeclaration), walktree(self))
+ return filter(lambda x: isinstance(x, ModuleDeclaration), walktree(self))
def interface_calls(self):
- return itertools.ifilter(lambda x: isinstance(x, InterfaceCall), walktree(self))
+ return filter(lambda x: isinstance(x, InterfaceCall), walktree(self))
def avrules(self):
- return itertools.ifilter(lambda x: isinstance(x, AVRule), walktree(self))
+ return filter(lambda x: isinstance(x, AVRule), walktree(self))
def typerules(self):
- return itertools.ifilter(lambda x: isinstance(x, TypeRule), walktree(self))
+ return filter(lambda x: isinstance(x, TypeRule), walktree(self))
def typeattributes(self):
"""Iterate over all of the TypeAttribute children of this Interface."""
- return itertools.ifilter(lambda x: isinstance(x, TypeAttribute), walktree(self))
+ return filter(lambda x: isinstance(x, TypeAttribute), walktree(self))
def roleattributes(self):
"""Iterate over all of the RoleAttribute children of this Interface."""
- return itertools.ifilter(lambda x: isinstance(x, RoleAttribute), walktree(self))
+ return filter(lambda x: isinstance(x, RoleAttribute), walktree(self))
def requires(self):
- return itertools.ifilter(lambda x: isinstance(x, Require), walktree(self))
+ return filter(lambda x: isinstance(x, Require), walktree(self))
def roles(self):
- return itertools.ifilter(lambda x: isinstance(x, Role), walktree(self))
+ return filter(lambda x: isinstance(x, Role), walktree(self))
def role_allows(self):
- return itertools.ifilter(lambda x: isinstance(x, RoleAllow), walktree(self))
+ return filter(lambda x: isinstance(x, RoleAllow), walktree(self))
def role_types(self):
- return itertools.ifilter(lambda x: isinstance(x, RoleType), walktree(self))
+ return filter(lambda x: isinstance(x, RoleType), walktree(self))
def __str__(self):
if self.comment:
@@ -291,7 +290,7 @@ class SecurityContext(Leaf):
self.type = fields[2]
if len(fields) > 3:
# FUTURE - normalize level fields to allow more comparisons to succeed.
- self.level = string.join(fields[3:], ':')
+ self.level = ':'.join(fields[3:])
else:
self.level = None
@@ -703,7 +702,7 @@ def print_tree(head):
s = ""
for i in range(depth):
s = s + "\t"
- print s + str(node)
+ print(s + str(node))
class Headers(Node):
@@ -810,7 +809,7 @@ class SupportMacros(Node):
# are ordered correctly so that no macro is used before
# it is defined
s = set()
- if self.map.has_key(perm):
+ if perm in self.map:
for p in self.by_name(perm):
s.update(self.__expand_perm(p))
else:
@@ -833,7 +832,7 @@ class SupportMacros(Node):
def has_key(self, name):
if not self.map:
self.__gen_map()
- return self.map.has_key(name)
+ return name in self.map
class Require(Leaf):
def __init__(self, parent=None):
diff --git a/sepolgen/src/sepolgen/util.py b/sepolgen/src/sepolgen/util.py
index 74a11f51..1fca9717 100644
--- a/sepolgen/src/sepolgen/util.py
+++ b/sepolgen/src/sepolgen/util.py
@@ -16,6 +16,19 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
+import locale
+import sys
+
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+ bytes_type=bytes
+ string_type=str
+else:
+ bytes_type=str
+ string_type=unicode
+
class ConsoleProgressBar:
def __init__(self, out, steps=100, indicator='#'):
@@ -76,6 +89,88 @@ def first(s, sorted=False):
for x in s:
return x
+def encode_input(text):
+ import locale
+ """Encode given text via preferred system encoding"""
+ # locale will often find out the correct encoding
+ encoding = locale.getpreferredencoding()
+ try:
+ encoded_text = text.encode(encoding)
+ except UnicodeError:
+ # if it fails to find correct encoding then ascii is used
+ # which may lead to UnicodeError if `text` contains non ascii signs
+ # utf-8 is our guess to fix the situation
+ encoded_text = text.encode('utf-8')
+ return encoded_text
+
+def decode_input(text):
+ import locale
+ """Decode given text via preferred system encoding"""
+ # locale will often find out the correct encoding
+ encoding = locale.getpreferredencoding()
+ try:
+ decoded_text = text.decode(encoding)
+ except UnicodeError:
+ # if it fails to find correct encoding then ascii is used
+ # which may lead to UnicodeError if `text` contains non ascii signs
+ # utf-8 is our guess to fix the situation
+ decoded_text = text.decode('utf-8')
+ return decoded_text
+
+class Comparison():
+ """Class used when implementing rich comparison.
+
+ Inherit from this class if you want to have a rich
+ comparison withing the class, afterwards implement
+ _compare function within your class."""
+
+ def _compare(self, other, method):
+ raise NotImplemented
+
+ def __eq__(self, other):
+ return self._compare(other, lambda a, b: a == b)
+
+ def __lt__(self, other):
+ return self._compare(other, lambda a, b: a < b)
+
+ def __le__(self, other):
+ return self._compare(other, lambda a, b: a <= b)
+
+ def __ge__(self, other):
+ return self._compare(other, lambda a, b: a >= b)
+
+ def __gt__(self, other):
+ return self._compare(other, lambda a, b: a > b)
+
+ def __ne__(self, other):
+ return self._compare(other, lambda a, b: a != b)
+
+if sys.version_info < (2,7):
+ # cmp_to_key function is missing in python2.6
+ def cmp_to_key(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K:
+ def __init__(self, obj, *args):
+ self.obj = obj
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+ def __ne__(self, other):
+ return mycmp(self.obj, other.obj) != 0
+ return K
+else:
+ from functools import cmp_to_key
+
+def cmp(first, second):
+ return (first > second) - (second > first)
+
if __name__ == "__main__":
import sys
import time
diff --git a/sepolgen/src/sepolgen/yacc.py b/sepolgen/src/sepolgen/yacc.py
index bc4536de..f0063546 100644
--- a/sepolgen/src/sepolgen/yacc.py
+++ b/sepolgen/src/sepolgen/yacc.py
@@ -67,7 +67,13 @@ default_lr = 'LALR' # Default LR table generation method
error_count = 3 # Number of symbols that must be shifted to leave recovery mode
-import re, types, sys, cStringIO, hashlib, os.path
+import re, types, sys, hashlib, os.path
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+from . import util
# Exception raised for yacc-related errors
class YaccError(Exception): pass
@@ -109,7 +115,7 @@ class YaccProduction:
self.stack = stack
def __getitem__(self,n):
- if type(n) == types.IntType:
+ if type(n) == int:
if n >= 0: return self.slice[n].value
else: return self.stack[n].value
else:
@@ -139,9 +145,9 @@ class YaccProduction:
def pushback(self,n):
if n <= 0:
- raise ValueError, "Expected a positive value"
+ raise ValueError("Expected a positive value")
if n > (len(self.slice)-1):
- raise ValueError, "Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1)
+ raise ValueError("Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1))
for i in range(0,n):
self.pbstack.append(self.slice[-i-1])
@@ -157,7 +163,7 @@ class Parser:
# object directly.
if magic != "xyzzy":
- raise YaccError, "Can't instantiate Parser. Use yacc() instead."
+ raise YaccError("Can't instantiate Parser. Use yacc() instead.")
# Reset internal state
self.productions = None # List of productions
@@ -190,7 +196,7 @@ class Parser:
# If no lexer was given, we will try to use the lex module
if not lexer:
- import lex
+ from . import lex
lexer = lex.lexer
pslice.lexer = lexer
@@ -221,7 +227,7 @@ class Parser:
# is already set, we just use that. Otherwise, we'll pull
# the next token off of the lookaheadstack or from the lexer
if debug > 1:
- print 'state', statestack[-1]
+ print('state', statestack[-1])
if not lookahead:
if not lookaheadstack:
lookahead = get_token() # Get the next token
@@ -239,7 +245,7 @@ class Parser:
t = actions.get((s,ltype),None)
if debug > 1:
- print 'action', t
+ print('action', t)
if t is not None:
if t > 0:
# shift a symbol on the stack
@@ -396,7 +402,7 @@ class Parser:
continue
# Call an error function here
- raise RuntimeError, "yacc: internal parser error!!!\n"
+ raise RuntimeError("yacc: internal parser error!!!\n")
# -----------------------------------------------------------------------------
# === Parser Construction ===
@@ -457,12 +463,12 @@ def validate_dict(d):
if n[0:2] == 'p_':
sys.stderr.write("yacc: Warning. '%s' not defined as a function\n" % n)
- if 1 and isinstance(v,types.FunctionType) and v.func_code.co_argcount == 1:
+ if 1 and isinstance(v,types.FunctionType) and v.__code__.co_argcount == 1:
try:
doc = v.__doc__.split(" ")
if doc[1] == ':':
- sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.func_code.co_filename, v.func_code.co_firstlineno,n))
- except StandardError:
+ sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.__code__.co_filename, v.__code__.co_firstlineno,n))
+ except Exception:
pass
# -----------------------------------------------------------------------------
@@ -514,8 +520,8 @@ def initialize_vars():
# File objects used when creating the parser.out debugging file
global _vf, _vfc
- _vf = cStringIO.StringIO()
- _vfc = cStringIO.StringIO()
+ _vf = StringIO()
+ _vfc = StringIO()
# -----------------------------------------------------------------------------
# class Production:
@@ -581,7 +587,7 @@ class Production:
# Precompute list of productions immediately following
try:
p.lrafter = Prodnames[p.prod[n+1]]
- except (IndexError,KeyError),e:
+ except (IndexError,KeyError) as e:
p.lrafter = []
try:
p.lrbefore = p.prod[n-1]
@@ -615,7 +621,7 @@ _is_identifier = re.compile(r'^[a-zA-Z0-9_-~]+$')
def add_production(f,file,line,prodname,syms):
- if Terminals.has_key(prodname):
+ if prodname in Terminals:
sys.stderr.write("%s:%d: Illegal rule name '%s'. Already defined as a token.\n" % (file,line,prodname))
return -1
if prodname == 'error':
@@ -634,7 +640,7 @@ def add_production(f,file,line,prodname,syms):
if (len(c) > 1):
sys.stderr.write("%s:%d: Literal token %s in rule '%s' may only be a single character\n" % (file,line,s, prodname))
return -1
- if not Terminals.has_key(c):
+ if c not in Terminals:
Terminals[c] = []
syms[x] = c
continue
@@ -646,7 +652,7 @@ def add_production(f,file,line,prodname,syms):
# See if the rule is already in the rulemap
map = "%s -> %s" % (prodname,syms)
- if Prodmap.has_key(map):
+ if map in Prodmap:
m = Prodmap[map]
sys.stderr.write("%s:%d: Duplicate rule %s.\n" % (file,line, m))
sys.stderr.write("%s:%d: Previous definition at %s:%d\n" % (file,line, m.file, m.line))
@@ -663,7 +669,7 @@ def add_production(f,file,line,prodname,syms):
Productions.append(p)
Prodmap[map] = p
- if not Nonterminals.has_key(prodname):
+ if prodname not in Nonterminals:
Nonterminals[prodname] = [ ]
# Add all terminals to Terminals
@@ -687,13 +693,13 @@ def add_production(f,file,line,prodname,syms):
del p.prod[i]
continue
- if Terminals.has_key(t):
+ if t in Terminals:
Terminals[t].append(p.number)
# Is a terminal. We'll assign a precedence to p based on this
if not hasattr(p,"prec"):
p.prec = Precedence.get(t,('right',0))
else:
- if not Nonterminals.has_key(t):
+ if t not in Nonterminals:
Nonterminals[t] = [ ]
Nonterminals[t].append(p.number)
i += 1
@@ -722,8 +728,8 @@ def add_production(f,file,line,prodname,syms):
# and adds rules to the grammar
def add_function(f):
- line = f.func_code.co_firstlineno
- file = f.func_code.co_filename
+ line = f.__code__.co_firstlineno
+ file = f.__code__.co_filename
error = 0
if isinstance(f,types.MethodType):
@@ -731,11 +737,11 @@ def add_function(f):
else:
reqdargs = 1
- if f.func_code.co_argcount > reqdargs:
+ if f.__code__.co_argcount > reqdargs:
sys.stderr.write("%s:%d: Rule '%s' has too many arguments.\n" % (file,line,f.__name__))
return -1
- if f.func_code.co_argcount < reqdargs:
+ if f.__code__.co_argcount < reqdargs:
sys.stderr.write("%s:%d: Rule '%s' requires an argument.\n" % (file,line,f.__name__))
return -1
@@ -776,7 +782,7 @@ def add_function(f):
error += e
- except StandardError:
+ except Exception:
sys.stderr.write("%s:%d: Syntax error in rule '%s'\n" % (file,dline,ps))
error -= 1
else:
@@ -793,7 +799,7 @@ def compute_reachable():
(Unused terminals have already had their warning.)
'''
Reachable = { }
- for s in Terminals.keys() + Nonterminals.keys():
+ for s in list(Terminals.keys()) + list(Nonterminals.keys()):
Reachable[s] = 0
mark_reachable_from( Productions[0].prod[0], Reachable )
@@ -872,7 +878,7 @@ def compute_terminates():
some_error = 0
for (s,terminates) in Terminates.items():
if not terminates:
- if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
+ if s not in Prodnames and s not in Terminals and s != 'error':
# s is used-but-not-defined, and we've already warned of that,
# so it would be overkill to say that it's also non-terminating.
pass
@@ -893,7 +899,7 @@ def verify_productions(cycle_check=1):
if not p: continue
for s in p.prod:
- if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
+ if s not in Prodnames and s not in Terminals and s != 'error':
sys.stderr.write("%s:%d: Symbol '%s' used, but not defined as a token or a rule.\n" % (p.file,p.line,s))
error = 1
continue
@@ -935,12 +941,12 @@ def verify_productions(cycle_check=1):
if yaccdebug:
_vf.write("\nTerminals, with rules where they appear\n\n")
- ks = Terminals.keys()
+ ks = list(Terminals.keys())
ks.sort()
for k in ks:
_vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Terminals[k]])))
_vf.write("\nNonterminals, with rules where they appear\n\n")
- ks = Nonterminals.keys()
+ ks = list(Nonterminals.keys())
ks.sort()
for k in ks:
_vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Nonterminals[k]])))
@@ -1003,7 +1009,7 @@ def add_precedence(plist):
sys.stderr.write("yacc: Invalid precedence '%s'\n" % prec)
return -1
for t in terms:
- if Precedence.has_key(t):
+ if t in Precedence:
sys.stderr.write("yacc: Precedence already specified for terminal '%s'\n" % t)
error += 1
continue
@@ -1087,7 +1093,7 @@ def compute_follow(start=None):
# Here is the production set
for i in range(len(p.prod)):
B = p.prod[i]
- if Nonterminals.has_key(B):
+ if B in Nonterminals:
# Okay. We got a non-terminal in a production
fst = first(p.prod[i+1:])
hasempty = 0
@@ -1259,7 +1265,7 @@ def lr0_items():
for x in asyms.keys():
g = lr0_goto(I,x)
if not g: continue
- if _lr0_cidhash.has_key(id(g)): continue
+ if id(g) in _lr0_cidhash: continue
_lr0_cidhash[id(g)] = len(C)
C.append(g)
@@ -1305,7 +1311,7 @@ def compute_nullable_nonterminals():
nullable[p.name] = 1
continue
for t in p.prod:
- if not nullable.has_key(t): break
+ if t not in nullable: break
else:
nullable[p.name] = 1
if len(nullable) == num_nullable: break
@@ -1329,7 +1335,7 @@ def find_nonterminal_transitions(C):
for p in C[state]:
if p.lr_index < p.len - 1:
t = (state,p.prod[p.lr_index+1])
- if Nonterminals.has_key(t[1]):
+ if t[1] in Nonterminals:
if t not in trans: trans.append(t)
state = state + 1
return trans
@@ -1352,7 +1358,7 @@ def dr_relation(C,trans,nullable):
for p in g:
if p.lr_index < p.len - 1:
a = p.prod[p.lr_index+1]
- if Terminals.has_key(a):
+ if a in Terminals:
if a not in terms: terms.append(a)
# This extra bit is to handle the start state
@@ -1377,7 +1383,7 @@ def reads_relation(C, trans, empty):
for p in g:
if p.lr_index < p.len - 1:
a = p.prod[p.lr_index + 1]
- if empty.has_key(a):
+ if a in empty:
rel.append((j,a))
return rel
@@ -1437,15 +1443,15 @@ def compute_lookback_includes(C,trans,nullable):
t = p.prod[lr_index]
# Check to see if this symbol and state are a non-terminal transition
- if dtrans.has_key((j,t)):
+ if (j,t) in dtrans:
# Yes. Okay, there is some chance that this is an includes relation
# the only way to know for certain is whether the rest of the
# production derives empty
li = lr_index + 1
while li < p.len:
- if Terminals.has_key(p.prod[li]): break # No forget it
- if not nullable.has_key(p.prod[li]): break
+ if p.prod[li] in Terminals: break # No forget it
+ if p.prod[li] not in nullable: break
li = li + 1
else:
# Appears to be a relation between (j,t) and (state,N)
@@ -1466,7 +1472,7 @@ def compute_lookback_includes(C,trans,nullable):
else:
lookb.append((j,r))
for i in includes:
- if not includedict.has_key(i): includedict[i] = []
+ if i not in includedict: includedict[i] = []
includedict[i].append((state,N))
lookdict[(state,N)] = lookb
@@ -1513,11 +1519,11 @@ def traverse(x,N,stack,F,X,R,FP):
for a in F.get(y,[]):
if a not in F[x]: F[x].append(a)
if N[x] == d:
- N[stack[-1]] = sys.maxint
+ N[stack[-1]] = sys.maxsize
F[stack[-1]] = F[x]
element = stack.pop()
while element != x:
- N[stack[-1]] = sys.maxint
+ N[stack[-1]] = sys.maxsize
F[stack[-1]] = F[x]
element = stack.pop()
@@ -1577,7 +1583,7 @@ def add_lookaheads(lookbacks,followset):
for trans,lb in lookbacks.items():
# Loop over productions in lookback
for state,p in lb:
- if not p.lookaheads.has_key(state):
+ if state not in p.lookaheads:
p.lookaheads[state] = []
f = followset.get(trans,[])
for a in f:
@@ -1709,7 +1715,7 @@ def lr_parse_table(method):
else:
i = p.lr_index
a = p.prod[i+1] # Get symbol right after the "."
- if Terminals.has_key(a):
+ if a in Terminals:
g = lr0_goto(I,a)
j = _lr0_cidhash.get(id(g),-1)
if j >= 0:
@@ -1751,22 +1757,22 @@ def lr_parse_table(method):
action[st,a] = j
actionp[st,a] = p
- except StandardError,e:
- raise YaccError, "Hosed in lr_parse_table", e
+ except Exception as e:
+ raise YaccError("Hosed in lr_parse_table").with_traceback(e)
# Print the actions associated with each terminal
if yaccdebug:
_actprint = { }
for a,p,m in actlist:
- if action.has_key((st,a)):
+ if (st,a) in action:
if p is actionp[st,a]:
_vf.write(" %-15s %s\n" % (a,m))
_actprint[(a,m)] = 1
_vf.write("\n")
for a,p,m in actlist:
- if action.has_key((st,a)):
+ if (st,a) in action:
if p is not actionp[st,a]:
- if not _actprint.has_key((a,m)):
+ if (a,m) not in _actprint:
_vf.write(" ! %-15s [ %s ]\n" % (a,m))
_actprint[(a,m)] = 1
@@ -1776,7 +1782,7 @@ def lr_parse_table(method):
nkeys = { }
for ii in I:
for s in ii.usyms:
- if Nonterminals.has_key(s):
+ if s in Nonterminals:
nkeys[s] = None
for n in nkeys.keys():
g = lr0_goto(I,n)
@@ -1914,15 +1920,14 @@ del _lr_goto_items
f.close()
- except IOError,e:
- print "Unable to create '%s'" % filename
- print e
- return
+ except IOError as e:
+ print("Unable to create '%s'" % filename)
+ print(e)
def lr_read_tables(module=tab_module,optimize=0):
global _lr_action, _lr_goto, _lr_productions, _lr_method
try:
- exec "import %s as parsetab" % module
+ exec("import %s as parsetab" % module)
if (optimize) or (Signature.digest() == parsetab._lr_signature):
_lr_action = parsetab._lr_action
@@ -1938,13 +1943,13 @@ def lr_read_tables(module=tab_module,optimize=0):
# Available instance types. This is used when parsers are defined by a class.
-# it's a little funky because I want to preserve backwards compatibility
-# with Python 2.0 where types.ObjectType is undefined.
+# In Python3 the InstanceType and ObjectType are no more, they've passed, ceased
+# to be, they are ex-classes along with old-style classes
try:
_INSTANCETYPE = (types.InstanceType, types.ObjectType)
except AttributeError:
- _INSTANCETYPE = types.InstanceType
+ _INSTANCETYPE = object
# -----------------------------------------------------------------------------
# yacc(module)
@@ -1962,7 +1967,7 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
# Add parsing method to signature
- Signature.update(method)
+ Signature.update(util.encode_input(method))
# If a "module" parameter was supplied, extract its dictionary.
# Note: a module may in fact be an instance as well.
@@ -1977,7 +1982,7 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
for i in _items:
ldict[i[0]] = i[1]
else:
- raise ValueError,"Expected a module"
+ raise ValueError("Expected a module")
else:
# No module given. We might be able to get information from the caller.
@@ -1995,7 +2000,7 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
if not start:
start = ldict.get("start",None)
if start:
- Signature.update(start)
+ Signature.update(util.encode_input(start))
# If running in optimized mode. We're going to
@@ -2023,24 +2028,24 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
tokens = ldict.get("tokens",None)
if not tokens:
- raise YaccError,"module does not define a list 'tokens'"
- if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
- raise YaccError,"tokens must be a list or tuple."
+ raise YaccError("module does not define a list 'tokens'")
+ if not (isinstance(tokens,list) or isinstance(tokens,tuple)):
+ raise YaccError("tokens must be a list or tuple.")
# Check to see if a requires dictionary is defined.
requires = ldict.get("require",None)
if requires:
- if not (isinstance(requires,types.DictType)):
- raise YaccError,"require must be a dictionary."
+ if not (isinstance(requires,dict)):
+ raise YaccError("require must be a dictionary.")
for r,v in requires.items():
try:
- if not (isinstance(v,types.ListType)):
+ if not (isinstance(v,list)):
raise TypeError
v1 = [x.split(".") for x in v]
Requires[r] = v1
- except StandardError:
- print "Invalid specification for rule '%s' in require. Expected a list of strings" % r
+ except Exception:
+ print("Invalid specification for rule '%s' in require. Expected a list of strings" % r)
# Build the dictionary of terminals. We a record a 0 in the
@@ -2048,12 +2053,12 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
# used in the grammar
if 'error' in tokens:
- print "yacc: Illegal token 'error'. Is a reserved word."
- raise YaccError,"Illegal token name"
+ print("yacc: Illegal token 'error'. Is a reserved word.")
+ raise YaccError("Illegal token name")
for n in tokens:
- if Terminals.has_key(n):
- print "yacc: Warning. Token '%s' multiply defined." % n
+ if n in Terminals:
+ print("yacc: Warning. Token '%s' multiply defined." % n)
Terminals[n] = [ ]
Terminals['error'] = [ ]
@@ -2061,13 +2066,13 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
# Get the precedence map (if any)
prec = ldict.get("precedence",None)
if prec:
- if not (isinstance(prec,types.ListType) or isinstance(prec,types.TupleType)):
- raise YaccError,"precedence must be a list or tuple."
+ if not (isinstance(prec,list) or isinstance(prec,tuple)):
+ raise YaccError("precedence must be a list or tuple.")
add_precedence(prec)
- Signature.update(repr(prec))
+ Signature.update(util.encode_input(repr(prec)))
for n in tokens:
- if not Precedence.has_key(n):
+ if n not in Precedence:
Precedence[n] = ('right',0) # Default, right associative, 0 precedence
# Look for error handler
@@ -2078,17 +2083,17 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
elif isinstance(ef, types.MethodType):
ismethod = 1
else:
- raise YaccError,"'p_error' defined, but is not a function or method."
- eline = ef.func_code.co_firstlineno
- efile = ef.func_code.co_filename
+ raise YaccError("'p_error' defined, but is not a function or method.")
+ eline = ef.__code__.co_firstlineno
+ efile = ef.__code__.co_filename
files[efile] = None
- if (ef.func_code.co_argcount != 1+ismethod):
- raise YaccError,"%s:%d: p_error() requires 1 argument." % (efile,eline)
+ if (ef.__code__.co_argcount != 1+ismethod):
+ raise YaccError("%s:%d: p_error() requires 1 argument." % (efile,eline))
global Errorfunc
Errorfunc = ef
else:
- print "yacc: Warning. no p_error() function is defined."
+ print("yacc: Warning. no p_error() function is defined.")
# Get the list of built-in functions with p_ prefix
symbols = [ldict[f] for f in ldict.keys()
@@ -2097,27 +2102,27 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
# Check for non-empty symbols
if len(symbols) == 0:
- raise YaccError,"no rules of the form p_rulename are defined."
+ raise YaccError("no rules of the form p_rulename are defined.")
# Sort the symbols by line number
- symbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
+ symbols.sort(key=lambda x: x.__code__.co_firstlineno)
# Add all of the symbols to the grammar
for f in symbols:
if (add_function(f)) < 0:
error += 1
else:
- files[f.func_code.co_filename] = None
+ files[f.__code__.co_filename] = None
# Make a signature of the docstrings
for f in symbols:
if f.__doc__:
- Signature.update(f.__doc__)
+ Signature.update(util.encode_input(f.__doc__))
lr_init_vars()
if error:
- raise YaccError,"Unable to construct parser."
+ raise YaccError("Unable to construct parser.")
if not lr_read_tables(tabmodule):
@@ -2129,8 +2134,8 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
# Validate dictionary
validate_dict(ldict)
- if start and not Prodnames.has_key(start):
- raise YaccError,"Bad starting symbol '%s'" % start
+ if start and start not in Prodnames:
+ raise YaccError("Bad starting symbol '%s'" % start)
augment_grammar(start)
error = verify_productions(cycle_check=check_recursion)
@@ -2138,7 +2143,7 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
if (type(f) in (types.FunctionType,types.MethodType) and ldict[f].__name__[:2] != 'p_')]
if error:
- raise YaccError,"Unable to construct parser."
+ raise YaccError("Unable to construct parser.")
build_lritems()
compute_first1()
@@ -2147,7 +2152,7 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
if method in ['SLR','LALR']:
lr_parse_table(method)
else:
- raise YaccError, "Unknown parsing method '%s'" % method
+ raise YaccError("Unknown parsing method '%s'" % method)
if write_tables:
lr_write_tables(tabmodule,outputdir)
@@ -2159,8 +2164,8 @@ def yacc(method=default_lr, debug=yaccdebug, module=None, tabmodule=tab_module,
f.write("\n\n")
f.write(_vf.getvalue())
f.close()
- except IOError,e:
- print "yacc: can't create '%s'" % debugfile,e
+ except IOError as e:
+ print("yacc: can't create '%s'" % debugfile,e)
# Made it here. Create a parser object and set up its internal state.
# Set global parse() method to bound method of parser object.
@@ -2205,5 +2210,5 @@ def yacc_cleanup():
# Stub that raises an error if parsing is attempted without first calling yacc()
def parse(*args,**kwargs):
- raise YaccError, "yacc: No parser built with yacc()"
+ raise YaccError("yacc: No parser built with yacc()")
diff --git a/sepolgen/tests/test_access.py b/sepolgen/tests/test_access.py
index fec699e9..d45a823e 100644
--- a/sepolgen/tests/test_access.py
+++ b/sepolgen/tests/test_access.py
@@ -32,7 +32,7 @@ class TestAccessVector(unittest.TestCase):
self.assertEqual(a.obj_class, None)
self.assertTrue(isinstance(a.perms, refpolicy.IdSet))
self.assertTrue(isinstance(a.audit_msgs, type([])))
- self.assertEquals(len(a.audit_msgs), 0)
+ self.assertEqual(len(a.audit_msgs), 0)
# Construction from a list
a = access.AccessVector()
@@ -72,8 +72,10 @@ class TestAccessVector(unittest.TestCase):
self.assertEqual(l[0], "foo")
self.assertEqual(l[1], "bar")
self.assertEqual(l[2], "file")
- self.assertEqual(l[3], "read")
- self.assertEqual(l[4], "write")
+ perms = l[3:]
+ perms.sort()
+ self.assertEqual(perms[0], "read")
+ self.assertEqual(perms[1], "write")
def test_to_string(self):
a = access.AccessVector()
@@ -82,8 +84,21 @@ class TestAccessVector(unittest.TestCase):
a.obj_class = "file"
a.perms.update(["read", "write"])
- self.assertEquals(str(a), "allow foo bar:file { read write };")
- self.assertEquals(a.to_string(), "allow foo bar:file { read write };")
+ first, second = str(a).split(':')
+ self.assertEqual(first, "allow foo bar")
+ second = second.split(' ')
+ second.sort()
+ expected = "file { read write };".split(' ')
+ expected.sort()
+ self.assertEqual(second, expected)
+
+ first, second = a.to_string().split(':')
+ self.assertEqual(first, "allow foo bar")
+ second = second.split(' ')
+ second.sort()
+ expected = "file { read write };".split(' ')
+ expected.sort()
+ self.assertEqual(second, expected)
def test_cmp(self):
a = access.AccessVector()
@@ -98,36 +113,38 @@ class TestAccessVector(unittest.TestCase):
b.obj_class = "file"
b.perms.update(["read", "write"])
- self.assertEquals(a, b)
+ self.assertEqual(a, b)
# Source Type
b.src_type = "baz"
- self.assertEquals(cmp(a, b), 1)
+ self.assertNotEqual(a, b)
+ self.assertTrue(a > b)
b.src_type = "gaz"
- self.assertEquals(cmp(a, b), -1)
+ self.assertNotEqual(a, b)
+ self.assertTrue(a < b)
# Target Type
b.src_type = "foo"
b.tgt_type = "aar"
- self.assertEquals(cmp(a, b), 1)
+ self.assertNotEqual(a, b)
+ self.assertTrue(a > b)
b.tgt_type = "gaz"
- self.assertEquals(cmp(a, b), -1)
+ self.assertNotEqual(a, b)
+ self.assertTrue(a < b)
# Perms
b.tgt_type = "bar"
b.perms = refpolicy.IdSet(["read"])
- ret = cmp(a, b)
- self.assertEquals(ret, 1)
+ self.assertNotEqual(a, b)
+ self.assertTrue(a > b)
b.perms = refpolicy.IdSet(["read", "write", "append"])
- ret = cmp(a, b)
- self.assertEquals(ret, -1)
+ self.assertNotEqual(a, b)
b.perms = refpolicy.IdSet(["read", "append"])
- ret = cmp(a, b)
- self.assertEquals(ret, 1)
+ self.assertNotEqual(a, b)
class TestUtilFunctions(unittest.TestCase):
def test_is_idparam(self):
@@ -149,7 +166,7 @@ class TestUtilFunctions(unittest.TestCase):
rule.perms.add("write")
avs = access.avrule_to_access_vectors(rule)
- self.assertEquals(len(avs), 8)
+ self.assertEqual(len(avs), 8)
comps = [("foo", "what", "dir"),
("foo", "what", "file"),
("foo", "bar", "dir"),
@@ -160,15 +177,15 @@ class TestUtilFunctions(unittest.TestCase):
("baz", "bar", "file")]
status = [False] * 8
for av in access.avrule_to_access_vectors(rule):
- self.assertEquals(av.perms, refpolicy.IdSet(["read", "write"]))
- for i in xrange(len(comps)):
+ self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"]))
+ for i in range(len(comps)):
if comps[i][0] == av.src_type and \
comps[i][1] == av.tgt_type and \
comps[i][2] == av.obj_class:
status[i] = True
for s in status:
- self.assertEquals(s, True)
+ self.assertEqual(s, True)
class TestAccessVectorSet(unittest.TestCase):
@@ -203,18 +220,18 @@ class TestAccessVectorSet(unittest.TestCase):
("baz", "bar", "file")]
status = [False] * 8
for av in self.s:
- self.assertEquals(av.perms, refpolicy.IdSet(["read", "write"]))
- for i in xrange(len(comps)):
+ self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"]))
+ for i in range(len(comps)):
if comps[i][0] == av.src_type and \
comps[i][1] == av.tgt_type and \
comps[i][2] == av.obj_class:
status[i] = True
for s in status:
- self.assertEquals(s, True)
+ self.assertEqual(s, True)
def test_len(self):
- self.assertEquals(len(self.s), 8)
+ self.assertEqual(len(self.s), 8)
def test_list(self):
a = access.AccessVectorSet()
@@ -223,15 +240,22 @@ class TestAccessVectorSet(unittest.TestCase):
a.add("what", "bar", "file", refpolicy.IdSet(["read", "write"]))
avl = a.to_list()
+ avl.sort()
test_l = [['what','bar','file','read','write'],
['$1','foo','file','read','write'],
['$1','bar','file','read','write']]
+ test_l.sort()
for a,b in zip(test_l, avl):
self.assertEqual(len(a), len(b))
- for x,y in zip(a,b):
+ for x,y in list(zip(a,b))[:3]:
self.assertEqual(x, y)
+ perms1 = a[3:]
+ perms2 = b[3:]
+ perms1.sort()
+ perms2.sort()
+ self.assertEqual(perms1, perms2)
b = access.AccessVectorSet()
b.from_list(avl)
diff --git a/sepolgen/tests/test_audit.py b/sepolgen/tests/test_audit.py
index 7b742206..6379954f 100644
--- a/sepolgen/tests/test_audit.py
+++ b/sepolgen/tests/test_audit.py
@@ -60,29 +60,29 @@ class TestAVCMessage(unittest.TestCase):
def test_defs(self):
avc = sepolgen.audit.AVCMessage(audit1)
sc = sepolgen.refpolicy.SecurityContext()
- self.assertEquals(avc.scontext, sc)
- self.assertEquals(avc.tcontext, sc)
- self.assertEquals(avc.tclass, "")
- self.assertEquals(avc.accesses, [])
+ self.assertEqual(avc.scontext, sc)
+ self.assertEqual(avc.tcontext, sc)
+ self.assertEqual(avc.tclass, "")
+ self.assertEqual(avc.accesses, [])
def test_granted(self):
avc = sepolgen.audit.AVCMessage(granted1)
avc.from_split_string(granted1.split())
- self.assertEquals(avc.scontext.user, "user_u")
- self.assertEquals(avc.scontext.role, "system_r")
- self.assertEquals(avc.scontext.type, "unconfined_t")
- self.assertEquals(avc.scontext.level, "s0")
+ self.assertEqual(avc.scontext.user, "user_u")
+ self.assertEqual(avc.scontext.role, "system_r")
+ self.assertEqual(avc.scontext.type, "unconfined_t")
+ self.assertEqual(avc.scontext.level, "s0")
- self.assertEquals(avc.tcontext.user, "user_u")
- self.assertEquals(avc.tcontext.role, "object_r")
- self.assertEquals(avc.tcontext.type, "user_home_t")
- self.assertEquals(avc.tcontext.level, "s0")
+ self.assertEqual(avc.tcontext.user, "user_u")
+ self.assertEqual(avc.tcontext.role, "object_r")
+ self.assertEqual(avc.tcontext.type, "user_home_t")
+ self.assertEqual(avc.tcontext.level, "s0")
- self.assertEquals(avc.tclass, "file")
- self.assertEquals(avc.accesses, ["getattr"])
+ self.assertEqual(avc.tclass, "file")
+ self.assertEqual(avc.accesses, ["getattr"])
- self.assertEquals(avc.denial, False)
+ self.assertEqual(avc.denial, False)
def test_from_split_string(self):
@@ -91,54 +91,54 @@ class TestAVCMessage(unittest.TestCase):
recs = audit1.split()
avc.from_split_string(recs)
- self.assertEquals(avc.header, "audit(1158064002.046:4):")
- self.assertEquals(avc.scontext.user, "user_u")
- self.assertEquals(avc.scontext.role, "system_r")
- self.assertEquals(avc.scontext.type, "bluetooth_helper_t")
- self.assertEquals(avc.scontext.level, "s0-s0:c0")
+ self.assertEqual(avc.header, "audit(1158064002.046:4):")
+ self.assertEqual(avc.scontext.user, "user_u")
+ self.assertEqual(avc.scontext.role, "system_r")
+ self.assertEqual(avc.scontext.type, "bluetooth_helper_t")
+ self.assertEqual(avc.scontext.level, "s0-s0:c0")
- self.assertEquals(avc.tcontext.user, "system_u")
- self.assertEquals(avc.tcontext.role, "object_r")
- self.assertEquals(avc.tcontext.type, "xdm_tmp_t")
- self.assertEquals(avc.tcontext.level, "s0")
+ self.assertEqual(avc.tcontext.user, "system_u")
+ self.assertEqual(avc.tcontext.role, "object_r")
+ self.assertEqual(avc.tcontext.type, "xdm_tmp_t")
+ self.assertEqual(avc.tcontext.level, "s0")
- self.assertEquals(avc.tclass, "file")
- self.assertEquals(avc.accesses, ["read"])
+ self.assertEqual(avc.tclass, "file")
+ self.assertEqual(avc.accesses, ["read"])
- self.assertEquals(avc.comm, "bluez-pin")
+ self.assertEqual(avc.comm, "bluez-pin")
- self.assertEquals(avc.denial, True)
+ self.assertEqual(avc.denial, True)
# audit daemon message
avc = sepolgen.audit.AVCMessage(audit2)
recs = audit2.split()
avc.from_split_string(recs)
- self.assertEquals(avc.header, "audit(1158584779.745:708):")
- self.assertEquals(avc.scontext.user, "user_u")
- self.assertEquals(avc.scontext.role, "system_r")
- self.assertEquals(avc.scontext.type, "vpnc_t")
- self.assertEquals(avc.scontext.level, "s0")
+ self.assertEqual(avc.header, "audit(1158584779.745:708):")
+ self.assertEqual(avc.scontext.user, "user_u")
+ self.assertEqual(avc.scontext.role, "system_r")
+ self.assertEqual(avc.scontext.type, "vpnc_t")
+ self.assertEqual(avc.scontext.level, "s0")
- self.assertEquals(avc.tcontext.user, "user_u")
- self.assertEquals(avc.tcontext.role, "system_r")
- self.assertEquals(avc.tcontext.type, "vpnc_t")
- self.assertEquals(avc.tcontext.level, "s0")
+ self.assertEqual(avc.tcontext.user, "user_u")
+ self.assertEqual(avc.tcontext.role, "system_r")
+ self.assertEqual(avc.tcontext.type, "vpnc_t")
+ self.assertEqual(avc.tcontext.level, "s0")
- self.assertEquals(avc.tclass, "capability")
- self.assertEquals(avc.accesses, ["dac_read_search"])
+ self.assertEqual(avc.tclass, "capability")
+ self.assertEqual(avc.accesses, ["dac_read_search"])
- self.assertEquals(avc.comm, "sh")
+ self.assertEqual(avc.comm, "sh")
- self.assertEquals(avc.denial, True)
+ self.assertEqual(avc.denial, True)
class TestPathMessage(unittest.TestCase):
def test_from_split_string(self):
path = sepolgen.audit.PathMessage(path1)
recs = path1.split()
path.from_split_string(recs)
- self.assertEquals(path.path, "/usr/lib/sa/sa1")
+ self.assertEqual(path.path, "/usr/lib/sa/sa1")
# TODO - add tests for the other message types
@@ -149,27 +149,28 @@ class TestAuditParser(unittest.TestCase):
def test_parse_string(self):
a = sepolgen.audit.AuditParser()
a.parse_string(log1)
- self.assertEquals(len(a.avc_msgs), 11)
- self.assertEquals(len(a.compute_sid_msgs), 0)
- self.assertEquals(len(a.invalid_msgs), 0)
- self.assertEquals(len(a.policy_load_msgs), 0)
- self.assertEquals(len(a.path_msgs), 1)
+ self.assertEqual(len(a.avc_msgs), 11)
+ self.assertEqual(len(a.compute_sid_msgs), 0)
+ self.assertEqual(len(a.invalid_msgs), 0)
+ self.assertEqual(len(a.policy_load_msgs), 0)
+ self.assertEqual(len(a.path_msgs), 1)
def test_post_process(self):
a = sepolgen.audit.AuditParser()
a.parse_string(log2)
- self.assertEquals(len(a.avc_msgs), 2)
- self.assertEquals(a.avc_msgs[0].path, "/usr/lib/sa/sa1")
- self.assertEquals(a.avc_msgs[1].path, "/usr/lib/sa/sa1")
+ self.assertEqual(len(a.avc_msgs), 2)
+ self.assertEqual(a.avc_msgs[0].path, "/usr/lib/sa/sa1")
+ self.assertEqual(a.avc_msgs[1].path, "/usr/lib/sa/sa1")
def test_parse_file(self):
f = open("audit.txt")
a = sepolgen.audit.AuditParser()
a.parse_file(f)
- self.assertEquals(len(a.avc_msgs), 21)
- self.assertEquals(len(a.compute_sid_msgs), 0)
- self.assertEquals(len(a.invalid_msgs), 0)
- self.assertEquals(len(a.policy_load_msgs), 0)
+ f.close()
+ self.assertEqual(len(a.avc_msgs), 21)
+ self.assertEqual(len(a.compute_sid_msgs), 0)
+ self.assertEqual(len(a.invalid_msgs), 0)
+ self.assertEqual(len(a.policy_load_msgs), 0)
class TestGeneration(unittest.TestCase):
def test_generation(self):
diff --git a/sepolgen/tests/test_interfaces.py b/sepolgen/tests/test_interfaces.py
index b589bdf9..a55f7db8 100644
--- a/sepolgen/tests/test_interfaces.py
+++ b/sepolgen/tests/test_interfaces.py
@@ -202,11 +202,11 @@ class TestInterfaceSet(unittest.TestCase):
i = interfaces.InterfaceSet()
i.add_headers(h)
- self.assertEquals(len(i.interfaces), 1)
+ self.assertEqual(len(i.interfaces), 1)
for key, interface in i.interfaces.items():
- self.assertEquals(key, interface.name)
- self.assertEquals(key, "foo")
- self.assertEquals(len(interface.access), 2)
+ self.assertEqual(key, interface.name)
+ self.assertEqual(key, "foo")
+ self.assertEqual(len(interface.access), 2)
# Check the access vectors
comp_avs = [["$1", "usr_t", "dir", "create", "add_name"],
@@ -215,21 +215,21 @@ class TestInterfaceSet(unittest.TestCase):
self.assertTrue(ret)
# Check the params
- self.assertEquals(len(interface.params), 1)
+ self.assertEqual(len(interface.params), 1)
for param in interface.params.values():
- self.assertEquals(param.type, refpolicy.SRC_TYPE)
- self.assertEquals(param.name, "$1")
- self.assertEquals(param.num, 1)
- self.assertEquals(param.required, True)
+ self.assertEqual(param.type, refpolicy.SRC_TYPE)
+ self.assertEqual(param.name, "$1")
+ self.assertEqual(param.num, 1)
+ self.assertEqual(param.required, True)
def test_expansion(self):
h = refparser.parse(test_expansion)
i = interfaces.InterfaceSet()
i.add_headers(h)
- self.assertEquals(len(i.interfaces), 3)
+ self.assertEqual(len(i.interfaces), 3)
for key, interface in i.interfaces.items():
- self.assertEquals(key, interface.name)
+ self.assertEqual(key, interface.name)
if key == "foo":
comp_avs = [["$1", "usr_t", "dir", "create", "add_name"],
["$1", "usr_t", "file", "read", "write"]]
@@ -268,6 +268,7 @@ class TestInterfaceSet(unittest.TestCase):
i2 = interfaces.InterfaceSet()
f = open("output")
i2.from_file(f)
+ f.close()
if_status = [False, False, False]
for ifv in i2.interfaces.values():
if ifv.name == "files_search_usr":
@@ -277,6 +278,6 @@ class TestInterfaceSet(unittest.TestCase):
if ifv.name == "files_exec_usr_files":
if_status[2] = True
- self.assertEquals(if_status[0], True)
- self.assertEquals(if_status[1], True)
- self.assertEquals(if_status[2], True)
+ self.assertEqual(if_status[0], True)
+ self.assertEqual(if_status[1], True)
+ self.assertEqual(if_status[2], True)
diff --git a/sepolgen/tests/test_matching.py b/sepolgen/tests/test_matching.py
index 161e0016..3ecb80b8 100644
--- a/sepolgen/tests/test_matching.py
+++ b/sepolgen/tests/test_matching.py
@@ -33,15 +33,15 @@ class TestMatch(unittest.TestCase):
b.dist = 100
b.info_dir_change = True
- self.assertEquals(a, b)
+ self.assertEqual(a, b)
b.info_dir_change = False
- self.assertEquals(cmp(a, b), 1)
- self.assertEquals(cmp(b, a), -1)
+ self.assertTrue((a > b))
+ self.assertTrue((b < a))
b.dist = 200
- self.assertEquals(cmp(a, b), -1)
- self.assertEquals(cmp(b, a), 1)
+ self.assertTrue((a < b))
+ self.assertTrue((b > a))
class TestMatchList(unittest.TestCase):
def test_append(self):
@@ -90,7 +90,7 @@ class TestMatchList(unittest.TestCase):
for x, y in zip(l, ml):
self.assertEqual(x, y)
- self.assertEquals(ml.best(), c)
+ self.assertEqual(ml.best(), c)
test_expansion = """
diff --git a/sepolgen/tests/test_objectmodel.py b/sepolgen/tests/test_objectmodel.py
index 3db241c6..b5036727 100644
--- a/sepolgen/tests/test_objectmodel.py
+++ b/sepolgen/tests/test_objectmodel.py
@@ -25,20 +25,21 @@ class TestInfoFlow(unittest.TestCase):
info = sepolgen.objectmodel.PermMappings()
fd = open("perm_map")
info.from_file(fd)
+ fd.close()
pm = info.get("filesystem", "mount")
- self.assertEquals(pm.perm, "mount")
- self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_WRITE)
- self.assertEquals(pm.weight, 1)
+ self.assertEqual(pm.perm, "mount")
+ self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_WRITE)
+ self.assertEqual(pm.weight, 1)
self.assertRaises(KeyError, info.get, "filesystem", "foo")
pm = info.getdefault("filesystem", "foo")
- self.assertEquals(pm.perm, "foo")
- self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
- self.assertEquals(pm.weight, 5)
+ self.assertEqual(pm.perm, "foo")
+ self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
+ self.assertEqual(pm.weight, 5)
pm = info.getdefault("foo", "bar")
- self.assertEquals(pm.perm, "bar")
- self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
- self.assertEquals(pm.weight, 5)
+ self.assertEqual(pm.perm, "bar")
+ self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
+ self.assertEqual(pm.weight, 5)
diff --git a/sepolgen/tests/test_refparser.py b/sepolgen/tests/test_refparser.py
index 3fe6d796..d7db1451 100644
--- a/sepolgen/tests/test_refparser.py
+++ b/sepolgen/tests/test_refparser.py
@@ -107,12 +107,12 @@ class TestParser(unittest.TestCase):
h = refparser.parse(interface_example)
#print ""
#refpolicy.print_tree(h)
- #self.assertEquals(len(h.interfaces), 3)
+ #self.assertEqual(len(h.interfaces), 3)
name = "files_search_usr"
#i = h.interfaces[name]
- #self.assertEquals(i.name, name)
- #self.assertEquals(len(i.rules), 1)
+ #self.assertEqual(i.name, name)
+ #self.assertEqual(len(i.rules), 1)
#rule = i.rules[0]
#self.assertTrue(isinstance(rule, refpolicy.AVRule))
diff --git a/sepolgen/tests/test_refpolicy.py b/sepolgen/tests/test_refpolicy.py
index 8c871895..16e66806 100644
--- a/sepolgen/tests/test_refpolicy.py
+++ b/sepolgen/tests/test_refpolicy.py
@@ -24,10 +24,14 @@ import selinux
class TestIdSet(unittest.TestCase):
def test_set_to_str(self):
s = refpolicy.IdSet(["read", "write", "getattr"])
- self.assertEquals(s.to_space_str(), "{ read write getattr }")
+ s = s.to_space_str().split(' ')
+ s.sort()
+ expected = "{ read write getattr }".split(' ')
+ expected.sort()
+ self.assertEqual(s, expected)
s = refpolicy.IdSet()
s.add("read")
- self.assertEquals(s.to_space_str(), "read")
+ self.assertEqual(s.to_space_str(), "read")
class TestSecurityContext(unittest.TestCase):
def test_init(self):
@@ -38,25 +42,25 @@ class TestSecurityContext(unittest.TestCase):
context = "user_u:object_r:foo_t"
sc = refpolicy.SecurityContext()
sc.from_string(context)
- self.assertEquals(sc.user, "user_u")
- self.assertEquals(sc.role, "object_r")
- self.assertEquals(sc.type, "foo_t")
- self.assertEquals(sc.level, None)
+ self.assertEqual(sc.user, "user_u")
+ self.assertEqual(sc.role, "object_r")
+ self.assertEqual(sc.type, "foo_t")
+ self.assertEqual(sc.level, None)
if selinux.is_selinux_mls_enabled():
- self.assertEquals(str(sc), context + ":s0")
+ self.assertEqual(str(sc), context + ":s0")
else:
- self.assertEquals(str(sc), context)
- self.assertEquals(sc.to_string(default_level="s1"), context + ":s1")
+ self.assertEqual(str(sc), context)
+ self.assertEqual(sc.to_string(default_level="s1"), context + ":s1")
context = "user_u:object_r:foo_t:s0-s0:c0-c255"
sc = refpolicy.SecurityContext()
sc.from_string(context)
- self.assertEquals(sc.user, "user_u")
- self.assertEquals(sc.role, "object_r")
- self.assertEquals(sc.type, "foo_t")
- self.assertEquals(sc.level, "s0-s0:c0-c255")
- self.assertEquals(str(sc), context)
- self.assertEquals(sc.to_string(), context)
+ self.assertEqual(sc.user, "user_u")
+ self.assertEqual(sc.role, "object_r")
+ self.assertEqual(sc.type, "foo_t")
+ self.assertEqual(sc.level, "s0-s0:c0-c255")
+ self.assertEqual(str(sc), context)
+ self.assertEqual(sc.to_string(), context)
sc = refpolicy.SecurityContext()
self.assertRaises(ValueError, sc.from_string, "abc")
@@ -67,20 +71,20 @@ class TestSecurityContext(unittest.TestCase):
sc3 = refpolicy.SecurityContext("user_u:object_r:foo_t:s0")
sc4 = refpolicy.SecurityContext("user_u:object_r:bar_t")
- self.assertEquals(sc1, sc2)
- self.assertNotEquals(sc1, sc3)
- self.assertNotEquals(sc1, sc4)
+ self.assertEqual(sc1, sc2)
+ self.assertNotEqual(sc1, sc3)
+ self.assertNotEqual(sc1, sc4)
class TestObjecClass(unittest.TestCase):
def test_init(self):
o = refpolicy.ObjectClass(name="file")
- self.assertEquals(o.name, "file")
+ self.assertEqual(o.name, "file")
self.assertTrue(isinstance(o.perms, set))
class TestAVRule(unittest.TestCase):
def test_init(self):
a = refpolicy.AVRule()
- self.assertEquals(a.rule_type, a.ALLOW)
+ self.assertEqual(a.rule_type, a.ALLOW)
self.assertTrue(isinstance(a.src_types, set))
self.assertTrue(isinstance(a.tgt_types, set))
self.assertTrue(isinstance(a.obj_classes, set))
@@ -92,7 +96,7 @@ class TestAVRule(unittest.TestCase):
a.tgt_types.add("bar_t")
a.obj_classes.add("file")
a.perms.add("read")
- self.assertEquals(a.to_string(), "allow foo_t bar_t:file read;")
+ self.assertEqual(a.to_string(), "allow foo_t bar_t:file read;")
a.rule_type = a.DONTAUDIT
a.src_types.add("user_t")
@@ -100,17 +104,20 @@ class TestAVRule(unittest.TestCase):
a.obj_classes.add("lnk_file")
a.perms.add("write")
# This test might need to go because set ordering is not guaranteed
- self.assertEquals(a.to_string(),
- "dontaudit { foo_t user_t } { user_home_t bar_t }:{ lnk_file file } { read write };")
+ a = a.to_string().split(' ')
+ a.sort()
+ b = "dontaudit { foo_t user_t } { user_home_t bar_t }:{ lnk_file file } { read write };".split(' ')
+ b.sort()
+ self.assertEqual(a, b)
class TestTypeRule(unittest.TestCase):
def test_init(self):
a = refpolicy.TypeRule()
- self.assertEquals(a.rule_type, a.TYPE_TRANSITION)
+ self.assertEqual(a.rule_type, a.TYPE_TRANSITION)
self.assertTrue(isinstance(a.src_types, set))
self.assertTrue(isinstance(a.tgt_types, set))
self.assertTrue(isinstance(a.obj_classes, set))
- self.assertEquals(a.dest_type, "")
+ self.assertEqual(a.dest_type, "")
def test_to_string(self):
a = refpolicy.TypeRule()
@@ -118,7 +125,7 @@ class TestTypeRule(unittest.TestCase):
a.tgt_types.add("bar_exec_t")
a.obj_classes.add("process")
a.dest_type = "bar_t"
- self.assertEquals(a.to_string(), "type_transition foo_t bar_exec_t:process bar_t;")
+ self.assertEqual(a.to_string(), "type_transition foo_t bar_exec_t:process bar_t;")
class TestParseNode(unittest.TestCase):