From 0ce79dd3761d52f34e370f573cd750ae7a578089 Mon Sep 17 00:00:00 2001 From: Miroslav Grepl Date: Fri, 11 Apr 2014 09:54:44 +0200 Subject: Merge 3.3.8 upstream setools --- ChangeLog | 19 ++++ Makefile.am | 2 +- apol/top.tcl | 8 +- configure.ac | 72 +++++++++++--- libapol/include/apol/Makefile.am | 1 + libapol/include/apol/policy-query.h | 1 + libapol/src/Makefile.am | 1 + libapol/src/libapol.map | 1 + libqpol/include/qpol/Makefile.am | 1 + libqpol/include/qpol/policy.h | 1 + libqpol/src/Makefile.am | 1 + libqpol/src/libqpol.map | 1 + libqpol/src/module_compiler.c | 12 +++ libqpol/src/module_compiler.h | 1 + libqpol/src/policy_define.c | 188 +++++++++++++++++++++++++++++++++++- libqpol/src/policy_define.h | 2 + libqpol/src/policy_parse.y | 13 ++- libqpol/src/policy_scan.l | 1 + man/replcon.1 | 2 + man/seinfo.1 | 6 +- man/sesearch.1 | 2 + seaudit/progress.c | 5 +- seaudit/seaudit-report.c | 2 +- secmds/seinfo.c | 153 ++++++++++++++++++----------- secmds/sesearch.c | 168 ++++++++++++++++++++++++++++++-- sediff/sediff.c | 2 +- 26 files changed, 572 insertions(+), 94 deletions(-) diff --git a/ChangeLog b/ChangeLog index e492df4..1bce21d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2013-01-08 Steve Lawrence + + * SETools 3.3.8 + * Fix bug preventing seaudit from starting by Jake Lightner. + +2013-01-08 Steve Lawrence + + * Add python bindings for seinfo and sesearch by Dan Walsh. + * seinfo exits with an error status by Dan Walsh. + * Support for named file transition rules by Dan Walsh. + * Add support for default types in sesearch by Steve Lawrence. + * Man page updates for seinfo, seaudit, and sediff by Dan Walsh. + +2012-03-26 Chris PeBenito + * Fix file type drop down list for open/close Apol query. + +2012-03-06 Chris PeBenito + * Fix compile errors on new parameter in libsepol role_set_expand(). + 2010-05-07 Spencer Shimko * SETools 3.3.7. diff --git a/Makefile.am b/Makefile.am index 5dc1b5d..176c8ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,7 +10,7 @@ if BUILD_GUI endif # sediffx is also built conditionally, from sediffx/Makefile.am -SUBDIRS = libqpol libapol libsefs libpoldiff libseaudit secmds sechecker sediff man packages debian $(MAYBE_APOL) $(MAYBE_GUI) +SUBDIRS = libqpol libapol libsefs libpoldiff libseaudit secmds sechecker sediff man packages debian $(MAYBE_APOL) $(MAYBE_GUI) python #old indent opts #INDENT_OPTS = -npro -nbad -bap -sob -ss -l132 -di1 -nbc -br -nbbb -c40 -cd40 -ncdb -ce -cli0 -cp40 -ncs -d0 -nfc1 -nfca -i8 -ts8 -ci8 -lp -ip0 -npcs -npsl -sc diff --git a/apol/top.tcl b/apol/top.tcl index e0f87a3..f930318 100644 --- a/apol/top.tcl +++ b/apol/top.tcl @@ -618,9 +618,7 @@ proc ApolTop::_goto {} { } proc ApolTop::_open_query_file {} { - set types { - {"Query files" {$ApolTop::query_file_ext}} - } + set types " {\"Query files\" { $ApolTop::query_file_ext }} " set query_file [tk_getOpenFile -filetypes $types -title "Open Apol Query" \ -defaultextension $ApolTop::query_file_ext -parent .] if {$query_file != {}} { @@ -657,9 +655,7 @@ proc ApolTop::_open_query_file {} { } proc ApolTop::_save_query_file {} { - set types { - {"Query files" {$ApolTop::query_file_ext}} - } + set types " {\"Query files\" {$ApolTop::query_file_ext}} " set query_file [tk_getSaveFile -title "Save Apol Query" \ -defaultextension $ApolTop::query_file_ext \ -filetypes $types -parent .] diff --git a/configure.ac b/configure.ac index b885981..577ce48 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT(setools, 3.3.7, [Tresys Technology ], [setools]) +AC_INIT(setools, 3.3.8, [Tresys Technology ], [setools]) AC_PREREQ([2.59]) AC_CONFIG_SRCDIR(libqpol/src/policy.c) AC_CONFIG_HEADER(config.h) @@ -8,19 +8,19 @@ AM_INIT_AUTOMAKE([-Wno-portability]) dnl *** update these variables as versions change; also update AC_INIT *** libqpol_soversion=1 -libqpol_version=1.6 +libqpol_version=1.7 libapol_soversion=4 -libapol_version=4.3 +libapol_version=4.4 libpoldiff_soversion=1 -libpoldiff_version=1.3.2 +libpoldiff_version=1.3.3 libsefs_soversion=4 -libsefs_version=4.0.3 +libsefs_version=4.0.4 libseaudit_soversion=4 -libseaudit_version=4.4 +libseaudit_version=4.5 setoolsdir='${prefix}/share/setools-3.3' javadir='${prefix}/share/java' @@ -194,7 +194,7 @@ AC_ARG_ENABLE(swig-java, enable_jswig="$enableval") if test "x${enable_jswig}" = xyes; then if test ${do_swigify} = no; then - AC_PROG_SWIG(1.3.28) + AC_PROG_SWIG(2.0.0) fi AC_JAVA_OPTIONS if test "x$JAVAPREFIX" = x; then @@ -216,21 +216,23 @@ if test "x${enable_jswig}" = xyes; then do_swigify_java=yes do_swigify=yes fi + +AM_PATH_PYTHON(2.7) + AC_ARG_ENABLE(swig-python, AC_HELP_STRING([--enable-swig-python], [build SWIG interfaces for Python]), enable_pyswig="$enableval") if test "x${enable_pyswig}" = xyes; then if test ${do_swigify} = no; then - AC_PROG_SWIG(1.3.28) + AC_PROG_SWIG(2.0.0) fi - AM_PATH_PYTHON(2.3) SWIG_PYTHON do_swigify_python=yes do_swigify=yes fi if test ${do_swigify} = "yes"; then - AC_PROG_SWIG(1.3.28) + AC_PROG_SWIG(2.0.0) fi build_apol=yes AC_ARG_ENABLE(swig-tcl, @@ -239,7 +241,7 @@ AC_ARG_ENABLE(swig-tcl, enable_tclswig="$enableval", enable_tclswig="yes") if test "x${enable_tclswig}" = xyes; then if test ${do_swigify} = no; then - AC_PROG_SWIG(1.3.28) + AC_PROG_SWIG(2.0.0) fi TEA_INIT(3.5) TEA_PATH_TCLCONFIG @@ -497,17 +499,54 @@ sepol_save_CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLAGS} ${SELINUX_CFLAGS} ${SELINUX_LIB_FLAG}" CPPFLAGS="${CPPFLAGS} ${SELINUX_CFLAGS}" -dnl check for user and role mapping, added in libsepol version 2.0.29 -AC_MSG_CHECKING([for user and role mappings]) +dnl check for role attribute, added in libsepol 2.0.46 +AC_MSG_CHECKING([for libsepol role_set_expand() role attribute support]) AC_COMPILE_IFELSE( [AC_LANG_SOURCE([ #include +int main () { + return role_set_expand(NULL, NULL, NULL, NULL, NULL); +}])], + sepol_role_attrs="yes", + sepol_role_attrs="no") +AC_MSG_RESULT([${sepol_role_attrs}]) + +if test ${sepol_role_attrs} == "yes"; then + sepol_new_user_role_mapping="yes" + sepol_role_set_expand_base="yes" +else + dnl check for user and role mapping, added in libsepol version 2.0.29 + AC_MSG_CHECKING([for libsepol role_set_expand() user and role mappings]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ +#include int main () { return role_set_expand(NULL, NULL, NULL, NULL); }])], sepol_new_user_role_mapping="yes", sepol_new_user_role_mapping="no") -AC_MSG_RESULT([${sepol_new_user_role_mapping}]) + AC_MSG_RESULT([${sepol_new_user_role_mapping}]) + + if test ${sepol_new_user_role_mapping} == "no"; then + dnl if this is not the original role_set_expand(), this libsepol is too new + AC_MSG_CHECKING([for libsepol role_set_expand() original version]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ +#include +int main () { + return role_set_expand(NULL, NULL, NULL); +}])], + sepol_role_set_expand_base="yes", + sepol_role_set_expand_base="no") + AC_MSG_RESULT([${sepol_role_set_expand_base}]) + + if test ${sepol_role_set_expand_base} == "no"; then + AC_MSG_ERROR([this version of libsepol is incompatible with SETools]) + fi + else + sepol_role_set_expand_base="yes" + fi +fi dnl check for permissive types, added in libsepol version 2.0.26 AC_CHECK_DECL([TYPE_FLAGS_PERMISSIVE], @@ -819,6 +858,9 @@ fi if test ${sepol_new_user_role_mapping} == "yes"; then AC_DEFINE(HAVE_SEPOL_USER_ROLE_MAPPING, 1, [if users and roles are mapped during policy expansion]) fi +if test ${sepol_role_attrs} == "yes"; then + AC_DEFINE(HAVE_SEPOL_ROLE_ATTRS, 1, [if role attributes are supported]) +fi if test ${use_shared} == "yes"; then AC_DEFINE(LINK_SHARED, 1, [link programs using shared libraries]) @@ -888,6 +930,8 @@ AC_CONFIG_FILES([Makefile VERSION \ sediff/Makefile \ man/Makefile \ debian/Makefile \ + python/Makefile \ + python/setools/Makefile \ packages/Makefile packages/rpm/Makefile \ packages/libqpol.pc packages/libapol.pc packages/libpoldiff.pc packages/libseaudit.pc packages/libsefs.pc]) diff --git a/libapol/include/apol/Makefile.am b/libapol/include/apol/Makefile.am index 0883c10..e398ff2 100644 --- a/libapol/include/apol/Makefile.am +++ b/libapol/include/apol/Makefile.am @@ -27,6 +27,7 @@ apol_HEADERS = \ relabel-analysis.h \ render.h \ role-query.h \ + ftrule-query.h \ terule-query.h \ type-query.h \ types-relation-analysis.h \ diff --git a/libapol/include/apol/policy-query.h b/libapol/include/apol/policy-query.h index 315f70e..665e4cb 100644 --- a/libapol/include/apol/policy-query.h +++ b/libapol/include/apol/policy-query.h @@ -71,6 +71,7 @@ extern "C" #include "terule-query.h" #include "condrule-query.h" #include "rbacrule-query.h" +#include "ftrule-query.h" #include "range_trans-query.h" #include "constraint-query.h" diff --git a/libapol/src/Makefile.am b/libapol/src/Makefile.am index 3fa4f06..baaa4f6 100644 --- a/libapol/src/Makefile.am +++ b/libapol/src/Makefile.am @@ -40,6 +40,7 @@ libapol_a_SOURCES = \ render.c \ role-query.c \ terule-query.c \ + ftrule-query.c \ type-query.c \ types-relation-analysis.c \ user-query.c \ diff --git a/libapol/src/libapol.map b/libapol/src/libapol.map index 4894374..7657a2d 100644 --- a/libapol/src/libapol.map +++ b/libapol/src/libapol.map @@ -34,6 +34,7 @@ VERS_4.0{ apol_protocol_to_str; apol_qpol_context_render; apol_range_trans_*; + apol_filename_trans_*; apol_relabel_*; apol_role_*; apol_role_allow_*; diff --git a/libqpol/include/qpol/Makefile.am b/libqpol/include/qpol/Makefile.am index b55acb7..9b570e1 100644 --- a/libqpol/include/qpol/Makefile.am +++ b/libqpol/include/qpol/Makefile.am @@ -25,6 +25,7 @@ qpol_HEADERS = \ role_query.h \ syn_rule_query.h \ terule_query.h \ + ftrule_query.h \ type_query.h \ user_query.h \ util.h diff --git a/libqpol/include/qpol/policy.h b/libqpol/include/qpol/policy.h index ae4ea08..bf85718 100644 --- a/libqpol/include/qpol/policy.h +++ b/libqpol/include/qpol/policy.h @@ -55,6 +55,7 @@ extern "C" #include #include #include +#include #include #include #include diff --git a/libqpol/src/Makefile.am b/libqpol/src/Makefile.am index 34d87a6..0889a61 100644 --- a/libqpol/src/Makefile.am +++ b/libqpol/src/Makefile.am @@ -48,6 +48,7 @@ libqpol_a_SOURCES = \ syn_rule_internal.h \ syn_rule_query.c \ terule_query.c \ + ftrule_query.c \ type_query.c \ user_query.c \ util.c \ diff --git a/libqpol/src/libqpol.map b/libqpol/src/libqpol.map index dd293bc..6973cca 100644 --- a/libqpol/src/libqpol.map +++ b/libqpol/src/libqpol.map @@ -34,6 +34,7 @@ VERS_1.2 { qpol_policy_reevaluate_conds; qpol_portcon_*; qpol_range_trans_*; + qpol_filename_trans_*; qpol_role_*; qpol_syn_avrule_*; qpol_syn_terule_*; diff --git a/libqpol/src/module_compiler.c b/libqpol/src/module_compiler.c index dc19798..b06e285 100644 --- a/libqpol/src/module_compiler.c +++ b/libqpol/src/module_compiler.c @@ -1246,6 +1246,18 @@ void append_role_allow(role_allow_rule_t * role_allow_rules) decl->role_allow_rules = role_allow_rules; } +/* this doesn't actually append, but really prepends it */ +void append_filename_trans(filename_trans_rule_t * filename_trans_rules) +{ + avrule_decl_t *decl = stack_top->decl; + + /* filename transitions are not allowed within conditionals */ + assert(stack_top->type == 1); + + filename_trans_rules->next = decl->filename_trans_rules; + decl->filename_trans_rules = filename_trans_rules; +} + /* this doesn't actually append, but really prepends it */ void append_range_trans(range_trans_rule_t * range_tr_rules) { diff --git a/libqpol/src/module_compiler.h b/libqpol/src/module_compiler.h index 489086d..d46dca6 100644 --- a/libqpol/src/module_compiler.h +++ b/libqpol/src/module_compiler.h @@ -86,6 +86,7 @@ void append_avrule(avrule_t * avrule); void append_role_trans(role_trans_rule_t * role_tr_rules); void append_role_allow(role_allow_rule_t * role_allow_rules); void append_range_trans(range_trans_rule_t * range_tr_rules); +void append_filename_trans(filename_trans_rule_t * filename_trans_rules); /* Create a new optional block and add it to the global policy. * During the second pass resolve the block's requirements. Return 0 diff --git a/libqpol/src/policy_define.c b/libqpol/src/policy_define.c index c94f7aa..fad6b60 100644 --- a/libqpol/src/policy_define.c +++ b/libqpol/src/policy_define.c @@ -2132,7 +2132,9 @@ int define_role_trans(void) free(id); /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ -#ifdef HAVE_SEPOL_USER_ROLE_MAPPING +#ifdef HAVE_SEPOL_ROLE_ATTRS + if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) +#elif HAVE_SEPOL_USER_ROLE_MAPPING if (role_set_expand(&roles, &e_roles, policydbp, NULL)) #else if (role_set_expand(&roles, &e_roles, policydbp)) @@ -2226,6 +2228,190 @@ int define_role_allow(void) return 0; } +avrule_t *define_cond_filename_trans(void) +{ + yyerror("type transitions with a filename not allowed inside " + "conditionals\n"); + return COND_ERR; +} + +int define_filename_trans(void) +{ + char *id, *name = NULL; + type_set_t stypes, ttypes; + ebitmap_t e_stypes, e_ttypes; + ebitmap_t e_tclasses; + ebitmap_node_t *snode, *tnode, *cnode; + filename_trans_t *ft; + filename_trans_rule_t *ftr; + class_datum_t *cladatum; + type_datum_t *typdatum; + uint32_t otype; + unsigned int c, s, t; + int add; + + if (pass == 1) { + /* stype */ + while ((id = queue_remove(id_queue))) + free(id); + /* ttype */ + while ((id = queue_remove(id_queue))) + free(id); + /* tclass */ + while ((id = queue_remove(id_queue))) + free(id); + /* otype */ + id = queue_remove(id_queue); + free(id); + /* name */ + id = queue_remove(id_queue); + free(id); + return 0; + } + + + add = 1; + type_set_init(&stypes); + while ((id = queue_remove(id_queue))) { + if (set_types(&stypes, id, &add, 0)) + goto bad; + } + + add =1; + type_set_init(&ttypes); + while ((id = queue_remove(id_queue))) { + if (set_types(&ttypes, id, &add, 0)) + goto bad; + } + + ebitmap_init(&e_tclasses); + while ((id = queue_remove(id_queue))) { + if (!is_id_in_scope(SYM_CLASSES, id)) { + yyerror2("class %s is not within scope", id); + free(id); + goto bad; + } + cladatum = hashtab_search(policydbp->p_classes.table, id); + if (!cladatum) { + yyerror2("unknown class %s", id); + goto bad; + } + if (ebitmap_set_bit(&e_tclasses, cladatum->s.value - 1, TRUE)) { + yyerror("Out of memory"); + goto bad; + } + free(id); + } + + id = (char *)queue_remove(id_queue); + if (!id) { + yyerror("no otype in transition definition?"); + goto bad; + } + if (!is_id_in_scope(SYM_TYPES, id)) { + yyerror2("type %s is not within scope", id); + free(id); + goto bad; + } + typdatum = hashtab_search(policydbp->p_types.table, id); + if (!typdatum) { + yyerror2("unknown type %s used in transition definition", id); + goto bad; + } + free(id); + otype = typdatum->s.value; + + name = queue_remove(id_queue); + if (!name) { + yyerror("no pathname specified in filename_trans definition?"); + goto bad; + } + + /* We expand the class set into seperate rules. We expand the types + * just to make sure there are not duplicates. They will get turned + * into seperate rules later */ + ebitmap_init(&e_stypes); + if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) + goto bad; + + ebitmap_init(&e_ttypes); + if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) + goto bad; + + ebitmap_for_each_bit(&e_tclasses, cnode, c) { + if (!ebitmap_node_get_bit(cnode, c)) + continue; + ebitmap_for_each_bit(&e_stypes, snode, s) { + if (!ebitmap_node_get_bit(snode, s)) + continue; + ebitmap_for_each_bit(&e_ttypes, tnode, t) { + if (!ebitmap_node_get_bit(tnode, t)) + continue; + + for (ft = policydbp->filename_trans; ft; ft = ft->next) { + if (ft->stype == (s + 1) && + ft->ttype == (t + 1) && + ft->tclass == (c + 1) && + !strcmp(ft->name, name)) { + yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", + name, + policydbp->p_type_val_to_name[s], + policydbp->p_type_val_to_name[t], + policydbp->p_class_val_to_name[c]); + goto bad; + } + } + + ft = malloc(sizeof(*ft)); + if (!ft) { + yyerror("out of memory"); + goto bad; + } + memset(ft, 0, sizeof(*ft)); + + ft->next = policydbp->filename_trans; + policydbp->filename_trans = ft; + + ft->name = strdup(name); + if (!ft->name) { + yyerror("out of memory"); + goto bad; + } + ft->stype = s + 1; + ft->ttype = t + 1; + ft->tclass = c + 1; + ft->otype = otype; + } + } + + /* Now add the real rule since we didn't find any duplicates */ + ftr = malloc(sizeof(*ftr)); + if (!ftr) { + yyerror("out of memory"); + goto bad; + } + filename_trans_rule_init(ftr); + append_filename_trans(ftr); + + ftr->name = strdup(name); + ftr->stypes = stypes; + ftr->ttypes = ttypes; + ftr->tclass = c + 1; + ftr->otype = otype; + } + + free(name); + ebitmap_destroy(&e_stypes); + ebitmap_destroy(&e_ttypes); + ebitmap_destroy(&e_tclasses); + + return 0; + +bad: + free(name); + return -1; +} + static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) { constraint_expr_t *h = NULL, *l = NULL, *e, *newe; diff --git a/libqpol/src/policy_define.h b/libqpol/src/policy_define.h index 7be626c..f273fed 100644 --- a/libqpol/src/policy_define.h +++ b/libqpol/src/policy_define.h @@ -26,6 +26,7 @@ avrule_t *define_cond_compute_type(int which); avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * stmt); avrule_t *define_cond_te_avtab(int which); +avrule_t *define_cond_filename_trans(void); cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2); int define_attrib(void); int define_av_perms(int inherits); @@ -58,6 +59,7 @@ int define_range_trans(int class_specified); int define_role_allow(void); int define_role_trans(void); int define_role_types(void); +int define_filename_trans(void); int define_sens(void); int define_te_avtab(int which); int define_typealias(void); diff --git a/libqpol/src/policy_parse.y b/libqpol/src/policy_parse.y index 84f4114..dc16c6f 100644 --- a/libqpol/src/policy_parse.y +++ b/libqpol/src/policy_parse.y @@ -98,6 +98,7 @@ extern char *qpol_src_inputlim;/* end of data */ %type require_decl_def %token PATH +%token FILENAME %token CLONE %token COMMON %token CLASS @@ -360,7 +361,10 @@ cond_rule_def : cond_transition_def | require_block { $$ = NULL; } ; -cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';' +cond_transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' + { $$ = define_cond_filename_trans() ; + if ($$ == COND_ERR) return -1;} + | TYPE_TRANSITION names names ':' names identifier ';' { $$ = define_cond_compute_type(AVRULE_TRANSITION) ; if ($$ == COND_ERR) return -1;} | TYPE_MEMBER names names ':' names identifier ';' @@ -395,7 +399,9 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';' { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT); if ($$ == COND_ERR) return -1; } ; -transition_def : TYPE_TRANSITION names names ':' names identifier ';' +transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' + {if (define_filename_trans()) return -1; } + | TYPE_TRANSITION names names ':' names identifier ';' {if (define_compute_type(AVRULE_TRANSITION)) return -1;} | TYPE_MEMBER names names ':' names identifier ';' {if (define_compute_type(AVRULE_MEMBER)) return -1;} @@ -752,6 +758,9 @@ identifier : IDENTIFIER path : PATH { if (insert_id(yytext,0)) return -1; } ; +filename : FILENAME + { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; } + ; number : NUMBER { $$ = strtoul(yytext,NULL,0); } ; diff --git a/libqpol/src/policy_scan.l b/libqpol/src/policy_scan.l index 75485f3..30203cd 100644 --- a/libqpol/src/policy_scan.l +++ b/libqpol/src/policy_scan.l @@ -235,6 +235,7 @@ POLICYCAP { return(POLICYCAP); } permissive | PERMISSIVE { return(PERMISSIVE); } "/"({alnum}|[_\.\-/])* { return(PATH); } +\"({alnum}|[_\.\-])+\" { return(FILENAME); } {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); } {digit}+|0x{hexval}+ { return(NUMBER); } {digit}{1,3}(\.{digit}{1,3}){3} { return(IPV4_ADDR); } diff --git a/man/replcon.1 b/man/replcon.1 index 8aca08a..478dc51 100644 --- a/man/replcon.1 +++ b/man/replcon.1 @@ -44,6 +44,8 @@ Search for files which include PATH. .IP "-c CLASS, --class=CLASS" Search only files of object class CLASS. .SH OPTIONS +.IP "-R, --regex" +Enable regular expressions .IP "-v, --verbose" Display context info during replacement. .IP "-h, --help" diff --git a/man/seinfo.1 b/man/seinfo.1 index 8612119..6bc17db 100644 --- a/man/seinfo.1 +++ b/man/seinfo.1 @@ -76,6 +76,10 @@ There is no expanded information for this component. .IP "--nodecon[=ADDR]" Print a list of node contexts or, if ADDR is provided, print the statement for the node with address ADDR. There is no expanded information for this component. +.IP "--polcap" +Print policy capabilities. +.IP "--permissive" +Print permissive types. .IP "--portcon[=PORT]" Print a list of port contexts or, if PORT is provided, print the statement for port PORT. There is no expanded information for this component. @@ -93,7 +97,7 @@ These details include the types assigned to an attribute or role and the permiss This option is not available for all component types; see the description of each component for the details this option will provide. .IP "--stats" Print policy statistics including policy type and version information and counts of all components and rules. -.IP "-l" +.IP "-l, --line-breaks" Print line breaks when displaying constraint statements. .IP "-h, --help" Print help information and exit. diff --git a/man/sesearch.1 b/man/sesearch.1 index d002faf..573aedd 100644 --- a/man/sesearch.1 +++ b/man/sesearch.1 @@ -66,6 +66,8 @@ all rules of that type are considered to match the expression. Find rules with type/attribute NAME as their source. .IP "-t NAME, --target=NAME" Find rules with type/attribute NAME as their target. +.IP "-D NAME, --default=NAME" +Find rules with type NAME as their default. .IP "--role_source=NAME" Find rules with role NAME as their source. .IP "--role_target=NAME" diff --git a/seaudit/progress.c b/seaudit/progress.c index 01b01fb..2e0abeb 100644 --- a/seaudit/progress.c +++ b/seaudit/progress.c @@ -99,10 +99,11 @@ void progress_hide(progress_t * progress) int progress_wait(progress_t * progress) { - GTimeVal wait_time = { 0, 50000 }; + gint64 end_time; g_mutex_lock(progress->mutex); while (!progress->done) { - g_cond_timed_wait(progress->cond, progress->mutex, &wait_time); + end_time = g_get_monotonic_time () + 50000; // need to be set before each wait + g_cond_wait_until(progress->cond, progress->mutex, end_time); if (progress->s != NULL) { gtk_label_set_text(GTK_LABEL(progress->label2), progress->s); free(progress->s); diff --git a/seaudit/seaudit-report.c b/seaudit/seaudit-report.c index af3c6fb..d436c18 100644 --- a/seaudit/seaudit-report.c +++ b/seaudit/seaudit-report.c @@ -100,7 +100,7 @@ static void seaudit_report_info_usage(const char *program_name, int brief) printf(" -s, --stdin read log data from standard input\n"); printf(" -m, --malformed include malformed log messages\n"); printf(" -o FILE, --output=FILE output to FILE\n"); - printf(" --config=FILE read configuration from FILE\n"); + printf(" -c FILE, --config=FILE read configuration from FILE\n"); printf(" --html set output format to HTML\n"); printf(" --stylesheet=FILE HTML style sheet for formatting HTML report\n"); printf(" (ignored if --html is not given)\n"); diff --git a/secmds/seinfo.c b/secmds/seinfo.c index fdf23e9..a970890 100644 --- a/secmds/seinfo.c +++ b/secmds/seinfo.c @@ -54,13 +54,13 @@ static char *policy_file = NULL; -static void print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand); -static void print_attr_types(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand); -static void print_user_roles(FILE * fp, const qpol_user_t * user_datum, const apol_policy_t * policydb, const int expand); -static void print_role_types(FILE * fp, const qpol_role_t * role_datum, const apol_policy_t * policydb, const int expand); -static void print_bool_state(FILE * fp, const qpol_bool_t * bool_datum, const apol_policy_t * policydb, const int expand); -static void print_class_perms(FILE * fp, const qpol_class_t * class_datum, const apol_policy_t * policydb, const int expand); -static void print_cat_sens(FILE * fp, const qpol_cat_t * cat_datum, const apol_policy_t * policydb, const int expand); +static int print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand); +static int print_attr_types(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand); +static int print_user_roles(FILE * fp, const qpol_user_t * user_datum, const apol_policy_t * policydb, const int expand); +static int print_role_types(FILE * fp, const qpol_role_t * role_datum, const apol_policy_t * policydb, const int expand); +static int print_bool_state(FILE * fp, const qpol_bool_t * bool_datum, const apol_policy_t * policydb, const int expand); +static int print_class_perms(FILE * fp, const qpol_class_t * class_datum, const apol_policy_t * policydb, const int expand); +static int print_cat_sens(FILE * fp, const qpol_cat_t * cat_datum, const apol_policy_t * policydb, const int expand); static int qpol_cat_datum_compare(const void *datum1, const void *datum2, void *data); static int qpol_level_datum_compare(const void *datum1, const void *datum2, void *data); @@ -446,7 +446,8 @@ static int print_classes(FILE * fp, const char *name, int expand, const apol_pol if (name != NULL) { if (qpol_policy_get_class_by_name(q, name, &class_datum)) goto cleanup; - print_class_perms(fp, class_datum, policydb, expand); + if (print_class_perms(fp, class_datum, policydb, expand)) + goto cleanup; } else { if (qpol_policy_get_class_iter(q, &iter)) goto cleanup; @@ -457,7 +458,8 @@ static int print_classes(FILE * fp, const char *name, int expand, const apol_pol for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&class_datum)) goto cleanup; - print_class_perms(fp, class_datum, policydb, expand); + if (print_class_perms(fp, class_datum, policydb, expand)) + goto cleanup; } qpol_iterator_destroy(&iter); } @@ -510,7 +512,8 @@ static int print_types(FILE * fp, const char *name, int expand, const apol_polic if (name != NULL) { if (qpol_policy_get_type_by_name(q, name, &type_datum)) goto cleanup; - print_type_attrs(fp, type_datum, policydb, expand); + if (print_type_attrs(fp, type_datum, policydb, expand)) + goto cleanup; } else { if (qpol_policy_get_type_iter(q, &iter)) goto cleanup; @@ -518,7 +521,8 @@ static int print_types(FILE * fp, const char *name, int expand, const apol_polic for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&type_datum)) goto cleanup; - print_type_attrs(fp, type_datum, policydb, expand); + if (print_type_attrs(fp, type_datum, policydb, expand)) + goto cleanup; } } @@ -569,7 +573,10 @@ static int print_attribs(FILE * fp, const char *name, int expand, const apol_pol } type_datum = apol_vector_get_element(v, (size_t) 0); - print_attr_types(fp, type_datum, policydb, expand); + if (!type_datum) + goto cleanup; + if (print_attr_types(fp, type_datum, policydb, expand)) + goto cleanup; } else { attr_query = apol_attr_query_create(); if (!attr_query) @@ -585,7 +592,8 @@ static int print_attribs(FILE * fp, const char *name, int expand, const apol_pol type_datum = (qpol_type_t *) apol_vector_get_element(v, (size_t) i); if (!type_datum) goto cleanup; - print_attr_types(fp, type_datum, policydb, expand); + if (print_attr_types(fp, type_datum, policydb, expand)) + goto cleanup; } } apol_vector_destroy(&v); @@ -623,7 +631,8 @@ static int print_roles(FILE * fp, const char *name, int expand, const apol_polic if (name != NULL) { if (qpol_policy_get_role_by_name(q, name, &role_datum)) goto cleanup; - print_role_types(fp, role_datum, policydb, expand); + if (print_role_types(fp, role_datum, policydb, expand)) + goto cleanup; } else { if (qpol_policy_get_role_iter(q, &iter)) goto cleanup; @@ -634,7 +643,8 @@ static int print_roles(FILE * fp, const char *name, int expand, const apol_polic for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&role_datum)) goto cleanup; - print_role_types(fp, role_datum, policydb, expand); + if (print_role_types(fp, role_datum, policydb, expand)) + goto cleanup; } qpol_iterator_destroy(&iter); } @@ -671,7 +681,8 @@ static int print_booleans(FILE * fp, const char *name, int expand, const apol_po if (name != NULL) { if (qpol_policy_get_bool_by_name(q, name, &bool_datum)) goto cleanup; - print_bool_state(fp, bool_datum, policydb, expand); + if (print_bool_state(fp, bool_datum, policydb, expand)) + goto cleanup; } else { if (qpol_policy_get_bool_iter(q, &iter)) goto cleanup; @@ -681,7 +692,8 @@ static int print_booleans(FILE * fp, const char *name, int expand, const apol_po for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&bool_datum)) goto cleanup; - print_bool_state(fp, bool_datum, policydb, expand); + if (print_bool_state(fp, bool_datum, policydb, expand)) + goto cleanup; } qpol_iterator_destroy(&iter); } @@ -719,7 +731,8 @@ static int print_users(FILE * fp, const char *name, int expand, const apol_polic if (name != NULL) { if (qpol_policy_get_user_by_name(q, name, &user_datum)) goto cleanup; - print_user_roles(fp, user_datum, policydb, expand); + if (print_user_roles(fp, user_datum, policydb, expand)) + goto cleanup; } else { if (qpol_policy_get_user_iter(q, &iter)) goto cleanup; @@ -730,7 +743,8 @@ static int print_users(FILE * fp, const char *name, int expand, const apol_polic for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { if (qpol_iterator_get_item(iter, (void **)&user_datum)) goto cleanup; - print_user_roles(fp, user_datum, policydb, expand); + if (print_user_roles(fp, user_datum, policydb, expand)) + goto cleanup; } qpol_iterator_destroy(&iter); } @@ -827,7 +841,7 @@ static int print_sens(FILE * fp, const char *name, int expand, const apol_policy */ static int print_cats(FILE * fp, const char *name, int expand, const apol_policy_t * policydb) { - int retval = 0; + int retval = -1; apol_cat_query_t *query = NULL; apol_vector_t *v = NULL; const qpol_cat_t *cat_datum = NULL; @@ -851,7 +865,8 @@ static int print_cats(FILE * fp, const char *name, int expand, const apol_policy cat_datum = apol_vector_get_element(v, i); if (!cat_datum) goto cleanup; - print_cat_sens(fp, cat_datum, policydb, expand); + if (print_cat_sens(fp, cat_datum, policydb, expand)) + goto cleanup; } @@ -911,9 +926,10 @@ static int print_fsuse(FILE * fp, const char *type, const apol_policy_t * policy fprintf(fp, " %s\n", tmp); free(tmp); } - if (type && !apol_vector_get_size(v)) + if (type && !apol_vector_get_size(v)) { ERR(policydb, "No fs_use statement for filesystem of type %s.", type); - + goto cleanup; + } retval = 0; cleanup: apol_fs_use_query_destroy(&query); @@ -949,7 +965,6 @@ static int print_genfscon(FILE * fp, const char *type, const apol_policy_t * pol ERR(policydb, "%s", strerror(ENOMEM)); goto cleanup; } - if (apol_genfscon_query_set_filesystem(policydb, query, type)) goto cleanup; if (apol_genfscon_get_by_query(policydb, query, &v)) @@ -967,8 +982,10 @@ static int print_genfscon(FILE * fp, const char *type, const apol_policy_t * pol free(tmp); } - if (type && !apol_vector_get_size(v)) + if (type && !apol_vector_get_size(v)) { ERR(policydb, "No genfscon statement for filesystem of type %s.", type); + goto cleanup; + } retval = 0; cleanup: @@ -1646,6 +1663,7 @@ cleanup: // close and destroy iterators etc. int main(int argc, char **argv) { + int rc = 0; int classes, types, attribs, roles, users, all, expand, stats, rt, optc, isids, bools, sens, cats, fsuse, genfs, netif, node, port, permissives, polcaps, constrain, linebreaks; apol_policy_t *policydb = NULL; @@ -1851,46 +1869,46 @@ int main(int argc, char **argv) /* display requested info */ if (stats || all) - print_stats(stdout, policydb); + rc = print_stats(stdout, policydb); if (classes || all) - print_classes(stdout, class_name, expand, policydb); + rc = print_classes(stdout, class_name, expand, policydb); if (types || all) - print_types(stdout, type_name, expand, policydb); + rc = print_types(stdout, type_name, expand, policydb); if (attribs || all) - print_attribs(stdout, attrib_name, expand, policydb); + rc = print_attribs(stdout, attrib_name, expand, policydb); if (roles || all) - print_roles(stdout, role_name, expand, policydb); + rc = print_roles(stdout, role_name, expand, policydb); if (users || all) - print_users(stdout, user_name, expand, policydb); + rc = print_users(stdout, user_name, expand, policydb); if (bools || all) - print_booleans(stdout, bool_name, expand, policydb); + rc = print_booleans(stdout, bool_name, expand, policydb); if (sens || all) - print_sens(stdout, sens_name, expand, policydb); + rc = print_sens(stdout, sens_name, expand, policydb); if (cats || all) - print_cats(stdout, cat_name, expand, policydb); + rc = print_cats(stdout, cat_name, expand, policydb); if (fsuse || all) - print_fsuse(stdout, fsuse_type, policydb); + rc = print_fsuse(stdout, fsuse_type, policydb); if (genfs || all) - print_genfscon(stdout, genfs_type, policydb); + rc = print_genfscon(stdout, genfs_type, policydb); if (netif || all) - print_netifcon(stdout, netif_name, policydb); + rc = print_netifcon(stdout, netif_name, policydb); if (node || all) - print_nodecon(stdout, node_addr, policydb); + rc = print_nodecon(stdout, node_addr, policydb); if (port || all) - print_portcon(stdout, port_num, protocol, policydb); + rc = print_portcon(stdout, port_num, protocol, policydb); if (isids || all) - print_isids(stdout, isid_name, expand, policydb); + rc = print_isids(stdout, isid_name, expand, policydb); if (permissives || all) - print_permissives(stdout, permissive_name, expand, policydb); + rc = print_permissives(stdout, permissive_name, expand, policydb); if (polcaps || all) - print_polcaps(stdout, polcap_name, expand, policydb); + rc = print_polcaps(stdout, polcap_name, expand, policydb); if (constrain || all) - print_constraints(stdout, expand, policydb, linebreaks); + rc = print_constraints(stdout, expand, policydb, linebreaks); apol_policy_destroy(&policydb); apol_policy_path_destroy(&pol_path); free(policy_file); - exit(0); + exit(rc); } /** @@ -1903,8 +1921,9 @@ int main(int argc, char **argv) * @param expand Flag indicating whether to print each type's * attributes */ -static void print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand) +static int print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; qpol_iterator_t *iter = NULL; unsigned char isattr, isalias; const char *type_name = NULL, *attr_name = NULL; @@ -1933,9 +1952,10 @@ static void print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const ap } } + retval = 0; cleanup: qpol_iterator_destroy(&iter); - return; + return retval; } /** @@ -1948,8 +1968,9 @@ static void print_type_attrs(FILE * fp, const qpol_type_t * type_datum, const ap * @param expand Flag indicating whether to print each attribute's * types */ -static void print_attr_types(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand) +static int print_attr_types(FILE * fp, const qpol_type_t * type_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const qpol_type_t *attr_datum = NULL; qpol_iterator_t *iter = NULL; const char *attr_name = NULL, *type_name = NULL; @@ -1981,9 +2002,10 @@ static void print_attr_types(FILE * fp, const qpol_type_t * type_datum, const ap } + retval = 0; cleanup: qpol_iterator_destroy(&iter); - return; + return retval; } /** @@ -1996,8 +2018,9 @@ static void print_attr_types(FILE * fp, const qpol_type_t * type_datum, const ap * @param expand Flag indicating whether to print each user's * roles */ -static void print_user_roles(FILE * fp, const qpol_user_t * user_datum, const apol_policy_t * policydb, const int expand) +static int print_user_roles(FILE * fp, const qpol_user_t * user_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const qpol_role_t *role_datum = NULL; qpol_iterator_t *iter = NULL; const qpol_mls_range_t *range = NULL; @@ -2046,11 +2069,12 @@ static void print_user_roles(FILE * fp, const qpol_user_t * user_datum, const ap } } + retval = 0; cleanup: qpol_iterator_destroy(&iter); apol_mls_level_destroy(&ap_lvl); apol_mls_range_destroy(&ap_range); - return; + return retval; } /** @@ -2063,8 +2087,9 @@ static void print_user_roles(FILE * fp, const qpol_user_t * user_datum, const ap * @param expand Flag indicating whether to print each role's * types */ -static void print_role_types(FILE * fp, const qpol_role_t * role_datum, const apol_policy_t * policydb, const int expand) +static int print_role_types(FILE * fp, const qpol_role_t * role_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const char *role_name = NULL, *type_name = NULL; const qpol_role_t *dom_datum = NULL; const qpol_type_t *type_datum = NULL; @@ -2111,9 +2136,10 @@ static void print_role_types(FILE * fp, const qpol_role_t * role_datum, const ap } } + retval = 0; cleanup: qpol_iterator_destroy(&iter); - return; + return retval; } /** @@ -2126,22 +2152,27 @@ static void print_role_types(FILE * fp, const qpol_role_t * role_datum, const ap * @param expand Flag indicating whether to print each boolean's * initial state */ -static void print_bool_state(FILE * fp, const qpol_bool_t * bool_datum, const apol_policy_t * policydb, const int expand) +static int print_bool_state(FILE * fp, const qpol_bool_t * bool_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const char *bool_name = NULL; qpol_policy_t *q = apol_policy_get_qpol(policydb); int state; if (qpol_bool_get_name(q, bool_datum, &bool_name)) - return; + goto cleanup; fprintf(fp, " %s", bool_name); if (expand) { if (qpol_bool_get_state(q, bool_datum, &state)) - return; + goto cleanup; fprintf(fp, ": %s", state ? "TRUE" : "FALSE"); } fprintf(fp, "\n"); + + retval = 0; + cleanup: + return retval; } /** @@ -2154,8 +2185,9 @@ static void print_bool_state(FILE * fp, const qpol_bool_t * bool_datum, const ap * @param expand Flag indicating whether to print each object class' * permissions */ -static void print_class_perms(FILE * fp, const qpol_class_t * class_datum, const apol_policy_t * policydb, const int expand) +static int print_class_perms(FILE * fp, const qpol_class_t * class_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const char *class_name = NULL, *perm_name = NULL; qpol_iterator_t *iter = NULL; const qpol_common_t *common_datum = NULL; @@ -2194,9 +2226,10 @@ static void print_class_perms(FILE * fp, const qpol_class_t * class_datum, const qpol_iterator_destroy(&iter); } + retval = 0; cleanup: qpol_iterator_destroy(&iter); - return; + return retval; } /** @@ -2209,8 +2242,9 @@ static void print_class_perms(FILE * fp, const qpol_class_t * class_datum, const * @param expand Flag indicating whether to print each category's * sensitivities */ -static void print_cat_sens(FILE * fp, const qpol_cat_t * cat_datum, const apol_policy_t * policydb, const int expand) +static int print_cat_sens(FILE * fp, const qpol_cat_t * cat_datum, const apol_policy_t * policydb, const int expand) { + int retval = -1; const char *cat_name, *lvl_name; apol_level_query_t *query = NULL; apol_vector_t *v = NULL; @@ -2250,10 +2284,11 @@ static void print_cat_sens(FILE * fp, const qpol_cat_t * cat_datum, const apol_p } } + retval = 0; cleanup: apol_level_query_destroy(&query); apol_vector_destroy(&v); - return; + return retval; } /** diff --git a/secmds/sesearch.c b/secmds/sesearch.c index ec0315f..387d526 100644 --- a/secmds/sesearch.c +++ b/secmds/sesearch.c @@ -72,6 +72,7 @@ static struct option const longopts[] = { {"source", required_argument, NULL, 's'}, {"target", required_argument, NULL, 't'}, + {"default", required_argument, NULL, 'D'}, {"role_source", required_argument, NULL, EXPR_ROLE_SOURCE}, {"role_target", required_argument, NULL, EXPR_ROLE_TARGET}, {"class", required_argument, NULL, 'c'}, @@ -92,6 +93,7 @@ typedef struct options { char *src_name; char *tgt_name; + char *default_name; char *src_role_name; char *tgt_role_name; char *class_name; @@ -136,6 +138,7 @@ void usage(const char *program_name, int brief) printf("EXPRESSIONS:\n"); printf(" -s NAME, --source=NAME rules with type/attribute NAME as source\n"); printf(" -t NAME, --target=NAME rules with type/attribute NAME as target\n"); + printf(" -D NAME, --default=NAME rules with type NAME as default\n"); printf(" --role_source=NAME rules with role NAME as source\n"); printf(" --role_target=NAME rules with role NAME as target\n"); printf(" -c NAME, --class=NAME rules with class NAME as the object class\n"); @@ -293,7 +296,10 @@ static void print_syn_av_results(const apol_policy_t * policy, const options_t * tmp = apol_cond_expr_render(policy, cond); enable_char = (enabled ? 'E' : 'D'); branch_char = ((is_true && enabled) || (!is_true && !enabled) ? 'T' : 'F'); - asprintf(&expr, "[ %s ]", tmp); + if (asprintf(&expr, "[ %s ]", tmp) < 0) { + expr = NULL; + goto cleanup; + } free(tmp); tmp = NULL; if (!expr) @@ -356,7 +362,10 @@ static void print_av_results(const apol_policy_t * policy, const options_t * opt qpol_iterator_destroy(&iter); enable_char = (enabled ? 'E' : 'D'); branch_char = (list ? 'T' : 'F'); - asprintf(&expr, "[ %s ]", tmp); + if (asprintf(&expr, "[ %s ]", tmp) < 0) { + expr = NULL; + goto cleanup; + } free(tmp); tmp = NULL; if (!expr) @@ -412,6 +421,8 @@ static int perform_te_query(const apol_policy_t * policy, const options_t * opt, apol_terule_query_set_target(policy, teq, opt->tgt_name, opt->indirect); if (opt->bool_name) apol_terule_query_set_bool(policy, teq, opt->bool_name); + if (opt->default_name) + apol_terule_query_set_default(policy, teq, opt->default_name); if (opt->class_name) { if (opt->class_vector == NULL) { if (apol_terule_query_append_class(policy, teq, opt->class_name)) { @@ -488,11 +499,14 @@ static void print_syn_te_results(const apol_policy_t * policy, const options_t * tmp = apol_cond_expr_render(policy, cond); enable_char = (enabled ? 'E' : 'D'); branch_char = ((is_true && enabled) || (!is_true && !enabled) ? 'T' : 'F'); - asprintf(&expr, "[ %s ]", tmp); + if (asprintf(&expr, "[ %s ]", tmp) < 0) { + expr = NULL; + goto cleanup; + } free(tmp); tmp = NULL; if (!expr) - break; + goto cleanup; } } if (!(rule_str = apol_syn_terule_render(policy, rule))) @@ -553,7 +567,10 @@ static void print_te_results(const apol_policy_t * policy, const options_t * opt qpol_iterator_destroy(&iter); enable_char = (enabled ? 'E' : 'D'); branch_char = (list ? 'T' : 'F'); - asprintf(&expr, "[ %s ]", tmp); + if (asprintf(&expr, "[ %s ]", tmp) < 0) { + expr = NULL; + goto cleanup; + } free(tmp); tmp = NULL; if (!expr) @@ -575,6 +592,114 @@ static void print_te_results(const apol_policy_t * policy, const options_t * opt free(expr); } +static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) +{ + apol_filename_trans_query_t *ftq = NULL; + int error = 0; + + if (!policy || !opt || !v) { + ERR(policy, "%s", strerror(EINVAL)); + errno = EINVAL; + return -1; + } + + if (!opt->type && !opt->all) { + *v = NULL; + return 0; /* no search to do */ + } + + ftq = apol_filename_trans_query_create(); + if (!ftq) { + ERR(policy, "%s", strerror(ENOMEM)); + errno = ENOMEM; + return -1; + } + + apol_filename_trans_query_set_regex(policy, ftq, opt->useregex); + if (opt->src_name) { + if (apol_filename_trans_query_set_source(policy, ftq, opt->src_name, opt->indirect)) { + error = errno; + goto err; + } + } + + if (opt->tgt_name) { + if (apol_filename_trans_query_set_target(policy, ftq, opt->tgt_name, opt->indirect)) { + error = errno; + goto err; + } + } + + if (opt->default_name) { + if (apol_filename_trans_query_set_default(policy, ftq, opt->default_name)) { + error = errno; + goto err; + } + } + + if (opt->class_name) { + if (opt->class_vector == NULL) { + if (apol_filename_trans_query_append_class(policy, ftq, opt->class_name)) { + error = errno; + goto err; + } + } else { + for (size_t i = 0; i < apol_vector_get_size(opt->class_vector); ++i) { + char *class_name; + class_name = apol_vector_get_element(opt->class_vector, i); + if (!class_name) + continue; + if (apol_filename_trans_query_append_class(policy, ftq, class_name)) { + error = errno; + goto err; + } + } + } + } + + if (apol_filename_trans_get_by_query(policy, ftq, v)) { + error = errno; + goto err; + } + + apol_filename_trans_query_destroy(&ftq); + return 0; + + err: + apol_vector_destroy(v); + apol_filename_trans_query_destroy(&ftq); + ERR(policy, "%s", strerror(error)); + errno = error; + return -1; +} + +static void print_ft_results(const apol_policy_t * policy, const options_t * opt, const apol_vector_t * v) +{ + size_t i, num_filename_trans = 0; + const qpol_filename_trans_t *filename_trans = NULL; + char *filename_trans_str = NULL; + qpol_iterator_t *iter = NULL; + + if (!(num_filename_trans = apol_vector_get_size(v))) + goto cleanup; + + fprintf(stdout, "Found %zd named file transition rules:\n", num_filename_trans); + + for (i = 0; i < num_filename_trans; i++) { + if (!(filename_trans = apol_vector_get_element(v, i))) + goto cleanup; + + if (!(filename_trans_str = apol_filename_trans_render(policy, filename_trans))) + goto cleanup; + fprintf(stdout, "%s\n", filename_trans_str); + free(filename_trans_str); + filename_trans_str = NULL; + } + + cleanup: + free(filename_trans_str); +} + static int perform_ra_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) { apol_role_allow_query_t *raq = NULL; @@ -689,6 +814,13 @@ static int perform_rt_query(const apol_policy_t * policy, const options_t * opt, } } + if (opt->default_name) { + if (apol_role_trans_query_set_default(policy, rtq, opt->default_name)) { + error = errno; + goto err; + } + } + if (apol_role_trans_get_by_query(policy, rtq, v)) { error = errno; goto err; @@ -841,7 +973,7 @@ int main(int argc, char **argv) memset(&cmd_opts, 0, sizeof(cmd_opts)); cmd_opts.indirect = true; - while ((optc = getopt_long(argc, argv, "ATs:t:c:p:b:dRnSChV", longopts, NULL)) != -1) { + while ((optc = getopt_long(argc, argv, "ATs:t:c:p:b:dD:RnSChV", longopts, NULL)) != -1) { switch (optc) { case 0: break; @@ -869,6 +1001,18 @@ int main(int argc, char **argv) exit(1); } break; + case 'D': /* default */ + if (optarg == 0) { + usage(argv[0], 1); + printf("Missing default type for -D (--default)\n"); + exit(1); + } + cmd_opts.default_name = strdup(optarg); + if (!cmd_opts.default_name) { + + exit(1); + } + break; case EXPR_ROLE_SOURCE: if (optarg == 0) { usage(argv[0], 1); @@ -1128,6 +1272,17 @@ int main(int argc, char **argv) print_te_results(policy, &cmd_opts, v); fprintf(stdout, "\n"); } + + apol_vector_destroy(&v); + if (perform_ft_query(policy, &cmd_opts, &v)) { + rt = 1; + goto cleanup; + } + if (v) { + print_ft_results(policy, &cmd_opts, v); + fprintf(stdout, "\n"); + } + apol_vector_destroy(&v); if (perform_ra_query(policy, &cmd_opts, &v)) { rt = 1; @@ -1162,6 +1317,7 @@ int main(int argc, char **argv) apol_policy_path_destroy(&pol_path); free(cmd_opts.src_name); free(cmd_opts.tgt_name); + free(cmd_opts.default_name); free(cmd_opts.class_name); free(cmd_opts.permlist); free(cmd_opts.bool_name); diff --git a/sediff/sediff.c b/sediff/sediff.c index 6022775..341c650 100644 --- a/sediff/sediff.c +++ b/sediff/sediff.c @@ -420,7 +420,7 @@ int main(int argc, char **argv) poldiff_t *diff = NULL; size_t total = 0; - while ((optc = getopt_long(argc, argv, "ctarubANDLMCRqhV", longopts, NULL)) != -1) { + while ((optc = getopt_long(argc, argv, "ctarubAqhV", longopts, NULL)) != -1) { switch (optc) { case 0: break; -- cgit