diff --git a/0001-add-setools-seinfo-and-sesearch-python-bindings.patch b/0001-add-setools-seinfo-and-sesearch-python-bindings.patch new file mode 100644 index 0000000..58ac0ba --- /dev/null +++ b/0001-add-setools-seinfo-and-sesearch-python-bindings.patch @@ -0,0 +1,2773 @@ +From 32e8d1d3619dcdb40431c7eae3fe00efaae089c6 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:38:50 -0400 +Subject: [PATCH 1/6] add-setools-seinfo-and-sesearch-python-bindings + +--- + Makefile.am | 2 +- + configure.ac | 14 +- + python/Makefile.am | 1 + + python/Makefile.in | 716 +++++++++++++++++++++++++++++++++++++++++ + python/setools/Makefile.am | 36 ++ + python/setools/Makefile.in | 550 +++++++++++++++++++++++++++++++ + python/setools/__init__.py | 50 +++ + python/setools/seinfo.c | 769 ++++++++++++++++++++++++++++++++++++++++++++ + python/setools/sesearch.c | 478 +++++++++++++++++++++++++++ + python/setools/setup.py | 25 ++ + 11 files changed, 2635 insertions(+), 8 deletions(-) + create mode 100644 python/Makefile.am + create mode 100644 python/Makefile.in + create mode 100644 python/setools/Makefile.am + create mode 100644 python/setools/Makefile.in + create mode 100644 python/setools/__init__.py + create mode 100644 python/setools/seinfo.c + create mode 100644 python/setools/sesearch.c + create mode 100644 python/setools/setup.py + +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/configure.ac b/configure.ac +index b885981..e837e03 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -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 +@@ -888,6 +890,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/python/Makefile.am b/python/Makefile.am +new file mode 100644 +index 0000000..a1510c8 +--- /dev/null ++++ b/python/Makefile.am +@@ -0,0 +1 @@ ++SUBDIRS = setools +diff --git a/python/Makefile.in b/python/Makefile.in +new file mode 100644 +index 0000000..48c87ab +--- /dev/null ++++ b/python/Makefile.in +@@ -0,0 +1,716 @@ ++# Makefile.in generated by automake 1.11.1 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = python ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \ ++ $(top_srcdir)/m4/ac_java_options.m4 \ ++ $(top_srcdir)/m4/ac_pkg_swig.m4 \ ++ $(top_srcdir)/m4/ac_prog_jar.m4 \ ++ $(top_srcdir)/m4/ac_prog_java.m4 \ ++ $(top_srcdir)/m4/ac_prog_java_works.m4 \ ++ $(top_srcdir)/m4/ac_prog_javac.m4 \ ++ $(top_srcdir)/m4/ac_prog_javac_works.m4 \ ++ $(top_srcdir)/m4/ac_python_devel.m4 $(top_srcdir)/m4/c.m4 \ ++ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ ++ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ ++ $(top_srcdir)/m4/lt~obsolete.m4 \ ++ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/m4/tcl.m4 \ ++ $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++SOURCES = ++DIST_SOURCES = ++RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ ++ html-recursive info-recursive install-data-recursive \ ++ install-dvi-recursive install-exec-recursive \ ++ install-html-recursive install-info-recursive \ ++ install-pdf-recursive install-ps-recursive install-recursive \ ++ installcheck-recursive installdirs-recursive pdf-recursive \ ++ ps-recursive uninstall-recursive ++RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ ++ distclean-recursive maintainer-clean-recursive ++AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ ++ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ ++ distdir ++ETAGS = etags ++CTAGS = ctags ++DIST_SUBDIRS = $(SUBDIRS) ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++am__relativize = \ ++ dir0=`pwd`; \ ++ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ ++ sed_rest='s,^[^/]*/*,,'; \ ++ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ ++ sed_butlast='s,/*[^/]*$$,,'; \ ++ while test -n "$$dir1"; do \ ++ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ ++ if test "$$first" != "."; then \ ++ if test "$$first" = ".."; then \ ++ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ ++ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ ++ else \ ++ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ ++ if test "$$first2" = "$$first"; then \ ++ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ ++ else \ ++ dir2="../$$dir2"; \ ++ fi; \ ++ dir0="$$dir0"/"$$first"; \ ++ fi; \ ++ fi; \ ++ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ ++ done; \ ++ reldir="$$dir2" ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++APOL_CFLAGS = @APOL_CFLAGS@ ++APOL_LIB_FLAG = @APOL_LIB_FLAG@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BWIDGET_DESTDIR = @BWIDGET_DESTDIR@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CUNIT_LIB_FLAG = @CUNIT_LIB_FLAG@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH = @CYGPATH@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUGCFLAGS = @DEBUGCFLAGS@ ++DEBUGCXXFLAGS = @DEBUGCXXFLAGS@ ++DEBUGJFLAGS = @DEBUGJFLAGS@ ++DEBUGLDFLAGS = @DEBUGLDFLAGS@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GLADE_CFLAGS = @GLADE_CFLAGS@ ++GLADE_LIBS = @GLADE_LIBS@ ++GREP = @GREP@ ++GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ ++GTHREAD_LIBS = @GTHREAD_LIBS@ ++GTK_CFLAGS = @GTK_CFLAGS@ ++GTK_LIBS = @GTK_LIBS@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++JAR = @JAR@ ++JAVA = @JAVA@ ++JAVAC = @JAVAC@ ++JAVACFLAGS = @JAVACFLAGS@ ++JAVAFLAGS = @JAVAFLAGS@ ++JAVAPREFIX = @JAVAPREFIX@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LEX = @LEX@ ++LEXLIB = @LEXLIB@ ++LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++MKDIR_P = @MKDIR_P@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++PIXBUF_CFLAGS = @PIXBUF_CFLAGS@ ++PIXBUF_LIBS = @PIXBUF_LIBS@ ++PKG_CFLAGS = @PKG_CFLAGS@ ++PKG_HEADERS = @PKG_HEADERS@ ++PKG_INCLUDES = @PKG_INCLUDES@ ++PKG_LIBS = @PKG_LIBS@ ++PKG_LIB_FILE = @PKG_LIB_FILE@ ++PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ ++PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ ++PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ ++PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ ++POLDIFF_CFLAGS = @POLDIFF_CFLAGS@ ++POLDIFF_LIB_FLAG = @POLDIFF_LIB_FLAG@ ++PROFILECFLAGS = @PROFILECFLAGS@ ++PROFILELDFLAGS = @PROFILELDFLAGS@ ++PYTHON = @PYTHON@ ++PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ ++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ ++PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ ++PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ ++PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ ++PYTHON_PLATFORM = @PYTHON_PLATFORM@ ++PYTHON_PREFIX = @PYTHON_PREFIX@ ++PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ ++PYTHON_VERSION = @PYTHON_VERSION@ ++QPOL_CFLAGS = @QPOL_CFLAGS@ ++QPOL_LIB_FLAG = @QPOL_LIB_FLAG@ ++RANLIB = @RANLIB@ ++SEAUDIT_CFLAGS = @SEAUDIT_CFLAGS@ ++SEAUDIT_LIB_FLAG = @SEAUDIT_LIB_FLAG@ ++SED = @SED@ ++SEFS_CFLAGS = @SEFS_CFLAGS@ ++SEFS_LIB_FLAG = @SEFS_LIB_FLAG@ ++SELINUX_CFLAGS = @SELINUX_CFLAGS@ ++SELINUX_LIB_FLAG = @SELINUX_LIB_FLAG@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ ++SQLITE3_LIBS = @SQLITE3_LIBS@ ++STRIP = @STRIP@ ++SWIG = @SWIG@ ++SWIG_JAVA_CFLAGS = @SWIG_JAVA_CFLAGS@ ++SWIG_JAVA_OPT = @SWIG_JAVA_OPT@ ++SWIG_LIB = @SWIG_LIB@ ++SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ ++SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ ++SWIG_TCL_CFLAGS = @SWIG_TCL_CFLAGS@ ++SWIG_TCL_OPT = @SWIG_TCL_OPT@ ++TCLSH_PROG = @TCLSH_PROG@ ++TCL_AUTOPATH = @TCL_AUTOPATH@ ++TCL_BIN_DIR = @TCL_BIN_DIR@ ++TCL_DEFS = @TCL_DEFS@ ++TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ ++TCL_INCLUDES = @TCL_INCLUDES@ ++TCL_LD_FLAGS = @TCL_LD_FLAGS@ ++TCL_LIBS = @TCL_LIBS@ ++TCL_LIB_FILE = @TCL_LIB_FILE@ ++TCL_LIB_FLAG = @TCL_LIB_FLAG@ ++TCL_LIB_SPEC = @TCL_LIB_SPEC@ ++TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ ++TCL_SRC_DIR = @TCL_SRC_DIR@ ++TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ ++TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ ++TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ ++TCL_VERSION = @TCL_VERSION@ ++TK_BIN_DIR = @TK_BIN_DIR@ ++TK_INCLUDES = @TK_INCLUDES@ ++TK_LIBS = @TK_LIBS@ ++TK_LIB_FILE = @TK_LIB_FILE@ ++TK_LIB_FLAG = @TK_LIB_FLAG@ ++TK_LIB_SPEC = @TK_LIB_SPEC@ ++TK_SRC_DIR = @TK_SRC_DIR@ ++TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ ++TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ ++TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ ++TK_VERSION = @TK_VERSION@ ++TK_XINCLUDES = @TK_XINCLUDES@ ++VERSION = @VERSION@ ++WARNCFLAGS = @WARNCFLAGS@ ++WARNCXXFLAGS = @WARNCXXFLAGS@ ++WARNJFLAGS = @WARNJFLAGS@ ++WARNLDFLAGS = @WARNLDFLAGS@ ++WISH_PROG = @WISH_PROG@ ++XMKMF = @XMKMF@ ++XML_CFLAGS = @XML_CFLAGS@ ++XML_LIBS = @XML_LIBS@ ++YACC = @YACC@ ++YFLAGS = @YFLAGS@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++has_pkg_config = @has_pkg_config@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++javadir = @javadir@ ++libapol_jswig_soname = @libapol_jswig_soname@ ++libapol_pyswig_soname = @libapol_pyswig_soname@ ++libapol_soname = @libapol_soname@ ++libapol_soversion = @libapol_soversion@ ++libapol_tswig_soname = @libapol_tswig_soname@ ++libapol_version = @libapol_version@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++libpoldiff_jswig_soname = @libpoldiff_jswig_soname@ ++libpoldiff_pyswig_soname = @libpoldiff_pyswig_soname@ ++libpoldiff_soname = @libpoldiff_soname@ ++libpoldiff_soversion = @libpoldiff_soversion@ ++libpoldiff_tswig_soname = @libpoldiff_tswig_soname@ ++libpoldiff_version = @libpoldiff_version@ ++libqpol_jswig_soname = @libqpol_jswig_soname@ ++libqpol_pyswig_soname = @libqpol_pyswig_soname@ ++libqpol_soname = @libqpol_soname@ ++libqpol_soversion = @libqpol_soversion@ ++libqpol_tswig_soname = @libqpol_tswig_soname@ ++libqpol_version = @libqpol_version@ ++libseaudit_jswig_soname = @libseaudit_jswig_soname@ ++libseaudit_pyswig_soname = @libseaudit_pyswig_soname@ ++libseaudit_soname = @libseaudit_soname@ ++libseaudit_soversion = @libseaudit_soversion@ ++libseaudit_tswig_soname = @libseaudit_tswig_soname@ ++libseaudit_version = @libseaudit_version@ ++libsefs_jswig_soname = @libsefs_jswig_soname@ ++libsefs_pyswig_soname = @libsefs_pyswig_soname@ ++libsefs_soname = @libsefs_soname@ ++libsefs_soversion = @libsefs_soversion@ ++libsefs_tswig_soname = @libsefs_tswig_soname@ ++libsefs_version = @libsefs_version@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++lt_ECHO = @lt_ECHO@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++pdfdir = @pdfdir@ ++pkgpyexecdir = @pkgpyexecdir@ ++pkgpythondir = @pkgpythondir@ ++prefix = @prefix@ ++profile_install_dir = @profile_install_dir@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++pyexecdir = @pyexecdir@ ++pythondir = @pythondir@ ++sbindir = @sbindir@ ++selinux_default_policy = @selinux_default_policy@ ++selinux_policy_dir = @selinux_policy_dir@ ++sepol_srcdir = @sepol_srcdir@ ++setoolsdir = @setoolsdir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++uudecode = @uudecode@ ++SUBDIRS = setools ++all: all-recursive ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ ++ && { if test -f $@; then exit 0; else break; fi; }; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu python/Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu python/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(am__aclocal_m4_deps): ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++ ++# This directory's subdirectories are mostly independent; you can cd ++# into them and run `make' without going through this Makefile. ++# To change the values of `make' variables: instead of editing Makefiles, ++# (1) if the variable is set in `config.status', edit `config.status' ++# (which will cause the Makefiles to be regenerated when you run `make'); ++# (2) otherwise, pass the desired values on the `make' command line. ++$(RECURSIVE_TARGETS): ++ @fail= failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ dot_seen=yes; \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done; \ ++ if test "$$dot_seen" = "no"; then \ ++ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ ++ fi; test -z "$$fail" ++ ++$(RECURSIVE_CLEAN_TARGETS): ++ @fail= failcom='exit 1'; \ ++ for f in x $$MAKEFLAGS; do \ ++ case $$f in \ ++ *=* | --[!k]*);; \ ++ *k*) failcom='fail=yes';; \ ++ esac; \ ++ done; \ ++ dot_seen=no; \ ++ case "$@" in \ ++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ ++ *) list='$(SUBDIRS)' ;; \ ++ esac; \ ++ rev=''; for subdir in $$list; do \ ++ if test "$$subdir" = "."; then :; else \ ++ rev="$$subdir $$rev"; \ ++ fi; \ ++ done; \ ++ rev="$$rev ."; \ ++ target=`echo $@ | sed s/-recursive//`; \ ++ for subdir in $$rev; do \ ++ echo "Making $$target in $$subdir"; \ ++ if test "$$subdir" = "."; then \ ++ local_target="$$target-am"; \ ++ else \ ++ local_target="$$target"; \ ++ fi; \ ++ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ ++ || eval $$failcom; \ ++ done && test -z "$$fail" ++tags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ ++ done ++ctags-recursive: ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ ++ done ++ ++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ mkid -fID $$unique ++tags: TAGS ++ ++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ set x; \ ++ here=`pwd`; \ ++ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ ++ include_option=--etags-include; \ ++ empty_fix=.; \ ++ else \ ++ include_option=--include; \ ++ empty_fix=; \ ++ fi; \ ++ list='$(SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test ! -f $$subdir/TAGS || \ ++ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ ++ fi; \ ++ done; \ ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ shift; \ ++ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ ++ test -n "$$unique" || unique=$$empty_fix; \ ++ if test $$# -gt 0; then \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ "$$@" $$unique; \ ++ else \ ++ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ ++ $$unique; \ ++ fi; \ ++ fi ++ctags: CTAGS ++CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ ++ $(TAGS_FILES) $(LISP) ++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ ++ unique=`for i in $$list; do \ ++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ ++ done | \ ++ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ ++ END { if (nonempty) { for (i in files) print i; }; }'`; \ ++ test -z "$(CTAGS_ARGS)$$unique" \ ++ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ ++ $$unique ++ ++GTAGS: ++ here=`$(am__cd) $(top_builddir) && pwd` \ ++ && $(am__cd) $(top_srcdir) \ ++ && gtags -i $(GTAGS_ARGS) "$$here" ++ ++distclean-tags: ++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ list='$(DISTFILES)'; \ ++ dist_files=`for file in $$list; do echo $$file; done | \ ++ sed -e "s|^$$srcdirstrip/||;t" \ ++ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ ++ case $$dist_files in \ ++ */*) $(MKDIR_P) `echo "$$dist_files" | \ ++ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ ++ sort -u` ;; \ ++ esac; \ ++ for file in $$dist_files; do \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ if test -d $$d/$$file; then \ ++ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test -d "$(distdir)/$$file"; then \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ ++ else \ ++ test -f "$(distdir)/$$file" \ ++ || cp -p $$d/$$file "$(distdir)/$$file" \ ++ || exit 1; \ ++ fi; \ ++ done ++ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ test -d "$(distdir)/$$subdir" \ ++ || $(MKDIR_P) "$(distdir)/$$subdir" \ ++ || exit 1; \ ++ fi; \ ++ done ++ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ ++ if test "$$subdir" = .; then :; else \ ++ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ ++ $(am__relativize); \ ++ new_distdir=$$reldir; \ ++ dir1=$$subdir; dir2="$(top_distdir)"; \ ++ $(am__relativize); \ ++ new_top_distdir=$$reldir; \ ++ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ ++ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ++ ($(am__cd) $$subdir && \ ++ $(MAKE) $(AM_MAKEFLAGS) \ ++ top_distdir="$$new_top_distdir" \ ++ distdir="$$new_distdir" \ ++ am__remove_distdir=: \ ++ am__skip_length_check=: \ ++ am__skip_mode_fix=: \ ++ distdir) \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-recursive ++all-am: Makefile ++installdirs: installdirs-recursive ++installdirs-am: ++install: install-recursive ++install-exec: install-exec-recursive ++install-data: install-data-recursive ++uninstall: uninstall-recursive ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-recursive ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-recursive ++ ++clean-am: clean-generic clean-libtool mostlyclean-am ++ ++distclean: distclean-recursive ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic distclean-tags ++ ++dvi: dvi-recursive ++ ++dvi-am: ++ ++html: html-recursive ++ ++html-am: ++ ++info: info-recursive ++ ++info-am: ++ ++install-data-am: ++ ++install-dvi: install-dvi-recursive ++ ++install-dvi-am: ++ ++install-exec-am: ++ ++install-html: install-html-recursive ++ ++install-html-am: ++ ++install-info: install-info-recursive ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-recursive ++ ++install-pdf-am: ++ ++install-ps: install-ps-recursive ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-recursive ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-recursive ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-recursive ++ ++pdf-am: ++ ++ps: ps-recursive ++ ++ps-am: ++ ++uninstall-am: ++ ++.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ ++ install-am install-strip tags-recursive ++ ++.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ ++ all all-am check check-am clean clean-generic clean-libtool \ ++ ctags ctags-recursive distclean distclean-generic \ ++ distclean-libtool distclean-tags distdir dvi dvi-am html \ ++ html-am info info-am install install-am install-data \ ++ install-data-am install-dvi install-dvi-am install-exec \ ++ install-exec-am install-html install-html-am install-info \ ++ install-info-am install-man install-pdf install-pdf-am \ ++ install-ps install-ps-am install-strip installcheck \ ++ installcheck-am installdirs installdirs-am maintainer-clean \ ++ maintainer-clean-generic mostlyclean mostlyclean-generic \ ++ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ ++ uninstall uninstall-am ++ ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff --git a/python/setools/Makefile.am b/python/setools/Makefile.am +new file mode 100644 +index 0000000..c4635fb +--- /dev/null ++++ b/python/setools/Makefile.am +@@ -0,0 +1,36 @@ ++EXTRA_DIST = \ ++ sesearch.c \ ++ seinfo.c \ ++ __init__.py \ ++ setup.py \ ++ $(NULL) ++ ++AM_CFLAGS = @DEBUGCFLAGS@ @WARNCFLAGS@ @PROFILECFLAGS@ @SELINUX_CFLAGS@ \ ++ @QPOL_CFLAGS@ @APOL_CFLAGS@ ++AM_CXXFLAGS = @DEBUGCXXFLAGS@ @WARNCXXFLAGS@ @PROFILECFLAGS@ @SELINUX_CFLAGS@ \ ++ @QPOL_CFLAGS@ @APOL_CFLAGS@ @SEFS_CFLAGS@ ++AM_LDFLAGS = @DEBUGLDFLAGS@ @WARNLDFLAGS@ @PROFILELDFLAGS@ ++ ++LDADD = @SELINUX_LIB_FLAG@ @APOL_LIB_FLAG@ @QPOL_LIB_FLAG@ ++DEPENDENCIES = $(top_builddir)/libapol/src/libapol.so $(top_builddir)/libqpol/src/libqpol.so ++all-am: python-build ++ ++seinfo_SOURCES = seinfo.c ++ ++sesearch_SOURCES = sesearch.c ++ ++python-build: sesearch.c seinfo.c ++ @mkdir -p setools ++ @cp __init__.py setools ++ LIBS="$(QPOL_LIB_FLAG) $(APOL_LIB_FLAG)" INCLUDES="$(QPOL_CFLAGS) $(APOL_CFLAGS)" $(PYTHON) setup.py build ++ ++install-exec-hook: ++ $(PYTHON) setup.py install `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` ++ ++uninstall-hook: ++ $(PYTHON) setup.py uninstall `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` ++ ++clean-local: ++ $(PYTHON) setup.py clean -a ++ rm -f *~ ++ +diff --git a/python/setools/Makefile.in b/python/setools/Makefile.in +new file mode 100644 +index 0000000..704ffc7 +--- /dev/null ++++ b/python/setools/Makefile.in +@@ -0,0 +1,550 @@ ++# Makefile.in generated by automake 1.11.1 from Makefile.am. ++# @configure_input@ ++ ++# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, ++# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, ++# Inc. ++# This Makefile.in is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++@SET_MAKE@ ++VPATH = @srcdir@ ++pkgdatadir = $(datadir)/@PACKAGE@ ++pkgincludedir = $(includedir)/@PACKAGE@ ++pkglibdir = $(libdir)/@PACKAGE@ ++pkglibexecdir = $(libexecdir)/@PACKAGE@ ++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd ++install_sh_DATA = $(install_sh) -c -m 644 ++install_sh_PROGRAM = $(install_sh) -c ++install_sh_SCRIPT = $(install_sh) -c ++INSTALL_HEADER = $(INSTALL_DATA) ++transform = $(program_transform_name) ++NORMAL_INSTALL = : ++PRE_INSTALL = : ++POST_INSTALL = : ++NORMAL_UNINSTALL = : ++PRE_UNINSTALL = : ++POST_UNINSTALL = : ++build_triplet = @build@ ++host_triplet = @host@ ++subdir = python/setools ++DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ++am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_classpath.m4 \ ++ $(top_srcdir)/m4/ac_java_options.m4 \ ++ $(top_srcdir)/m4/ac_pkg_swig.m4 \ ++ $(top_srcdir)/m4/ac_prog_jar.m4 \ ++ $(top_srcdir)/m4/ac_prog_java.m4 \ ++ $(top_srcdir)/m4/ac_prog_java_works.m4 \ ++ $(top_srcdir)/m4/ac_prog_javac.m4 \ ++ $(top_srcdir)/m4/ac_prog_javac_works.m4 \ ++ $(top_srcdir)/m4/ac_python_devel.m4 $(top_srcdir)/m4/c.m4 \ ++ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ ++ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ ++ $(top_srcdir)/m4/lt~obsolete.m4 \ ++ $(top_srcdir)/m4/swig_python.m4 $(top_srcdir)/m4/tcl.m4 \ ++ $(top_srcdir)/configure.ac ++am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ ++ $(ACLOCAL_M4) ++mkinstalldirs = $(install_sh) -d ++CONFIG_HEADER = $(top_builddir)/config.h ++CONFIG_CLEAN_FILES = ++CONFIG_CLEAN_VPATH_FILES = ++SOURCES = ++DIST_SOURCES = ++DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ++ACLOCAL = @ACLOCAL@ ++AMTAR = @AMTAR@ ++APOL_CFLAGS = @APOL_CFLAGS@ ++APOL_LIB_FLAG = @APOL_LIB_FLAG@ ++AR = @AR@ ++AUTOCONF = @AUTOCONF@ ++AUTOHEADER = @AUTOHEADER@ ++AUTOMAKE = @AUTOMAKE@ ++AWK = @AWK@ ++BWIDGET_DESTDIR = @BWIDGET_DESTDIR@ ++CC = @CC@ ++CCDEPMODE = @CCDEPMODE@ ++CFLAGS = @CFLAGS@ ++CPP = @CPP@ ++CPPFLAGS = @CPPFLAGS@ ++CUNIT_LIB_FLAG = @CUNIT_LIB_FLAG@ ++CXX = @CXX@ ++CXXCPP = @CXXCPP@ ++CXXDEPMODE = @CXXDEPMODE@ ++CXXFLAGS = @CXXFLAGS@ ++CYGPATH = @CYGPATH@ ++CYGPATH_W = @CYGPATH_W@ ++DEBUGCFLAGS = @DEBUGCFLAGS@ ++DEBUGCXXFLAGS = @DEBUGCXXFLAGS@ ++DEBUGJFLAGS = @DEBUGJFLAGS@ ++DEBUGLDFLAGS = @DEBUGLDFLAGS@ ++DEFS = @DEFS@ ++DEPDIR = @DEPDIR@ ++DSYMUTIL = @DSYMUTIL@ ++DUMPBIN = @DUMPBIN@ ++ECHO_C = @ECHO_C@ ++ECHO_N = @ECHO_N@ ++ECHO_T = @ECHO_T@ ++EGREP = @EGREP@ ++EXEEXT = @EXEEXT@ ++FGREP = @FGREP@ ++GLADE_CFLAGS = @GLADE_CFLAGS@ ++GLADE_LIBS = @GLADE_LIBS@ ++GREP = @GREP@ ++GTHREAD_CFLAGS = @GTHREAD_CFLAGS@ ++GTHREAD_LIBS = @GTHREAD_LIBS@ ++GTK_CFLAGS = @GTK_CFLAGS@ ++GTK_LIBS = @GTK_LIBS@ ++INSTALL = @INSTALL@ ++INSTALL_DATA = @INSTALL_DATA@ ++INSTALL_PROGRAM = @INSTALL_PROGRAM@ ++INSTALL_SCRIPT = @INSTALL_SCRIPT@ ++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ ++JAR = @JAR@ ++JAVA = @JAVA@ ++JAVAC = @JAVAC@ ++JAVACFLAGS = @JAVACFLAGS@ ++JAVAFLAGS = @JAVAFLAGS@ ++JAVAPREFIX = @JAVAPREFIX@ ++LD = @LD@ ++LDFLAGS = @LDFLAGS@ ++LEX = @LEX@ ++LEXLIB = @LEXLIB@ ++LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ ++LIBOBJS = @LIBOBJS@ ++LIBS = @LIBS@ ++LIBTOOL = @LIBTOOL@ ++LIPO = @LIPO@ ++LN_S = @LN_S@ ++LTLIBOBJS = @LTLIBOBJS@ ++MAKEINFO = @MAKEINFO@ ++MKDIR_P = @MKDIR_P@ ++NM = @NM@ ++NMEDIT = @NMEDIT@ ++OBJDUMP = @OBJDUMP@ ++OBJEXT = @OBJEXT@ ++OTOOL = @OTOOL@ ++OTOOL64 = @OTOOL64@ ++PACKAGE = @PACKAGE@ ++PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ ++PACKAGE_NAME = @PACKAGE_NAME@ ++PACKAGE_STRING = @PACKAGE_STRING@ ++PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ ++PACKAGE_VERSION = @PACKAGE_VERSION@ ++PATH_SEPARATOR = @PATH_SEPARATOR@ ++PIXBUF_CFLAGS = @PIXBUF_CFLAGS@ ++PIXBUF_LIBS = @PIXBUF_LIBS@ ++PKG_CFLAGS = @PKG_CFLAGS@ ++PKG_HEADERS = @PKG_HEADERS@ ++PKG_INCLUDES = @PKG_INCLUDES@ ++PKG_LIBS = @PKG_LIBS@ ++PKG_LIB_FILE = @PKG_LIB_FILE@ ++PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ ++PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ ++PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ ++PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ ++POLDIFF_CFLAGS = @POLDIFF_CFLAGS@ ++POLDIFF_LIB_FLAG = @POLDIFF_LIB_FLAG@ ++PROFILECFLAGS = @PROFILECFLAGS@ ++PROFILELDFLAGS = @PROFILELDFLAGS@ ++PYTHON = @PYTHON@ ++PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ ++PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ ++PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ ++PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ ++PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ ++PYTHON_PLATFORM = @PYTHON_PLATFORM@ ++PYTHON_PREFIX = @PYTHON_PREFIX@ ++PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ ++PYTHON_VERSION = @PYTHON_VERSION@ ++QPOL_CFLAGS = @QPOL_CFLAGS@ ++QPOL_LIB_FLAG = @QPOL_LIB_FLAG@ ++RANLIB = @RANLIB@ ++SEAUDIT_CFLAGS = @SEAUDIT_CFLAGS@ ++SEAUDIT_LIB_FLAG = @SEAUDIT_LIB_FLAG@ ++SED = @SED@ ++SEFS_CFLAGS = @SEFS_CFLAGS@ ++SEFS_LIB_FLAG = @SEFS_LIB_FLAG@ ++SELINUX_CFLAGS = @SELINUX_CFLAGS@ ++SELINUX_LIB_FLAG = @SELINUX_LIB_FLAG@ ++SET_MAKE = @SET_MAKE@ ++SHELL = @SHELL@ ++SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ ++SQLITE3_LIBS = @SQLITE3_LIBS@ ++STRIP = @STRIP@ ++SWIG = @SWIG@ ++SWIG_JAVA_CFLAGS = @SWIG_JAVA_CFLAGS@ ++SWIG_JAVA_OPT = @SWIG_JAVA_OPT@ ++SWIG_LIB = @SWIG_LIB@ ++SWIG_PYTHON_CPPFLAGS = @SWIG_PYTHON_CPPFLAGS@ ++SWIG_PYTHON_OPT = @SWIG_PYTHON_OPT@ ++SWIG_TCL_CFLAGS = @SWIG_TCL_CFLAGS@ ++SWIG_TCL_OPT = @SWIG_TCL_OPT@ ++TCLSH_PROG = @TCLSH_PROG@ ++TCL_AUTOPATH = @TCL_AUTOPATH@ ++TCL_BIN_DIR = @TCL_BIN_DIR@ ++TCL_DEFS = @TCL_DEFS@ ++TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ ++TCL_INCLUDES = @TCL_INCLUDES@ ++TCL_LD_FLAGS = @TCL_LD_FLAGS@ ++TCL_LIBS = @TCL_LIBS@ ++TCL_LIB_FILE = @TCL_LIB_FILE@ ++TCL_LIB_FLAG = @TCL_LIB_FLAG@ ++TCL_LIB_SPEC = @TCL_LIB_SPEC@ ++TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ ++TCL_SRC_DIR = @TCL_SRC_DIR@ ++TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ ++TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ ++TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ ++TCL_VERSION = @TCL_VERSION@ ++TK_BIN_DIR = @TK_BIN_DIR@ ++TK_INCLUDES = @TK_INCLUDES@ ++TK_LIBS = @TK_LIBS@ ++TK_LIB_FILE = @TK_LIB_FILE@ ++TK_LIB_FLAG = @TK_LIB_FLAG@ ++TK_LIB_SPEC = @TK_LIB_SPEC@ ++TK_SRC_DIR = @TK_SRC_DIR@ ++TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ ++TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ ++TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ ++TK_VERSION = @TK_VERSION@ ++TK_XINCLUDES = @TK_XINCLUDES@ ++VERSION = @VERSION@ ++WARNCFLAGS = @WARNCFLAGS@ ++WARNCXXFLAGS = @WARNCXXFLAGS@ ++WARNJFLAGS = @WARNJFLAGS@ ++WARNLDFLAGS = @WARNLDFLAGS@ ++WISH_PROG = @WISH_PROG@ ++XMKMF = @XMKMF@ ++XML_CFLAGS = @XML_CFLAGS@ ++XML_LIBS = @XML_LIBS@ ++YACC = @YACC@ ++YFLAGS = @YFLAGS@ ++abs_builddir = @abs_builddir@ ++abs_srcdir = @abs_srcdir@ ++abs_top_builddir = @abs_top_builddir@ ++abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_CC = @ac_ct_CC@ ++ac_ct_CXX = @ac_ct_CXX@ ++ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ ++am__include = @am__include@ ++am__leading_dot = @am__leading_dot@ ++am__quote = @am__quote@ ++am__tar = @am__tar@ ++am__untar = @am__untar@ ++bindir = @bindir@ ++build = @build@ ++build_alias = @build_alias@ ++build_cpu = @build_cpu@ ++build_os = @build_os@ ++build_vendor = @build_vendor@ ++builddir = @builddir@ ++datadir = @datadir@ ++datarootdir = @datarootdir@ ++docdir = @docdir@ ++dvidir = @dvidir@ ++exec_prefix = @exec_prefix@ ++has_pkg_config = @has_pkg_config@ ++host = @host@ ++host_alias = @host_alias@ ++host_cpu = @host_cpu@ ++host_os = @host_os@ ++host_vendor = @host_vendor@ ++htmldir = @htmldir@ ++includedir = @includedir@ ++infodir = @infodir@ ++install_sh = @install_sh@ ++javadir = @javadir@ ++libapol_jswig_soname = @libapol_jswig_soname@ ++libapol_pyswig_soname = @libapol_pyswig_soname@ ++libapol_soname = @libapol_soname@ ++libapol_soversion = @libapol_soversion@ ++libapol_tswig_soname = @libapol_tswig_soname@ ++libapol_version = @libapol_version@ ++libdir = @libdir@ ++libexecdir = @libexecdir@ ++libpoldiff_jswig_soname = @libpoldiff_jswig_soname@ ++libpoldiff_pyswig_soname = @libpoldiff_pyswig_soname@ ++libpoldiff_soname = @libpoldiff_soname@ ++libpoldiff_soversion = @libpoldiff_soversion@ ++libpoldiff_tswig_soname = @libpoldiff_tswig_soname@ ++libpoldiff_version = @libpoldiff_version@ ++libqpol_jswig_soname = @libqpol_jswig_soname@ ++libqpol_pyswig_soname = @libqpol_pyswig_soname@ ++libqpol_soname = @libqpol_soname@ ++libqpol_soversion = @libqpol_soversion@ ++libqpol_tswig_soname = @libqpol_tswig_soname@ ++libqpol_version = @libqpol_version@ ++libseaudit_jswig_soname = @libseaudit_jswig_soname@ ++libseaudit_pyswig_soname = @libseaudit_pyswig_soname@ ++libseaudit_soname = @libseaudit_soname@ ++libseaudit_soversion = @libseaudit_soversion@ ++libseaudit_tswig_soname = @libseaudit_tswig_soname@ ++libseaudit_version = @libseaudit_version@ ++libsefs_jswig_soname = @libsefs_jswig_soname@ ++libsefs_pyswig_soname = @libsefs_pyswig_soname@ ++libsefs_soname = @libsefs_soname@ ++libsefs_soversion = @libsefs_soversion@ ++libsefs_tswig_soname = @libsefs_tswig_soname@ ++libsefs_version = @libsefs_version@ ++localedir = @localedir@ ++localstatedir = @localstatedir@ ++lt_ECHO = @lt_ECHO@ ++mandir = @mandir@ ++mkdir_p = @mkdir_p@ ++oldincludedir = @oldincludedir@ ++pdfdir = @pdfdir@ ++pkgpyexecdir = @pkgpyexecdir@ ++pkgpythondir = @pkgpythondir@ ++prefix = @prefix@ ++profile_install_dir = @profile_install_dir@ ++program_transform_name = @program_transform_name@ ++psdir = @psdir@ ++pyexecdir = @pyexecdir@ ++pythondir = @pythondir@ ++sbindir = @sbindir@ ++selinux_default_policy = @selinux_default_policy@ ++selinux_policy_dir = @selinux_policy_dir@ ++sepol_srcdir = @sepol_srcdir@ ++setoolsdir = @setoolsdir@ ++sharedstatedir = @sharedstatedir@ ++srcdir = @srcdir@ ++sysconfdir = @sysconfdir@ ++target_alias = @target_alias@ ++top_build_prefix = @top_build_prefix@ ++top_builddir = @top_builddir@ ++top_srcdir = @top_srcdir@ ++uudecode = @uudecode@ ++EXTRA_DIST = \ ++ sesearch.c \ ++ seinfo.c \ ++ __init__.py \ ++ setup.py \ ++ $(NULL) ++ ++AM_CFLAGS = @DEBUGCFLAGS@ @WARNCFLAGS@ @PROFILECFLAGS@ @SELINUX_CFLAGS@ \ ++ @QPOL_CFLAGS@ @APOL_CFLAGS@ ++ ++AM_CXXFLAGS = @DEBUGCXXFLAGS@ @WARNCXXFLAGS@ @PROFILECFLAGS@ @SELINUX_CFLAGS@ \ ++ @QPOL_CFLAGS@ @APOL_CFLAGS@ @SEFS_CFLAGS@ ++ ++AM_LDFLAGS = @DEBUGLDFLAGS@ @WARNLDFLAGS@ @PROFILELDFLAGS@ ++LDADD = @SELINUX_LIB_FLAG@ @APOL_LIB_FLAG@ @QPOL_LIB_FLAG@ ++DEPENDENCIES = $(top_builddir)/libapol/src/libapol.so $(top_builddir)/libqpol/src/libqpol.so ++seinfo_SOURCES = seinfo.c ++sesearch_SOURCES = sesearch.c ++all: all-am ++ ++.SUFFIXES: ++$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) ++ @for dep in $?; do \ ++ case '$(am__configure_deps)' in \ ++ *$$dep*) \ ++ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ ++ && { if test -f $@; then exit 0; else break; fi; }; \ ++ exit 1;; \ ++ esac; \ ++ done; \ ++ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu python/setools/Makefile'; \ ++ $(am__cd) $(top_srcdir) && \ ++ $(AUTOMAKE) --gnu python/setools/Makefile ++.PRECIOUS: Makefile ++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status ++ @case '$?' in \ ++ *config.status*) \ ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ ++ *) \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ ++ esac; ++ ++$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++ ++$(top_srcdir)/configure: $(am__configure_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(ACLOCAL_M4): $(am__aclocal_m4_deps) ++ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ++$(am__aclocal_m4_deps): ++ ++mostlyclean-libtool: ++ -rm -f *.lo ++ ++clean-libtool: ++ -rm -rf .libs _libs ++tags: TAGS ++TAGS: ++ ++ctags: CTAGS ++CTAGS: ++ ++ ++distdir: $(DISTFILES) ++ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ ++ list='$(DISTFILES)'; \ ++ dist_files=`for file in $$list; do echo $$file; done | \ ++ sed -e "s|^$$srcdirstrip/||;t" \ ++ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ ++ case $$dist_files in \ ++ */*) $(MKDIR_P) `echo "$$dist_files" | \ ++ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ ++ sort -u` ;; \ ++ esac; \ ++ for file in $$dist_files; do \ ++ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ ++ if test -d $$d/$$file; then \ ++ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ ++ if test -d "$(distdir)/$$file"; then \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ ++ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ ++ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ ++ fi; \ ++ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ ++ else \ ++ test -f "$(distdir)/$$file" \ ++ || cp -p $$d/$$file "$(distdir)/$$file" \ ++ || exit 1; \ ++ fi; \ ++ done ++check-am: all-am ++check: check-am ++all-am: Makefile ++installdirs: ++install: install-am ++install-exec: install-exec-am ++install-data: install-data-am ++uninstall: uninstall-am ++ ++install-am: all-am ++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am ++ ++installcheck: installcheck-am ++install-strip: ++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ ++ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ ++ `test -z '$(STRIP)' || \ ++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install ++mostlyclean-generic: ++ ++clean-generic: ++ ++distclean-generic: ++ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) ++ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) ++ ++maintainer-clean-generic: ++ @echo "This command is intended for maintainers to use" ++ @echo "it deletes files that may require special tools to rebuild." ++clean: clean-am ++ ++clean-am: clean-generic clean-libtool clean-local mostlyclean-am ++ ++distclean: distclean-am ++ -rm -f Makefile ++distclean-am: clean-am distclean-generic ++ ++dvi: dvi-am ++ ++dvi-am: ++ ++html: html-am ++ ++html-am: ++ ++info: info-am ++ ++info-am: ++ ++install-data-am: ++ ++install-dvi: install-dvi-am ++ ++install-dvi-am: ++ ++install-exec-am: ++ @$(NORMAL_INSTALL) ++ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook ++install-html: install-html-am ++ ++install-html-am: ++ ++install-info: install-info-am ++ ++install-info-am: ++ ++install-man: ++ ++install-pdf: install-pdf-am ++ ++install-pdf-am: ++ ++install-ps: install-ps-am ++ ++install-ps-am: ++ ++installcheck-am: ++ ++maintainer-clean: maintainer-clean-am ++ -rm -f Makefile ++maintainer-clean-am: distclean-am maintainer-clean-generic ++ ++mostlyclean: mostlyclean-am ++ ++mostlyclean-am: mostlyclean-generic mostlyclean-libtool ++ ++pdf: pdf-am ++ ++pdf-am: ++ ++ps: ps-am ++ ++ps-am: ++ ++uninstall-am: ++ @$(NORMAL_INSTALL) ++ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook ++.MAKE: install-am install-exec-am install-strip uninstall-am ++ ++.PHONY: all all-am check check-am clean clean-generic clean-libtool \ ++ clean-local distclean distclean-generic distclean-libtool \ ++ distdir dvi dvi-am html html-am info info-am install \ ++ install-am install-data install-data-am install-dvi \ ++ install-dvi-am install-exec install-exec-am install-exec-hook \ ++ install-html install-html-am install-info install-info-am \ ++ install-man install-pdf install-pdf-am install-ps \ ++ install-ps-am install-strip installcheck installcheck-am \ ++ installdirs maintainer-clean maintainer-clean-generic \ ++ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ++ ps ps-am uninstall uninstall-am uninstall-hook ++ ++all-am: python-build ++ ++python-build: sesearch.c seinfo.c ++ @mkdir -p setools ++ @cp __init__.py setools ++ LIBS="$(QPOL_LIB_FLAG) $(APOL_LIB_FLAG)" INCLUDES="$(QPOL_CFLAGS) $(APOL_CFLAGS)" $(PYTHON) setup.py build ++ ++install-exec-hook: ++ $(PYTHON) setup.py install `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` ++ ++uninstall-hook: ++ $(PYTHON) setup.py uninstall `test -n "$(DESTDIR)" && echo --root $(DESTDIR)` ++ ++clean-local: ++ $(PYTHON) setup.py clean -a ++ rm -f *~ ++ ++# Tell versions [3.59,3.63) of GNU make to not export all variables. ++# Otherwise a system limit (for SysV at least) may be exceeded. ++.NOEXPORT: +diff --git a/python/setools/__init__.py b/python/setools/__init__.py +new file mode 100644 +index 0000000..6f075c4 +--- /dev/null ++++ b/python/setools/__init__.py +@@ -0,0 +1,50 @@ ++#!/usr/bin/env python ++ ++# Author: Thomas Liu ++ ++import _sesearch ++import _seinfo ++import types ++ ++TYPE = _seinfo.TYPE ++ROLE = _seinfo.ROLE ++ATTRIBUTE = _seinfo.ATTRIBUTE ++PORT = _seinfo.PORT ++USER = _seinfo.USER ++ ++ALLOW = 'allow' ++AUDITALLOW = 'auditallow' ++NEVERALLOW = 'neverallow' ++DONTAUDIT = 'dontaudit' ++SCONTEXT = 'scontext' ++TCONTEXT = 'tcontext' ++PERMS = 'permlist' ++CLASS = 'class' ++ ++def sesearch(types, info): ++ valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT] ++ for type in types: ++ if type not in valid_types: ++ raise ValueError("Type has to be in %s" % valid_types) ++ info[type] = True ++ ++ perms = [] ++ if PERMS in info: ++ perms = info[PERMS] ++ info[PERMS] = ",".join(info[PERMS]) ++ ++ ++ dict_list = _sesearch.sesearch(info) ++ if dict_list and len(perms) != 0: ++ dict_list = filter(lambda x: dict_has_perms(x, perms), dict_list) ++ return dict_list ++ ++def dict_has_perms(dict, perms): ++ for perm in perms: ++ if perm not in dict[PERMS]: ++ return False ++ return True ++ ++def seinfo(setype, name=None): ++ dict_list = _seinfo.seinfo(setype, name) ++ return dict_list +diff --git a/python/setools/seinfo.c b/python/setools/seinfo.c +new file mode 100644 +index 0000000..211930a +--- /dev/null ++++ b/python/setools/seinfo.c +@@ -0,0 +1,769 @@ ++/** ++ * @file ++ * Command line tool to search TE rules. ++ * ++ * @author Frank Mayer mayerf@tresys.com ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Paul Rosenfeld prosenfeld@tresys.com ++ * @author Thomas Liu ++ * @author Dan Walsh ++ * ++ * Copyright (C) 2003-2008 Tresys Technology, LLC ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * This is a modified version of seinfo to be used as part of a library for ++ * Python bindings. ++ */ ++ ++#include "Python.h" ++ ++/* libapol */ ++#include ++#include ++#include ++#include ++#include ++ ++/* libqpol */ ++#include ++#include ++ ++/* other */ ++#include ++#include ++#include ++#include ++#include ++ ++#define COPYRIGHT_INFO "Copyright (C) 2003-2007 Tresys Technology, LLC" ++static char *policy_file = NULL; ++ ++enum input ++{ ++ TYPE, ATTRIBUTE, ROLE, USER, PORT, ++}; ++ ++/** ++ * Gets a textual representation of an attribute, and ++ * all of that attribute's types. ++ * ++ * @param type_datum Reference to sepol type_datum ++ * @param policydb Reference to a policy ++ */ ++static PyObject* get_attr(const qpol_type_t * type_datum, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *dict = PyDict_New(); ++ const qpol_type_t *attr_datum = NULL; ++ qpol_iterator_t *iter = NULL; ++ const char *attr_name = NULL, *type_name = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ unsigned char isattr; ++ ++ if (qpol_type_get_name(q, type_datum, &attr_name)) ++ goto cleanup; ++ PyObject *obj = PyString_FromString(attr_name); ++ PyDict_SetItemString(dict, "name", obj); ++ Py_DECREF(obj); ++ ++ /* get an iterator over all types this attribute has */ ++ if (qpol_type_get_isattr(q, type_datum, &isattr)) ++ goto cleanup; ++ if (isattr) { /* sanity check */ ++ if (qpol_type_get_type_iter(q, type_datum, &iter)) ++ goto cleanup; ++ PyObject *list = PyList_New(0); ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&attr_datum)) ++ goto cleanup; ++ if (qpol_type_get_name(q, attr_datum, &type_name)) ++ goto cleanup; ++ PyObject *obj = PyString_FromString(type_name); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ qpol_iterator_destroy(&iter); ++ PyDict_SetItemString(dict, "types", list); ++ Py_DECREF(list); ++ } else /* this should never happen */ ++ goto cleanup; ++ ++ retval = 0; ++cleanup: ++ qpol_iterator_destroy(&iter); ++ if (retval) { ++ Py_DECREF(dict); ++ return NULL; ++ } ++ return dict; ++} ++ ++/** ++ * Gets statistics regarding a policy's attributes. ++ * If this function is given a name, it will attempt to ++ * get statistics about a particular attribute; otherwise ++ * the function gets statistics about all of the policy's ++ * attributes. ++ * ++ * @param name Reference to an attribute's name; if NULL, ++ * all object classes will be considered ++ * @param policydb Reference to a policy ++ * ++ * @return 0 on success, < 0 on error. ++ */ ++static PyObject* get_attribs(const char *name, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *list = PyList_New(0); ++ apol_attr_query_t *attr_query = NULL; ++ apol_vector_t *v = NULL; ++ const qpol_type_t *type_datum = NULL; ++ size_t n_attrs, i; ++ ++ /* we are only getting information about 1 attribute */ ++ if (name != NULL) { ++ attr_query = apol_attr_query_create(); ++ if (!attr_query) ++ goto cleanup; ++ if (apol_attr_query_set_attr(policydb, attr_query, name)) ++ goto cleanup; ++ if (apol_attr_get_by_query(policydb, attr_query, &v)) ++ goto cleanup; ++ apol_attr_query_destroy(&attr_query); ++ if (apol_vector_get_size(v) == 0) { ++ apol_vector_destroy(&v); ++ errno = EINVAL; ++ goto cleanup; ++ } ++ ++ type_datum = apol_vector_get_element(v, (size_t) 0); ++ PyObject *obj = get_attr(type_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } else { ++ attr_query = apol_attr_query_create(); ++ if (!attr_query) ++ goto cleanup; ++ if (apol_attr_get_by_query(policydb, attr_query, &v)) ++ goto cleanup; ++ apol_attr_query_destroy(&attr_query); ++ n_attrs = apol_vector_get_size(v); ++ ++ for (i = 0; i < n_attrs; i++) { ++ /* get qpol_type_t* item from vector */ ++ type_datum = (qpol_type_t *) apol_vector_get_element(v, (size_t) i); ++ if (!type_datum) ++ goto cleanup; ++ PyObject *obj = get_attr(type_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ } ++ apol_vector_destroy(&v); ++ ++ retval = 0; ++ cleanup: ++ apol_attr_query_destroy(&attr_query); ++ apol_vector_destroy(&v); ++ if (retval) { ++ Py_DECREF(list); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return list; ++} ++ ++/** ++ * Get a textual representation of a type, and ++ * all of that type's attributes. ++ * ++ * @param type_datum Reference to sepol type_datum ++ * @param policydb Reference to a policy ++ */ ++static PyObject* get_type_attrs(const qpol_type_t * type_datum, const apol_policy_t * policydb) ++{ ++ qpol_iterator_t *iter = NULL; ++ const char *attr_name = NULL; ++ const qpol_type_t *attr_datum = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ ++ if (qpol_type_get_attr_iter(q, type_datum, &iter)) ++ goto cleanup; ++ PyObject *list = PyList_New(0); ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&attr_datum)) ++ goto cleanup; ++ if (qpol_type_get_name(q, attr_datum, &attr_name)) ++ goto cleanup; ++ PyObject *obj = PyString_FromString(attr_name); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ ++ cleanup: ++ qpol_iterator_destroy(&iter); ++ return list; ++} ++ ++static PyObject* get_type( const qpol_type_t * type_datum, const apol_policy_t * policydb) { ++ ++ PyObject *dict = PyDict_New(); ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ const char *type_name = NULL; ++ ++ unsigned char isalias, ispermissive, isattr; ++ ++ if (qpol_type_get_name(q, type_datum, &type_name)) ++ goto cleanup; ++ if (qpol_type_get_isalias(q, type_datum, &isalias)) ++ goto cleanup; ++ if (qpol_type_get_isattr(q, type_datum, &isattr)) ++ goto cleanup; ++ if (qpol_type_get_ispermissive(q, type_datum, &ispermissive)) ++ goto cleanup; ++ ++ PyObject *obj = PyString_FromString(type_name); ++ PyDict_SetItemString(dict, "name", obj); ++ Py_DECREF(obj); ++ obj = PyBool_FromLong(ispermissive); ++ PyDict_SetItemString(dict, "permissive", obj); ++ Py_DECREF(obj); ++ if (!isattr && !isalias) { ++ obj = get_type_attrs(type_datum, policydb); ++ PyDict_SetItemString(dict, "attributes", obj); ++ Py_DECREF(obj); ++ } ++ return dict; ++cleanup: ++ Py_DECREF(dict); ++ return NULL; ++} ++ ++/** ++ * Gets a textual representation of a user, and ++ * all of that user's roles. ++ * ++ * @param type_datum Reference to sepol type_datum ++ * @param policydb Reference to a policy ++ * roles ++ */ ++static PyObject* get_user(const qpol_user_t * user_datum, const apol_policy_t * policydb) ++{ ++ PyObject *dict = NULL; ++ const qpol_role_t *role_datum = NULL; ++ qpol_iterator_t *iter = NULL; ++ const qpol_mls_range_t *range = NULL; ++ const qpol_mls_level_t *dflt_level = NULL; ++ apol_mls_level_t *ap_lvl = NULL; ++ apol_mls_range_t *ap_range = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ char *tmp; ++ const char *user_name, *role_name; ++ ++ if (qpol_user_get_name(q, user_datum, &user_name)) ++ goto cleanup; ++ ++ dict = PyDict_New(); ++ PyObject *obj = PyString_FromString(user_name); ++ PyDict_SetItemString(dict, "name", obj); ++ Py_DECREF(obj); ++ ++ if (qpol_policy_has_capability(q, QPOL_CAP_MLS)) { ++ if (qpol_user_get_dfltlevel(q, user_datum, &dflt_level)) ++ goto cleanup; ++ ap_lvl = apol_mls_level_create_from_qpol_mls_level(policydb, dflt_level); ++ tmp = apol_mls_level_render(policydb, ap_lvl); ++ if (!tmp) ++ goto cleanup; ++ obj = PyString_FromString(tmp); ++ PyDict_SetItemString(dict, "level", obj); ++ Py_DECREF(obj); ++ free(tmp); ++ /* print default range */ ++ if (qpol_user_get_range(q, user_datum, &range)) ++ goto cleanup; ++ ap_range = apol_mls_range_create_from_qpol_mls_range(policydb, range); ++ tmp = apol_mls_range_render(policydb, ap_range); ++ if (!tmp) ++ goto cleanup; ++ obj = PyString_FromString(tmp); ++ PyDict_SetItemString(dict, "range", obj); ++ Py_DECREF(obj); ++ free(tmp); ++ } ++ ++ if (qpol_user_get_role_iter(q, user_datum, &iter)) ++ goto cleanup; ++ PyObject *list = PyList_New(0); ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&role_datum)) { ++ Py_DECREF(list); ++ goto cleanup; ++ } ++ if (qpol_role_get_name(q, role_datum, &role_name)) { ++ Py_DECREF(list); ++ goto cleanup; ++ } ++ PyObject *obj = PyString_FromString(role_name); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ PyDict_SetItemString(dict, "roles", list); ++ Py_DECREF(list); ++ ++cleanup: ++ qpol_iterator_destroy(&iter); ++ apol_mls_level_destroy(&ap_lvl); ++ apol_mls_range_destroy(&ap_range); ++ return dict; ++} ++ ++/** ++ * Gets statistics regarding a policy's users. ++ * If this function is given a name, it will attempt to ++ * get statistics about a particular user; otherwise ++ * the function gets statistics about all of the policy's ++ * users. ++ * ++ * @param name Reference to a user's name; if NULL, ++ * all users will be considered ++ * @param policydb Reference to a policy ++ * ++ * @return 0 on success, < 0 on error. ++ */ ++static PyObject* get_users(const char *name, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *list = PyList_New(0); ++ qpol_iterator_t *iter = NULL; ++ const qpol_user_t *user_datum = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ ++ if (name != NULL) { ++ if (qpol_policy_get_user_by_name(q, name, &user_datum)) { ++ errno = EINVAL; ++ goto cleanup; ++ } ++ PyObject *obj = get_user(user_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } else { ++ if (qpol_policy_get_user_iter(q, &iter)) ++ goto cleanup; ++ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&user_datum)) ++ goto cleanup; ++ PyObject *obj = get_user(user_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ qpol_iterator_destroy(&iter); ++ } ++ ++ retval = 0; ++ cleanup: ++ qpol_iterator_destroy(&iter); ++ if (retval) { ++ Py_DECREF(list); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return list; ++} ++ ++/** ++ * get a textual representation of a role, and ++ * all of that role's types. ++ * ++ * @param type_datum Reference to sepol type_datum ++ * @param policydb Reference to a policy ++ * types ++ */ ++static PyObject* get_role(const qpol_role_t * role_datum, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *dict = PyDict_New(); ++ const char *role_name = NULL, *type_name = NULL; ++ const qpol_role_t *dom_datum = NULL; ++ const qpol_type_t *type_datum = NULL; ++ qpol_iterator_t *iter = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ size_t n_dom = 0, n_types = 0; ++ ++ if (qpol_role_get_name(q, role_datum, &role_name)) ++ goto cleanup; ++ ++ PyObject *obj = PyString_FromString(role_name); ++ PyDict_SetItemString(dict, "name", obj); ++ Py_DECREF(obj); ++ ++ if (qpol_role_get_dominate_iter(q, role_datum, &iter)) ++ goto cleanup; ++ if (qpol_iterator_get_size(iter, &n_dom)) ++ goto cleanup; ++ if ((int)n_dom > 0) { ++ PyObject *list = PyList_New(0); ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&dom_datum)) ++ goto cleanup; ++ if (qpol_role_get_name(q, dom_datum, &role_name)) ++ goto cleanup; ++ PyObject *obj = PyString_FromString(role_name); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ PyDict_SetItemString(dict, "dominate", list); ++ Py_DECREF(list); ++ } ++ qpol_iterator_destroy(&iter); ++ ++ if (qpol_role_get_type_iter(q, role_datum, &iter)) ++ goto cleanup; ++ if (qpol_iterator_get_size(iter, &n_types)) ++ goto cleanup; ++ if ((int)n_types > 0) { ++ PyObject *list = PyList_New(0); ++ /* print types */ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&type_datum)) ++ goto cleanup; ++ if (qpol_type_get_name(q, type_datum, &type_name)) ++ goto cleanup; ++ PyObject *obj = PyString_FromString(type_name); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ PyDict_SetItemString(dict, "types", list); ++ Py_DECREF(list); ++ } ++ ++ retval = 0; ++cleanup: ++ qpol_iterator_destroy(&iter); ++ if (retval) { ++ Py_DECREF(dict); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return dict; ++} ++ ++/** ++ * Get statistics regarding a policy's ports. ++ * If this function is given a name, it will attempt to ++ * get statistics about a particular port; otherwise ++ * the function get statistics about all of the policy's ports. ++ * ++ * @param name Reference to an port's name; if NULL, ++ * all ports will be considered ++ * @param policydb Reference to a policy ++ * ++ * @return 0 on success, < 0 on error. ++ */ ++static PyObject* get_ports(const char *num, const apol_policy_t * policydb) ++{ ++ PyObject *list = PyList_New(0); ++ int retval = -1; ++ const qpol_portcon_t *portcon = NULL; ++ qpol_iterator_t *iter = NULL; ++ uint16_t low_port, high_port; ++ uint8_t ocon_proto; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ const qpol_context_t *ctxt = NULL; ++ const char *proto_str; ++ PyObject *dict; ++ const char *type = NULL; ++ const apol_mls_range_t *range = NULL; ++ char *range_str = NULL; ++ PyObject *obj = NULL; ++ apol_context_t *c = NULL; ++ ++ if (qpol_policy_get_portcon_iter(q, &iter)) ++ goto cleanup; ++ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&portcon)) ++ goto cleanup; ++ if (qpol_portcon_get_low_port(q, portcon, &low_port)) ++ goto cleanup; ++ if (qpol_portcon_get_high_port(q, portcon, &high_port)) ++ goto cleanup; ++ if (qpol_portcon_get_protocol(q, portcon, &ocon_proto)) ++ goto cleanup; ++ if (num) { ++ if (atoi(num) < low_port || atoi(num) > high_port) ++ continue; ++ } ++ ++ if ((ocon_proto != IPPROTO_TCP) && ++ (ocon_proto != IPPROTO_UDP)) ++ goto cleanup; ++ ++ if (qpol_portcon_get_context(q, portcon, &ctxt)) { ++ PyErr_SetString(PyExc_RuntimeError, "Could not get for port context."); ++ goto cleanup; ++ } ++ ++ if ((proto_str = apol_protocol_to_str(ocon_proto)) == NULL) { ++ PyErr_SetString(PyExc_RuntimeError, "Invalid protocol for port"); ++ goto cleanup; ++ } ++ ++ if ((c = apol_context_create_from_qpol_context(policydb, ctxt)) == NULL) { ++ goto cleanup; ++ } ++ ++ if((type = apol_context_get_type(c)) == NULL) { ++ apol_context_destroy(&c); ++ goto cleanup; ++ } ++ ++ dict = PyDict_New(); ++ obj = PyString_FromString(type); ++ PyDict_SetItemString(dict, "type", obj); ++ Py_DECREF(obj); ++ ++ if((range = apol_context_get_range(c)) == NULL) { ++ goto cleanup; ++ } ++ ++ range_str = apol_mls_range_render(policydb, range); ++ if (range_str == NULL) { ++ goto cleanup; ++ } ++ obj = PyString_FromString(range_str); ++ PyDict_SetItemString(dict, "range", obj); ++ Py_DECREF(obj); ++ ++ obj = PyString_FromString(proto_str); ++ PyDict_SetItemString(dict, "protocol", obj); ++ Py_DECREF(obj); ++ ++ obj = PyInt_FromLong(high_port); ++ PyDict_SetItemString(dict, "high", obj); ++ Py_DECREF(obj); ++ ++ obj = PyInt_FromLong(low_port); ++ PyDict_SetItemString(dict, "low", obj); ++ Py_DECREF(obj); ++ ++ PyList_Append(list, dict); ++ Py_DECREF(dict); ++ } ++ retval = 0; ++ cleanup: ++ free(range_str); ++ apol_context_destroy(&c); ++ qpol_iterator_destroy(&iter); ++ ++ if (retval) { ++ Py_DECREF(list); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return list; ++} ++ ++/** ++ * Get statistics regarding a policy's roles. ++ * If this function is given a name, it will attempt to ++ * get statistics about a particular role; otherwise ++ * the function get statistics about all of the policy's roles. ++ * ++ * @param name Reference to an role's name; if NULL, ++ * all roles will be considered ++ * @param policydb Reference to a policy ++ * ++ * @return 0 on success, < 0 on error. ++ */ ++static PyObject* get_roles(const char *name, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *list = PyList_New(0); ++ const qpol_role_t *role_datum = NULL; ++ qpol_iterator_t *iter = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ ++ if (name != NULL) { ++ if (qpol_policy_get_role_by_name(q, name, &role_datum)) { ++ errno = EINVAL; ++ goto cleanup; ++ } ++ PyObject *obj = get_role(role_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } else { ++ if (qpol_policy_get_role_iter(q, &iter)) ++ goto cleanup; ++ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&role_datum)) ++ goto cleanup; ++ PyObject *obj = get_role(role_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ qpol_iterator_destroy(&iter); ++ } ++ ++ retval = 0; ++ cleanup: ++ qpol_iterator_destroy(&iter); ++ if (retval) { ++ Py_DECREF(list); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return list; ++} ++ ++/** ++ * Get statistics regarding a policy's types. ++ * If this function is given a name, it will attempt to ++ * print statistics about a particular type; otherwise ++ * the function prints statistics about all of the policy's types. ++ * ++ * @param name Reference to a type's name; if NULL, ++ * all object classes will be considered ++ * @param policydb Reference to a policy ++ * ++ * @return 0 on success, < 0 on error. ++ */ ++static PyObject* get_types(const char *name, const apol_policy_t * policydb) ++{ ++ int retval = -1; ++ PyObject *list = PyList_New(0); ++ const qpol_type_t *type_datum = NULL; ++ qpol_iterator_t *iter = NULL; ++ qpol_policy_t *q = apol_policy_get_qpol(policydb); ++ ++ /* if name was provided, only print that name */ ++ if (name != NULL) { ++ if (qpol_policy_get_type_by_name(q, name, &type_datum)) { ++ errno = EINVAL; ++ goto cleanup; ++ } ++ PyObject *obj = get_type(type_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } else { ++ if (qpol_policy_get_type_iter(q, &iter)) ++ goto cleanup; ++ /* Print all type names */ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ if (qpol_iterator_get_item(iter, (void **)&type_datum)) ++ goto cleanup; ++ PyObject *obj = get_type(type_datum, policydb); ++ PyList_Append(list, obj); ++ Py_DECREF(obj); ++ } ++ } ++ retval = 0; ++cleanup: ++ qpol_iterator_destroy(&iter); ++ if (retval) { ++ Py_DECREF(list); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ return list; ++} ++ ++PyObject* seinfo(int type, const char *name) ++{ ++ int rt = -1; ++ ++ apol_policy_t *policydb = NULL; ++ apol_policy_path_t *pol_path = NULL; ++ apol_vector_t *mod_paths = NULL; ++ apol_policy_path_type_e path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC; ++ PyObject* output = NULL; ++ ++ rt = qpol_default_policy_find(&policy_file); ++ if (rt != 0) { ++ PyErr_SetString(PyExc_RuntimeError,"No default policy found."); ++ return NULL; ++ } ++ ++ pol_path = apol_policy_path_create(path_type, policy_file, mod_paths); ++ if (!pol_path) { ++ free(policy_file); ++ apol_vector_destroy(&mod_paths); ++ PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); ++ return NULL; ++ } ++ apol_vector_destroy(&mod_paths); ++ ++ int policy_load_options = 0; ++ policy_load_options |= QPOL_POLICY_OPTION_MATCH_SYSTEM; ++ policydb = apol_policy_create_from_policy_path(pol_path, policy_load_options, NULL, NULL); ++ if (!policydb) { ++ free(policy_file); ++ apol_policy_path_destroy(&pol_path); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ free(policy_file); ++ ++ /* display requested info */ ++ if (type == TYPE) ++ output = get_types(name, policydb); ++ ++ if (type == ATTRIBUTE) ++ output = get_attribs(name, policydb); ++ ++ if (type == ROLE) ++ output = get_roles(name, policydb); ++ ++ if (type == USER) ++ output = get_users(name, policydb); ++ ++ if (type == PORT) ++ output = get_ports(name, policydb); ++ ++ apol_policy_destroy(&policydb); ++ apol_policy_path_destroy(&pol_path); ++ return output; ++} ++ ++PyObject *wrap_seinfo(PyObject *self, PyObject *args){ ++ unsigned int type; ++ char *name; ++ ++ if (!PyArg_ParseTuple(args, "iz", &type, &name)) ++ return NULL; ++ ++ return Py_BuildValue("O",seinfo(type, name)); ++ ++} ++ ++static PyMethodDef methods[] = { ++ {"seinfo", (PyCFunction) wrap_seinfo, METH_VARARGS}, ++ {NULL, NULL, 0, NULL} ++}; ++ ++void init_seinfo(){ ++ PyObject *m; ++ m = Py_InitModule("_seinfo", methods); ++ PyModule_AddIntConstant(m, "ATTRIBUTE", ATTRIBUTE); ++ PyModule_AddIntConstant(m, "PORT", PORT); ++ PyModule_AddIntConstant(m, "ROLE", ROLE); ++ PyModule_AddIntConstant(m, "TYPE", TYPE); ++ PyModule_AddIntConstant(m, "USER", USER); ++} +diff --git a/python/setools/sesearch.c b/python/setools/sesearch.c +new file mode 100644 +index 0000000..faaf8b7 +--- /dev/null ++++ b/python/setools/sesearch.c +@@ -0,0 +1,478 @@ ++// Author: Thomas Liu ++ ++/** ++ * @file ++ * Command line tool to search TE rules. ++ * ++ * @author Frank Mayer mayerf@tresys.com ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Paul Rosenfeld prosenfeld@tresys.com ++ * @author Thomas Liu ++ * ++ * Copyright (C) 2003-2008 Tresys Technology, LLC ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * This is a modified version of sesearch to be used as part of a library for ++ * Python bindings. ++ */ ++ ++#include "Python.h" ++ ++/* libapol */ ++#include ++#include ++#include ++#include ++#include ++ ++/* libqpol*/ ++#include ++#include ++#include ++#include ++ ++/* other */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define COPYRIGHT_INFO "Copyright (C) 2003-2007 Tresys Technology, LLC" ++static char *policy_file = NULL; ++ ++enum opt_values ++{ ++ RULE_NEVERALLOW = 256, RULE_AUDIT, RULE_AUDITALLOW, RULE_DONTAUDIT, ++ RULE_ROLE_ALLOW, RULE_ROLE_TRANS, RULE_RANGE_TRANS, RULE_ALL, ++ EXPR_ROLE_SOURCE, EXPR_ROLE_TARGET ++}; ++ ++; ++ ++typedef struct options ++{ ++ char *src_name; ++ char *tgt_name; ++ char *src_role_name; ++ char *tgt_role_name; ++ char *class_name; ++ char *permlist; ++ char *bool_name; ++ apol_vector_t *class_vector; ++ bool all; ++ bool lineno; ++ bool semantic; ++ bool indirect; ++ bool allow; ++ bool nallow; ++ bool auditallow; ++ bool dontaudit; ++ bool type; ++ bool rtrans; ++ bool role_allow; ++ bool role_trans; ++ bool useregex; ++ bool show_cond; ++ apol_vector_t *perm_vector; ++} options_t; ++ ++static int perform_av_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) ++{ ++ apol_avrule_query_t *avq = NULL; ++ unsigned int rules = 0; ++ int error = 0; ++ char *tmp = NULL, *tok = NULL, *s = NULL; ++ ++ if (!policy || !opt || !v) { ++ PyErr_SetString(PyExc_RuntimeError,strerror(EINVAL)); ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if (!opt->all && !opt->allow && !opt->nallow && !opt->auditallow && !opt->dontaudit) { ++ *v = NULL; ++ return 0; /* no search to do */ ++ } ++ ++ avq = apol_avrule_query_create(); ++ if (!avq) { ++ PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ if (opt->allow || opt->all) ++ rules |= QPOL_RULE_ALLOW; ++ if ((opt->nallow || opt->all) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_NEVERALLOW)) ++ rules |= QPOL_RULE_NEVERALLOW; ++ if (opt->auditallow || opt->all) ++ rules |= QPOL_RULE_AUDITALLOW; ++ if (opt->dontaudit || opt->all) ++ rules |= QPOL_RULE_DONTAUDIT; ++ apol_avrule_query_set_rules(policy, avq, rules); ++ apol_avrule_query_set_regex(policy, avq, opt->useregex); ++ if (opt->src_name) ++ apol_avrule_query_set_source(policy, avq, opt->src_name, opt->indirect); ++ if (opt->tgt_name) ++ apol_avrule_query_set_target(policy, avq, opt->tgt_name, opt->indirect); ++ if (opt->bool_name) ++ apol_avrule_query_set_bool(policy, avq, opt->bool_name); ++ if (opt->class_name) { ++ if (opt->class_vector == NULL) { ++ if (apol_avrule_query_append_class(policy, avq, opt->class_name)) { ++ error = errno; ++ goto err; ++ } ++ } else { ++ size_t i; ++ for (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_avrule_query_append_class(policy, avq, class_name)) { ++ error = errno; ++ goto err; ++ } ++ } ++ } ++ } ++ ++ if (opt->permlist) { ++ tmp = strdup(opt->permlist); ++ for (tok = strtok(tmp, ","); tok; tok = strtok(NULL, ",")) { ++ if (apol_avrule_query_append_perm(policy, avq, tok)) { ++ error = errno; ++ goto err; ++ } ++ if ((s = strdup(tok)) == NULL || apol_vector_append(opt->perm_vector, s) < 0) { ++ error = errno; ++ goto err; ++ } ++ s = NULL; ++ } ++ free(tmp); ++ } ++ ++ if (!(opt->semantic) && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { ++ if (apol_syn_avrule_get_by_query(policy, avq, v)) { ++ error = errno; ++ goto err; ++ } ++ } else { ++ if (apol_avrule_get_by_query(policy, avq, v)) { ++ error = errno; ++ goto err; ++ } ++ } ++ ++ apol_avrule_query_destroy(&avq); ++ return 0; ++ ++ err: ++ apol_vector_destroy(v); ++ apol_avrule_query_destroy(&avq); ++ free(tmp); ++ free(s); ++ PyErr_SetString(PyExc_RuntimeError,strerror(error)); ++ errno = error; ++ return -1; ++} ++ ++ ++ ++static PyObject* get_av_results(const apol_policy_t * policy, const options_t * opt, const apol_vector_t * v) ++{ ++ int retval = -1; ++ PyObject *list = PyList_New(0); ++ qpol_policy_t *q = apol_policy_get_qpol(policy); ++ size_t i, num_rules = 0; ++ const qpol_avrule_t *rule = NULL; ++ char *tmp = NULL, *rule_str = NULL, *expr = NULL; ++ char enable_char = ' ', branch_char = ' '; ++ qpol_iterator_t *iter = NULL; ++ uint32_t enabled = 0; ++ ++ if (!policy || !v) ++ return NULL; ++ ++ if (!(num_rules = apol_vector_get_size(v))) ++ return NULL; ++ ++ for (i = 0; i < num_rules; i++) { ++ enable_char = branch_char = ' '; ++ if (!(rule = apol_vector_get_element(v, i))) ++ goto cleanup; ++ ++ if (qpol_avrule_get_is_enabled(q, rule, &enabled)) ++ goto cleanup; ++ if (!enabled) ++ continue; ++ ++ const qpol_type_t *type; ++ const char *tmp_name; ++ uint32_t rule_type = 0; ++ ++ const qpol_class_t *obj_class = NULL; ++ ++ PyObject *dict = PyDict_New(); ++ ++ qpol_avrule_get_rule_type(q, rule, &rule_type); ++ tmp_name = apol_rule_type_to_str(rule_type); ++ PyObject *obj = PyString_FromString(tmp_name); ++ PyDict_SetItemString(dict, "type", obj); ++ Py_DECREF(obj); ++ // source ++ qpol_avrule_get_source_type(q, rule, &type); ++ qpol_type_get_name(q, type, &tmp_name); ++ obj = PyString_FromString(tmp_name); ++ PyDict_SetItemString(dict, "scontext", obj); ++ Py_DECREF(obj); ++ ++ qpol_avrule_get_target_type(q, rule, &type); ++ qpol_type_get_name(q, type, &tmp_name); ++ obj = PyString_FromString(tmp_name); ++ PyDict_SetItemString(dict, "tcontext", obj); ++ Py_DECREF(obj); ++ ++ qpol_avrule_get_object_class(q, rule, &obj_class); ++ qpol_type_get_name(q, type, &tmp_name); ++ obj = PyString_FromString(tmp_name); ++ PyDict_SetItemString(dict, "class", obj); ++ Py_DECREF(obj); ++ qpol_avrule_get_perm_iter(q, rule, &iter); ++ PyObject *permlist = PyList_New(0); ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ const char *perm_name = NULL; ++ qpol_iterator_get_item(iter, (void **)&perm_name); ++ obj = PyString_FromString(perm_name); ++ PyList_Append(permlist, obj); ++ Py_DECREF(obj); ++ } ++ PyDict_SetItemString(dict, "permlist", permlist); ++ Py_DECREF(permlist); ++ PyList_Append(list, dict); ++ Py_DECREF(dict); ++ ++ free(rule_str); ++ rule_str = NULL; ++ free(expr); ++ expr = NULL; ++ } ++ retval = 0; ++ cleanup: ++ free(tmp); ++ free(rule_str); ++ free(expr); ++ if (retval) { ++ Py_DECREF(list); ++ return NULL; ++ } ++ return list; ++} ++ ++ ++PyObject* sesearch(bool allow, ++ bool neverallow, ++ bool auditallow, ++ bool dontaudit, ++ const char *src_name, ++ const char *tgt_name, ++ const char *class_name, ++ const char *permlist ++ ) ++{ ++ options_t cmd_opts; ++ int rt = -1; ++ PyObject *output = NULL; ++ ++ apol_policy_t *policy = NULL; ++ apol_vector_t *v = NULL; ++ apol_policy_path_t *pol_path = NULL; ++ apol_vector_t *mod_paths = NULL; ++ apol_policy_path_type_e path_type = APOL_POLICY_PATH_TYPE_MONOLITHIC; ++ ++ memset(&cmd_opts, 0, sizeof(cmd_opts)); ++ cmd_opts.indirect = true; ++ cmd_opts.allow = allow; ++ cmd_opts.nallow = neverallow; ++ cmd_opts.auditallow = auditallow; ++ cmd_opts.dontaudit = dontaudit; ++ if (src_name) ++ cmd_opts.src_name = strdup(src_name); ++ if (tgt_name) ++ cmd_opts.tgt_name = strdup(tgt_name); ++ if (class_name) ++ cmd_opts.class_name = strdup(class_name); ++ if (permlist){ ++ cmd_opts.perm_vector = apol_vector_create(free); ++ cmd_opts.permlist = strdup(permlist); ++ } ++ int pol_opt = 0; ++ if (!(cmd_opts.nallow || cmd_opts.all)) ++ pol_opt |= QPOL_POLICY_OPTION_NO_NEVERALLOWS; ++ ++ ++ rt = qpol_default_policy_find(&policy_file); ++ if (rt) { ++ PyErr_SetString(PyExc_RuntimeError,"No default policy found."); ++ return NULL; ++ } ++ pol_opt |= QPOL_POLICY_OPTION_MATCH_SYSTEM; ++ ++ if (apol_file_is_policy_path_list(policy_file) > 0) { ++ pol_path = apol_policy_path_create_from_file(policy_file); ++ if (!pol_path) { ++ free(policy_file); ++ PyErr_SetString(PyExc_RuntimeError,"invalid policy list"); ++ return NULL; ++ } ++ } ++ ++ if (!pol_path) ++ pol_path = apol_policy_path_create(path_type, policy_file, mod_paths); ++ if (!pol_path) { ++ free(policy_file); ++ PyErr_SetString(PyExc_RuntimeError,strerror(ENOMEM)); ++ return NULL; ++ } ++ free(policy_file); ++ apol_vector_destroy(&mod_paths); ++ ++ policy = apol_policy_create_from_policy_path(pol_path, pol_opt, NULL, NULL); ++ if (!policy) { ++ apol_policy_path_destroy(&pol_path); ++ PyErr_SetString(PyExc_RuntimeError,strerror(errno)); ++ return NULL; ++ } ++ /* handle regex for class name */ ++ if (cmd_opts.useregex && cmd_opts.class_name != NULL) { ++ cmd_opts.class_vector = apol_vector_create(NULL); ++ apol_vector_t *qpol_matching_classes = NULL; ++ apol_class_query_t *regex_match_query = apol_class_query_create(); ++ apol_class_query_set_regex(policy, regex_match_query, 1); ++ apol_class_query_set_class(policy, regex_match_query, cmd_opts.class_name); ++ if (apol_class_get_by_query(policy, regex_match_query, &qpol_matching_classes)) { ++ apol_class_query_destroy(®ex_match_query); ++ PyErr_SetString(PyExc_RuntimeError,"Query failed"); ++ goto cleanup; ++ } ++ const qpol_class_t *class = NULL; ++ size_t i; ++ for (i = 0; i < apol_vector_get_size(qpol_matching_classes); ++i) { ++ const char *class_name; ++ class = apol_vector_get_element(qpol_matching_classes, i); ++ if (!class) ++ break; ++ qpol_class_get_name(apol_policy_get_qpol(policy), class, &class_name); ++ apol_vector_append(cmd_opts.class_vector, (void *)class_name); ++ } ++ if (!apol_vector_get_size(qpol_matching_classes)) { ++ apol_vector_destroy(&qpol_matching_classes); ++ apol_class_query_destroy(®ex_match_query); ++ PyErr_SetString(PyExc_RuntimeError,"No classes match expression"); ++ goto cleanup; ++ } ++ apol_vector_destroy(&qpol_matching_classes); ++ apol_class_query_destroy(®ex_match_query); ++ } ++ ++ if (!cmd_opts.semantic && qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { ++ if (qpol_policy_build_syn_rule_table(apol_policy_get_qpol(policy))) { ++ apol_policy_destroy(&policy); ++ PyErr_SetString(PyExc_RuntimeError,"Query failed"); ++ goto cleanup; ++ } ++ } ++ ++ /* if syntactic rules are not available always do semantic search */ ++ if (!qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_SYN_RULES)) { ++ cmd_opts.semantic = 1; ++ } ++ ++ /* supress line numbers if doing semantic search or not available */ ++ if (cmd_opts.semantic || !qpol_policy_has_capability(apol_policy_get_qpol(policy), QPOL_CAP_LINE_NUMBERS)) { ++ cmd_opts.lineno = 0; ++ } ++ if (perform_av_query(policy, &cmd_opts, &v)) { ++ goto cleanup; ++ } ++ if (v) { ++ output = get_av_results(policy, &cmd_opts, v); ++ } ++ apol_vector_destroy(&v); ++ cleanup: ++ apol_policy_destroy(&policy); ++ apol_policy_path_destroy(&pol_path); ++ free(cmd_opts.src_name); ++ free(cmd_opts.tgt_name); ++ free(cmd_opts.class_name); ++ free(cmd_opts.permlist); ++ free(cmd_opts.bool_name); ++ free(cmd_opts.src_role_name); ++ free(cmd_opts.tgt_role_name); ++ apol_vector_destroy(&cmd_opts.perm_vector); ++ apol_vector_destroy(&cmd_opts.class_vector); ++ ++ if (output) return output; ++ return Py_None; ++} ++static int Dict_ContainsInt(PyObject *dict, const char *key){ ++ PyObject *item = PyDict_GetItemString(dict, key); ++ if (item) ++ return PyInt_AsLong(item); ++ return false; ++} ++ ++static const char *Dict_ContainsString(PyObject *dict, const char *key){ ++ PyObject *item = PyDict_GetItemString(dict, key); ++ if (item) ++ return PyString_AsString(item); ++ return NULL; ++} ++ ++PyObject *wrap_sesearch(PyObject *self, PyObject *args){ ++ PyObject *dict; ++ if (!PyArg_ParseTuple(args, "O", &dict)) ++ return NULL; ++ int allow = Dict_ContainsInt(dict, "allow"); ++ int neverallow = Dict_ContainsInt(dict, "neverallow"); ++ int auditallow = Dict_ContainsInt(dict, "auditallow"); ++ int dontaudit = Dict_ContainsInt(dict, "dontaudit"); ++ ++ const char *src_name = Dict_ContainsString(dict, "scontext"); ++ const char *tgt_name = Dict_ContainsString(dict, "tcontext"); ++ const char *class_name = Dict_ContainsString(dict, "class"); ++ const char *permlist = Dict_ContainsString(dict, "permlist"); ++ ++ return Py_BuildValue("O",sesearch(allow, neverallow, auditallow, dontaudit, src_name, tgt_name, class_name, permlist)); ++ ++} ++ ++static PyMethodDef methods[] = { ++ {"sesearch", (PyCFunction) wrap_sesearch, METH_VARARGS}, ++ {NULL, NULL, 0, NULL} ++}; ++ ++void init_sesearch(){ ++ PyObject *m; ++ m = Py_InitModule("_sesearch", methods); ++} +diff --git a/python/setools/setup.py b/python/setools/setup.py +new file mode 100644 +index 0000000..053b885 +--- /dev/null ++++ b/python/setools/setup.py +@@ -0,0 +1,25 @@ ++#!/usr/bin/env python ++ ++# Author: Thomas Liu ++import os ++from distutils.core import setup, Extension ++LIBS=["apol", "qpol"] ++ ++try: ++ inc=os.getenv("INCLUDES").split(" ") ++ INCLUDES=map(lambda x: x[2:], inc) ++ LIBDIRS=map(lambda x: "/".join(x.split("/")[:-1]), os.getenv("LIBS").split()) ++except: ++ INCLUDES="" ++ LIBDIRS="" ++ ++extension_sesearch = Extension("setools._sesearch", [ "sesearch.c"]) ++extension_sesearch.include_dirs=INCLUDES ++extension_sesearch.libraries=LIBS ++extension_sesearch.library_dirs=LIBDIRS ++extension_seinfo = Extension("setools._seinfo", [ "seinfo.c"]) ++extension_seinfo.include_dirs=INCLUDES ++extension_seinfo.libraries=LIBS ++extension_seinfo.library_dirs=LIBDIRS ++ ++setup(name = "setools", version="1.0", description="Python setools bindings", author="Thomas Liu", author_email="tliu@redhat.com", ext_modules=[extension_sesearch, extension_seinfo], packages=["setools"]) +-- +1.7.6.2 + diff --git a/0002-setools-should-exit-with-an-error-status-if-it-gets-.patch b/0002-setools-should-exit-with-an-error-status-if-it-gets-.patch new file mode 100644 index 0000000..62a8050 --- /dev/null +++ b/0002-setools-should-exit-with-an-error-status-if-it-gets-.patch @@ -0,0 +1,133 @@ +From 667fe9187c203ffcba855e821dff11c8f71ef000 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:39:51 -0400 +Subject: [PATCH 2/6] setools-should-exit-with-an-error-status-if-it-gets-an + error + +--- + secmds/seinfo.c | 51 +++++++++++++++++++++++++++------------------------ + 1 files changed, 27 insertions(+), 24 deletions(-) + +diff --git a/secmds/seinfo.c b/secmds/seinfo.c +index fdf23e9..3088f88 100644 +--- a/secmds/seinfo.c ++++ b/secmds/seinfo.c +@@ -827,7 +827,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; +@@ -911,9 +911,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 +950,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 +967,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 +1648,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 +1854,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); + } + + /** +-- +1.7.6.2 + diff --git a/0003-Since-we-do-not-ship-neverallow-rules-all-always-fai.patch b/0003-Since-we-do-not-ship-neverallow-rules-all-always-fai.patch new file mode 100644 index 0000000..ae30696 --- /dev/null +++ b/0003-Since-we-do-not-ship-neverallow-rules-all-always-fai.patch @@ -0,0 +1,28 @@ +From 252b7c8bf311d615164a20f4f402767e5859d972 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:40:28 -0400 +Subject: [PATCH 3/6] Since-we-do-not-ship-neverallow-rules-all-always-fail + +--- + libqpol/src/avrule_query.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/libqpol/src/avrule_query.c b/libqpol/src/avrule_query.c +index 749565b..76dcaa3 100644 +--- a/libqpol/src/avrule_query.c ++++ b/libqpol/src/avrule_query.c +@@ -57,8 +57,9 @@ int qpol_policy_get_avrule_iter(const qpol_policy_t * policy, uint32_t rule_type + + if ((rule_type_mask & QPOL_RULE_NEVERALLOW) && !qpol_policy_has_capability(policy, QPOL_CAP_NEVERALLOW)) { + ERR(policy, "%s", "Cannot get avrules: Neverallow rules requested but not available"); +- errno = ENOTSUP; +- return STATUS_ERR; ++/* errno = ENOTSUP; ++ return STATUS_ERR; */ ++ return STATUS_SUCCESS; + } + + db = &policy->p->p; +-- +1.7.6.2 + diff --git a/0004-Fix-man-pages-and-getoptions.patch b/0004-Fix-man-pages-and-getoptions.patch new file mode 100644 index 0000000..c06270e --- /dev/null +++ b/0004-Fix-man-pages-and-getoptions.patch @@ -0,0 +1,78 @@ +From b3c8ef5822dbf3e3272fc29627ddac7e20e936d5 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:41:12 -0400 +Subject: [PATCH 4/6] Fix-man-pages-and-getoptions + +--- + man/replcon.1 | 2 ++ + man/seinfo.1 | 6 +++++- + seaudit/seaudit-report.c | 2 +- + sediff/sediff.c | 2 +- + 4 files changed, 9 insertions(+), 3 deletions(-) + +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/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/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; +-- +1.7.6.2 + diff --git a/0005-Fix-sepol-calls-to-work-with-latest-libsepol.patch b/0005-Fix-sepol-calls-to-work-with-latest-libsepol.patch new file mode 100644 index 0000000..01f545d --- /dev/null +++ b/0005-Fix-sepol-calls-to-work-with-latest-libsepol.patch @@ -0,0 +1,34 @@ +From 2b58d92add64b53b16cbb438e7b69e85d046afd1 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:46:38 -0400 +Subject: [PATCH 5/6] Fix sepol calls to work with latest libsepol + +--- + configure.ac | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index e837e03..3c11e23 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -505,7 +505,7 @@ AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ + #include + int main () { +- return role_set_expand(NULL, NULL, NULL, NULL); ++ return role_set_expand(NULL, NULL, NULL, NULL, NULL); + }])], + sepol_new_user_role_mapping="yes", + sepol_new_user_role_mapping="no") +@@ -541,7 +541,7 @@ if test ${sepol_check_boolmap} = "yes"; then + [AC_LANG_SOURCE([ + #include + int main () { +- return expand_module_avrules(NULL, NULL, NULL, NULL, NULL, 0, 0); ++ return expand_module_avrules(NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0); + }])], + AC_MSG_RESULT([yes]), + AC_MSG_ERROR([this version of libsepol is incompatible with SETools])) +-- +1.7.6.2 + diff --git a/0006-Changes-to-support-named-file_trans-rules.patch b/0006-Changes-to-support-named-file_trans-rules.patch new file mode 100644 index 0000000..7068cca --- /dev/null +++ b/0006-Changes-to-support-named-file_trans-rules.patch @@ -0,0 +1,1483 @@ +From 287f507657e162bc09b5c186bbd580901fbc942a Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 15:47:28 -0400 +Subject: [PATCH 6/6] Changes to support named file_trans rules + +--- + libapol/include/apol/ftrule-query.h | 198 +++++++++++++++++++ + libapol/include/apol/policy-query.h | 1 + + libapol/src/Makefile.am | 1 + + libapol/src/ftrule-query.c | 363 +++++++++++++++++++++++++++++++++++ + libapol/src/libapol.map | 1 + + libqpol/include/qpol/ftrule_query.h | 116 +++++++++++ + libqpol/include/qpol/policy.h | 1 + + libqpol/src/Makefile.am | 1 + + libqpol/src/ftrule_query.c | 277 ++++++++++++++++++++++++++ + libqpol/src/libqpol.map | 1 + + libqpol/src/module_compiler.c | 12 ++ + libqpol/src/policy_define.c | 186 ++++++++++++++++++- + libqpol/src/policy_parse.y | 13 +- + libqpol/src/policy_scan.l | 1 + + secmds/sesearch.c | 101 ++++++++++ + 15 files changed, 1270 insertions(+), 3 deletions(-) + create mode 100644 libapol/include/apol/ftrule-query.h + create mode 100644 libapol/src/ftrule-query.c + create mode 100644 libqpol/include/qpol/ftrule_query.h + create mode 100644 libqpol/src/ftrule_query.c + +diff --git a/libapol/include/apol/ftrule-query.h b/libapol/include/apol/ftrule-query.h +new file mode 100644 +index 0000000..119c52f +--- /dev/null ++++ b/libapol/include/apol/ftrule-query.h +@@ -0,0 +1,198 @@ ++/** ++ * @file ++ * ++ * Routines to query filename_transition rules of a ++ * policy. ++ * ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Jason Tang jtang@tresys.com ++ * ++ * Copyright (C) 2006-2007 Tresys Technology, LLC ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef APOL_FILENAMERULE_QUERY_H ++#define APOL_FILENAMERULE_QUERY_H ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++#include "policy.h" ++#include "vector.h" ++#include ++ ++ typedef struct apol_filename_trans_query apol_filename_trans_query_t; ++ ++ ++/******************** filename_transition queries ********************/ ++ ++/** ++ * Execute a query against all filename_transition rules within the ++ * policy. ++ * ++ * @param p Policy within which to look up filename_transition rules. ++ * @param r Structure containing parameters for query. If this is ++ * NULL then return all filename_transition rules. ++ * @param v Reference to a vector of qpol_filename_trans_t. The vector ++ * will be allocated by this function. The caller must call ++ * apol_vector_destroy() afterwards. This will be set to NULL upon no ++ * results or upon error. ++ * ++ * @return 0 on success (including none found), negative on error. ++ */ ++ extern int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * r, apol_vector_t ** v); ++ ++/** ++ * Allocate and return a new filename trans query structure. All fields ++ * are initialized, such that running this blank query results in ++ * returning all filename_transitions within the policy. The caller must ++ * call apol_filename_trans_query_destroy() upon the return value ++ * afterwards. ++ * ++ * @return An initialized filename trans query structure, or NULL upon ++ * error. ++ */ ++ extern apol_filename_trans_query_t *apol_filename_trans_query_create(void); ++ ++/** ++ * Deallocate all memory associated with the referenced filename trans ++ * query, and then set it to NULL. This function does nothing if the ++ * query is already NULL. ++ * ++ * @param r Reference to a filename trans query structure to destroy. ++ */ ++ extern void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r); ++ ++/** ++ * Set a filename_trans query to return rules whose source symbol matches ++ * symbol. Symbol may be a type or attribute; if it is an alias then ++ * the query will convert it to its primary prior to searching. If ++ * is_indirect is non-zero then the search will be done indirectly. ++ * If the symbol is a type, then the query matches rules with one of ++ * the type's attributes. If the symbol is an attribute, then it ++ * matches rule with any of the attribute's types. ++ * ++ * @param p Policy handler, to report errors. ++ * @param t TE rule query to set. ++ * @param symbol Limit query to rules with this symbol as their ++ * source, or NULL to unset this field. ++ * @param is_indirect If non-zero, perform indirect matching. ++ * ++ * @return 0 on success, negative on error. ++ */ ++ extern int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol, ++ int is_indirect); ++ ++/** ++ * Set a filename trans query to return rules with a particular target ++ * symbol. Symbol may be a type or attribute; if it is an alias then ++ * the query will convert it to its primary prior to searching. If ++ * is_indirect is non-zero then the search will be done indirectly. ++ * If the symbol is a type, then the query matches rules with one of ++ * the type's attributes. If the symbol is an attribute, then it ++ * matches rule with any of the attribute's types. ++ * ++ * @param p Policy handler, to report errors. ++ * @param r Role trans query to set. ++ * @param symbol Limit query to rules with this type or attribute as ++ * their target, or NULL to unset this field. ++ * @param is_indirect If non-zero, perform indirect matching. ++ * ++ * @return 0 on success, negative on error. ++ */ ++ extern int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *symbol, ++ int is_indirect); ++ ++/** ++ * Set a filename trans query to return rules with a particular default ++ * filename. This field is ignored if ++ * apol_filename_trans_query_set_source_any() is set to non-zero. ++ * ++ * @param p Policy handler, to report errors. ++ * @param r Role trans query to set. ++ * @param filename Limit query to rules with this filename as their default, or ++ * NULL to unset this field. ++ * ++ * @return 0 on success, negative on error. ++ */ ++ extern int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *filename); ++ ++/** ++ * Set at filename_trans query to return rules with this object (non-common) ++ * class. If more than one class are appended to the query, the ++ * rule's class must be one of those appended. (I.e., the rule's ++ * class must be a member of the query's classes.) Pass a NULL to ++ * clear all classes. Note that this performs straight string ++ * comparison, ignoring the regex flag. ++ ++ * ++ * @param p Policy handler, to report errors. ++ * @param t TE rule query to set. ++ * @param obj_class Name of object class to add to search set. ++ * ++ * @return 0 on success, negative on error. ++ */ ++ extern int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class); ++ ++/** ++ * Set a filename trans query to treat the source filename as any. That is, ++ * use the same symbol for either source or default of a ++ * filename_transition rule. This flag does nothing if the source filename is ++ * not set. Note that a filename_transition's target is a type, so thus ++ * this flag does not affect its searching. ++ * ++ * @param p Policy handler, to report errors. ++ * @param r Role trans query to set. ++ * @param is_any Non-zero to use source symbol for source or default ++ * field, 0 to keep source as only source. ++ * ++ * @return Always 0. ++ */ ++ extern int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_any); ++ ++/** ++ * Set a filename trans query to use regular expression searching for ++ * source, target, and default fields. Strings will be treated as ++ * regexes instead of literals. For the target type, matching will ++ * occur against the type name or any of its aliases. ++ * ++ * @param p Policy handler, to report errors. ++ * @param r Role trans query to set. ++ * @param is_regex Non-zero to enable regex searching, 0 to disable. ++ * ++ * @return Always 0. ++ */ ++ extern int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_regex); ++ ++/** ++ * Render a filename_transition rule to a string. ++ * ++ * @param policy Policy handler, to report errors. ++ * @param rule The rule to render. ++ * ++ * @return A newly malloc()'d string representation of the rule, or NULL on ++ * failure; if the call fails, errno will be set. The caller is responsible ++ * for calling free() on the returned string. ++ */ ++ extern char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * rule); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +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/ftrule-query.c b/libapol/src/ftrule-query.c +new file mode 100644 +index 0000000..dc248de +--- /dev/null ++++ b/libapol/src/ftrule-query.c +@@ -0,0 +1,363 @@ ++/** ++ * @file ++ * ++ * Provides a way for setools to make queries about type enforcement ++ * filename_transs within a policy. The caller obtains a query object, fills in ++ * its parameters, and then runs the query; it obtains a vector of ++ * results. Searches are conjunctive -- all fields of the search ++ * query must match for a datum to be added to the results query. ++ * ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Jason Tang jtang@tresys.com ++ * ++ * Copyright (C) 2006-2007 Tresys Technology, LLC ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "policy-query-internal.h" ++ ++#include ++#include ++ ++struct apol_filename_trans_query ++{ ++ char *source, *target, *default_type, *name; ++ apol_vector_t *classes; ++ unsigned int flags; ++}; ++ ++ ++/******************** filename_transition queries ********************/ ++ ++int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * t, apol_vector_t ** v) ++{ ++ apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL; ++ int retval = -1, source_as_any = 0, is_regex = 0, append_filename_trans; ++ char *bool_name = NULL; ++ *v = NULL; ++ unsigned int flags = 0; ++ qpol_iterator_t *iter = NULL, *type_iter = NULL; ++ ++ if (t != NULL) { ++ flags = t->flags; ++ is_regex = t->flags & APOL_QUERY_REGEX; ++ if (t->source != NULL && ++ (source_list = ++ apol_query_create_candidate_type_list(p, t->source, is_regex, ++ t->flags & APOL_QUERY_SOURCE_INDIRECT, ++ ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) / ++ APOL_QUERY_SOURCE_TYPE))) == NULL) { ++ goto cleanup; ++ } ++ ++ if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) { ++ default_list = target_list = source_list; ++ source_as_any = 1; ++ } else { ++ if (t->target != NULL && ++ (target_list = ++ apol_query_create_candidate_type_list(p, t->target, is_regex, ++ t->flags & APOL_QUERY_TARGET_INDIRECT, ++ ((t-> ++ flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE)) ++ / APOL_QUERY_TARGET_TYPE))) == NULL) { ++ goto cleanup; ++ } ++ if (t->default_type != NULL && ++ (default_list = ++ apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0, ++ APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) { ++ goto cleanup; ++ } ++ } ++ if (t->classes != NULL && ++ apol_vector_get_size(t->classes) > 0 && ++ (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) { ++ goto cleanup; ++ } ++ } ++ ++ if (qpol_policy_get_filename_trans_iter(p->p, &iter) < 0) { ++ return -1; ++ } ++ ++ if ((*v = apol_vector_create(NULL)) == NULL) { ++ ERR(p, "%s", strerror(errno)); ++ goto cleanup; ++ } ++ ++ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { ++ qpol_filename_trans_t *filename_trans; ++ if (qpol_iterator_get_item(iter, (void **)&filename_trans) < 0) { ++ goto cleanup; ++ } ++ int match_source = 0, match_target = 0, match_default = 0, match_bool = 0; ++ size_t i; ++ ++ if (source_list == NULL) { ++ match_source = 1; ++ } else { ++ const qpol_type_t *source_type; ++ if (qpol_filename_trans_get_source_type(p->p, filename_trans, &source_type) < 0) { ++ goto cleanup; ++ } ++ if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) { ++ match_source = 1; ++ } ++ } ++ ++ /* if source did not match, but treating source symbol ++ * as any field, then delay rejecting this filename_trans until ++ * the target and default have been checked */ ++ if (!source_as_any && !match_source) { ++ continue; ++ } ++ ++ if (target_list == NULL || (source_as_any && match_source)) { ++ match_target = 1; ++ } else { ++ const qpol_type_t *target_type; ++ if (qpol_filename_trans_get_target_type(p->p, filename_trans, &target_type) < 0) { ++ goto cleanup; ++ } ++ if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) { ++ match_target = 1; ++ } ++ } ++ ++ if (!source_as_any && !match_target) { ++ continue; ++ } ++ ++ if (default_list == NULL || (source_as_any && match_source) || (source_as_any && match_target)) { ++ match_default = 1; ++ } else { ++ const qpol_type_t *default_type; ++ if (qpol_filename_trans_get_default_type(p->p, filename_trans, &default_type) < 0) { ++ goto cleanup; ++ } ++ if (apol_vector_get_index(default_list, default_type, NULL, NULL, &i) == 0) { ++ match_default = 1; ++ } ++ } ++ ++ if (!source_as_any && !match_default) { ++ continue; ++ } ++ /* at least one thing must match if source_as_any was given */ ++ if (source_as_any && (!match_source && !match_target && !match_default)) { ++ continue; ++ } ++ ++ if (class_list != NULL) { ++ const qpol_class_t *obj_class; ++ if (qpol_filename_trans_get_object_class(p->p, filename_trans, &obj_class) < 0) { ++ goto cleanup; ++ } ++ if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) { ++ continue; ++ } ++ } ++ ++ if (apol_vector_append(*v, filename_trans)) { ++ ERR(p, "%s", strerror(ENOMEM)); ++ goto cleanup; ++ } ++ } ++ ++ retval = 0; ++ cleanup: ++ if (retval != 0) { ++ apol_vector_destroy(v); ++ } ++ apol_vector_destroy(&source_list); ++ if (!source_as_any) { ++ apol_vector_destroy(&target_list); ++ apol_vector_destroy(&default_list); ++ } ++ apol_vector_destroy(&class_list); ++ return retval; ++} ++ ++apol_filename_trans_query_t *apol_filename_trans_query_create(void) ++{ ++ apol_filename_trans_query_t *t = calloc(1, sizeof(apol_filename_trans_query_t)); ++ if (t != NULL) { ++ t->flags = ++ (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE | ++ APOL_QUERY_TARGET_ATTRIBUTE); ++ } ++ return t; ++} ++ ++void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r) ++{ ++ if (r != NULL && *r != NULL) { ++ free((*r)->source); ++ free((*r)->target); ++ free((*r)->default_type); ++ free((*r)->name); ++ free(*r); ++ *r = NULL; ++ } ++} ++ ++int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename, int is_indirect) ++{ ++ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT); ++ return apol_query_set(p, &t->source, NULL, filename); ++} ++ ++int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *type, int is_indirect) ++{ ++ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT); ++ return apol_query_set(p, &t->target, NULL, type); ++} ++ ++int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol) ++{ ++ return apol_query_set(p, &t->default_type, NULL, symbol); ++} ++ ++int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class) ++{ ++ char *s = NULL; ++ if (obj_class == NULL) { ++ apol_vector_destroy(&t->classes); ++ } else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL) ++ || apol_vector_append(t->classes, s) < 0) { ++ ERR(p, "%s", strerror(errno)); ++ free(s); ++ return -1; ++ } ++ return 0; ++} ++ ++int apol_filename_trans_query_set_name(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename) ++{ ++ return apol_query_set(p, &t->name, NULL, filename); ++} ++ ++int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_any) ++{ ++ return apol_query_set_flag(p, &t->flags, is_any, APOL_QUERY_SOURCE_AS_ANY); ++} ++ ++int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_regex) ++{ ++ return apol_query_set_regex(p, &t->flags, is_regex); ++} ++ ++char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * filename_trans) ++{ ++ char *tmp = NULL; ++ const char *tmp_name = NULL; ++ const char *filename_trans_type_str; ++ int error = 0; ++ size_t tmp_sz = 0; ++ uint32_t filename_trans_type = 0; ++ const qpol_type_t *type = NULL; ++ const qpol_class_t *obj_class = NULL; ++ ++ if (!policy || !filename_trans) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ /* source type */ ++ if (qpol_filename_trans_get_source_type(policy->p, filename_trans, &type)) { ++ error = errno; ++ goto err; ++ } ++ if (qpol_type_get_name(policy->p, type, &tmp_name)) { ++ error = errno; ++ goto err; ++ } ++ if (apol_str_appendf(&tmp, &tmp_sz, "transition_type %s ", tmp_name)) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ ++ /* target type */ ++ if (qpol_filename_trans_get_target_type(policy->p, filename_trans, &type)) { ++ error = errno; ++ goto err; ++ } ++ if (qpol_type_get_name(policy->p, type, &tmp_name)) { ++ error = errno; ++ goto err; ++ } ++ if (apol_str_appendf(&tmp, &tmp_sz, "%s : ", tmp_name)) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ ++ /* object class */ ++ if (qpol_filename_trans_get_object_class(policy->p, filename_trans, &obj_class)) { ++ error = errno; ++ goto err; ++ } ++ if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) { ++ error = errno; ++ goto err; ++ } ++ if (apol_str_appendf(&tmp, &tmp_sz, "%s ", tmp_name)) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ ++ /* default type */ ++ if (qpol_filename_trans_get_default_type(policy->p, filename_trans, &type)) { ++ error = errno; ++ goto err; ++ } ++ if (qpol_type_get_name(policy->p, type, &tmp_name)) { ++ error = errno; ++ goto err; ++ } ++ if (apol_str_appendf(&tmp, &tmp_sz, "%s", tmp_name)) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ ++ if (qpol_filename_trans_get_filename(policy->p, filename_trans, &tmp_name)) { ++ error = errno; ++ goto err; ++ } ++ ++ if (apol_str_appendf(&tmp, &tmp_sz, " %s", tmp_name)) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ ++ if (apol_str_appendf(&tmp, &tmp_sz, ";")) { ++ error = errno; ++ ERR(policy, "%s", strerror(error)); ++ goto err; ++ } ++ return tmp; ++ ++ err: ++ free(tmp); ++ errno = error; ++ return NULL; ++} +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/ftrule_query.h b/libqpol/include/qpol/ftrule_query.h +new file mode 100644 +index 0000000..1f533a4 +--- /dev/null ++++ b/libqpol/include/qpol/ftrule_query.h +@@ -0,0 +1,116 @@ ++/** ++ * @file ++ * Defines public interface for iterating over FTRULE rules. ++ * ++ * @author Kevin Carr kcarr@tresys.com ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Jason Tang jtang@tresys.com ++ * ++ * Copyright (C) 2006-2007 Tresys Technology, LLC ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef QPOL_FTRULERULE_QUERY ++#define QPOL_FTRULERULE_QUERY ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++#include ++#include ++ ++ typedef struct qpol_filename_trans qpol_filename_trans_t; ++ ++/** ++ * Get an iterator over all filename transition rules in the policy. ++ * @param policy Policy from which to create the iterator. ++ * @param iter Iterator over items of type qpol_filename_trans_t returned. ++ * The caller is responsible for calling qpol_iterator_destroy() ++ * to free memory used by this iterator. ++ * It is important to note that this iterator is only valid as long as ++ * the policy is unmodifed. ++ * @returm 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *iter will be NULL. ++ */ ++ extern int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter); ++ ++/** ++ * Get the source type from a filename transition rule. ++ * @param policy The policy from which the rule comes. ++ * @param rule The rule from which to get the source type. ++ * @param source Pointer in which to store the source type. ++ * The caller should not free this pointer. ++ * @return 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *source will be NULL. ++ */ ++ extern int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const qpol_type_t ** source); ++ ++/** ++ * Get the target type from a filename transition rule. ++ * @param policy The policy from which the rule comes. ++ * @param rule The rule from which to get the target type. ++ * @param target Pointer in which to store the target type. ++ * The caller should not free this pointer. ++ * @return 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *target will be NULL. ++ */ ++ extern int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const qpol_type_t ** target); ++ ++/** ++ * Get the default type from a type rule. ++ * @param policy Policy from which the rule comes. ++ * @param rule The rule from which to get the default type. ++ * @param dflt Pointer in which to store the default type. ++ * The caller should not free this pointer. ++ * @returm 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *dflt will be NULL. ++ */ ++ extern int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const qpol_type_t ** dflt); ++ ++/** ++ * Get the object class from a type rule. ++ * @param policy Policy from which the rule comes. ++ * @param rule The rule from which to get the object class. ++ * @param obj_class Pointer in which to store the object class. ++ * The caller should not free this pointer. ++ * @returm 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *obj_class will be NULL. ++ */ ++ extern int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const qpol_class_t ** obj_class); ++ ++/** ++ * Get the transition filename type from a type rule. ++ * @param policy Policy from which the rule comes. ++ * @param rule The rule from which to get the transition filename. ++ * @param target Pointer in which to store the transition filename. ++ * The caller should not free this pointer. ++ * @returm 0 on success and < 0 on failure; if the call fails, ++ * errno will be set and *target will be NULL. ++ */ ++ extern int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const char ** name); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* QPOL_FTRULERULE_QUERY */ +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/ftrule_query.c b/libqpol/src/ftrule_query.c +new file mode 100644 +index 0000000..d6db848 +--- /dev/null ++++ b/libqpol/src/ftrule_query.c +@@ -0,0 +1,277 @@ ++/** ++ * @file ++ * Defines public interface for iterating over RBAC rules. ++ * ++ * @author Jeremy A. Mowery jmowery@tresys.com ++ * @author Jason Tang jtang@tresys.com ++ * ++ * Copyright (C) 2006-2007 Tresys Technology, LLC ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include "iterator_internal.h" ++#include "qpol_internal.h" ++#include ++ ++typedef struct filename_trans_state ++{ ++ filename_trans_t *head; ++ filename_trans_t *cur; ++} filename_trans_state_t; ++ ++static int filename_trans_state_end(const qpol_iterator_t * iter) ++{ ++ filename_trans_state_t *fts = NULL; ++ ++ if (!iter || !(fts = qpol_iterator_state(iter))) { ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ return fts->cur ? 0 : 1; ++} ++ ++static void *filename_trans_state_get_cur(const qpol_iterator_t * iter) ++{ ++ filename_trans_state_t *fts = NULL; ++ const policydb_t *db = NULL; ++ ++ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter)) || filename_trans_state_end(iter)) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ return fts->cur; ++} ++ ++static int filename_trans_state_next(qpol_iterator_t * iter) ++{ ++ filename_trans_state_t *fts = NULL; ++ const policydb_t *db = NULL; ++ ++ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ if (filename_trans_state_end(iter)) { ++ errno = ERANGE; ++ return STATUS_ERR; ++ } ++ ++ fts->cur = fts->cur->next; ++ ++ return STATUS_SUCCESS; ++} ++ ++static size_t filename_trans_state_size(const qpol_iterator_t * iter) ++{ ++ filename_trans_state_t *fts = NULL; ++ const policydb_t *db = NULL; ++ filename_trans_t *tmp = NULL; ++ size_t count = 0; ++ ++ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ for (tmp = fts->head; tmp; tmp = tmp->next) ++ count++; ++ ++ return count; ++} ++ ++int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) ++{ ++ policydb_t *db = NULL; ++ filename_trans_state_t *fts = NULL; ++ int error = 0; ++ ++ if (iter) ++ *iter = NULL; ++ ++ if (!policy || !iter) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ++ fts = calloc(1, sizeof(filename_trans_state_t)); ++ if (!fts) { ++ /* errno set by calloc */ ++ ERR(policy, "%s", strerror(errno)); ++ return STATUS_ERR; ++ } ++ fts->head = fts->cur = db->filename_trans; ++ ++ if (qpol_iterator_create ++ (policy, (void *)fts, filename_trans_state_get_cur, filename_trans_state_next, filename_trans_state_end, filename_trans_state_size, ++ free, iter)) { ++ error = errno; ++ free(fts); ++ errno = error; ++ return STATUS_ERR; ++ } ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** source) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (source) { ++ *source = NULL; ++ } ++ ++ if (!policy || !rule || !source) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *source = (qpol_type_t *) db->type_val_to_struct[ft->stype - 1]; ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** target) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (target) { ++ *target = NULL; ++ } ++ ++ if (!policy || !rule || !target) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *target = (qpol_type_t *) db->type_val_to_struct[ft->ttype - 1]; ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, ++ const qpol_class_t ** obj_class) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (obj_class) { ++ *obj_class = NULL; ++ } ++ ++ if (!policy || !rule || !obj_class) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *obj_class = (qpol_class_t *) db->class_val_to_struct[ft->tclass - 1]; ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_trans_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** output_type) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (output_type) { ++ *output_type = NULL; ++ } ++ ++ if (!policy || !rule || !output_type) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *output_type = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1]; ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** dflt) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (dflt) { ++ *dflt = NULL; ++ } ++ ++ if (!policy || !rule || !dflt) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *dflt = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1]; ++ ++ return STATUS_SUCCESS; ++} ++ ++int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name) ++{ ++ policydb_t *db = NULL; ++ filename_trans_t *ft = NULL; ++ ++ if (name) { ++ *name = NULL; ++ } ++ ++ if (!policy || !rule || !name) { ++ ERR(policy, "%s", strerror(EINVAL)); ++ errno = EINVAL; ++ return STATUS_ERR; ++ } ++ ++ db = &policy->p->p; ++ ft = (filename_trans_t *) rule; ++ ++ *name = ft->name; ++ ++ return STATUS_SUCCESS; ++} ++ +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 +@@ -1247,6 +1247,18 @@ void append_role_allow(role_allow_rule_t * 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) + { + avrule_decl_t *decl = stack_top->decl; +diff --git a/libqpol/src/policy_define.c b/libqpol/src/policy_define.c +index c94f7aa..0f3a45a 100644 +--- a/libqpol/src/policy_define.c ++++ b/libqpol/src/policy_define.c +@@ -2133,7 +2133,7 @@ int define_role_trans(void) + + /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ + #ifdef HAVE_SEPOL_USER_ROLE_MAPPING +- if (role_set_expand(&roles, &e_roles, policydbp, NULL)) ++ if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) + #else + if (role_set_expand(&roles, &e_roles, policydbp)) + #endif +@@ -2226,6 +2226,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_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/secmds/sesearch.c b/secmds/sesearch.c +index ec0315f..e44b3bc 100644 +--- a/secmds/sesearch.c ++++ b/secmds/sesearch.c +@@ -575,6 +575,95 @@ 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 == QPOL_RULE_TYPE_TRANS && !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)) { ++ 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 (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) ++{ ++ qpol_policy_t *q = apol_policy_get_qpol(policy); ++ size_t i, num_rules = 0; ++ const qpol_filename_trans_t *rule = NULL; ++ char *tmp = NULL, *rule_str = NULL, *expr = NULL; ++ char enable_char = ' ', branch_char = ' '; ++ qpol_iterator_t *iter = NULL; ++ const qpol_cond_t *cond = NULL; ++ uint32_t enabled = 0, list = 0; ++ ++ if (!(num_rules = apol_vector_get_size(v))) ++ goto cleanup; ++ ++ fprintf(stdout, "Found %zd named file transition rules:\n", num_rules); ++ ++ for (i = 0; i < num_rules; i++) { ++ enable_char = branch_char = ' '; ++ if (!(rule = apol_vector_get_element(v, i))) ++ goto cleanup; ++ ++ if (!(rule_str = apol_filename_trans_render(policy, rule))) ++ goto cleanup; ++ fprintf(stdout, "%s %s\n", rule_str, expr ? expr : ""); ++ free(rule_str); ++ rule_str = NULL; ++ free(expr); ++ expr = NULL; ++ } ++ ++ cleanup: ++ free(tmp); ++ free(rule_str); ++ free(expr); ++} ++ + 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; +@@ -1128,6 +1217,18 @@ int main(int argc, char **argv) + print_te_results(policy, &cmd_opts, v); + fprintf(stdout, "\n"); + } ++ ++ if (cmd_opts.all || cmd_opts.type == QPOL_RULE_TYPE_TRANS) { ++ apol_vector_destroy(&v); ++ if (perform_ft_query(policy, &cmd_opts, &v)) { ++ rt = 1; ++ goto cleanup; ++ } ++ ++ print_ft_results(policy, &cmd_opts, v); ++ fprintf(stdout, "\n"); ++ } ++ + apol_vector_destroy(&v); + if (perform_ra_query(policy, &cmd_opts, &v)) { + rt = 1; +-- +1.7.6.2 + diff --git a/0007-Remove-unused-variables.patch b/0007-Remove-unused-variables.patch new file mode 100644 index 0000000..dfa532c --- /dev/null +++ b/0007-Remove-unused-variables.patch @@ -0,0 +1,277 @@ +From e30036e358b8f1c3f56048b467e8646fa3bfffb6 Mon Sep 17 00:00:00 2001 +From: Dan Walsh +Date: Tue, 20 Sep 2011 16:40:26 -0400 +Subject: [PATCH 7/7] Remove unused variables + +--- + libapol/src/ftrule-query.c | 11 ++---- + libqpol/src/ftrule_query.c | 2 - + secmds/sesearch.c | 86 +++++++++++++++++++++++++++++++++----------- + 3 files changed, 68 insertions(+), 31 deletions(-) + +diff --git a/libapol/src/ftrule-query.c b/libapol/src/ftrule-query.c +index dc248de..9c7a23b 100644 +--- a/libapol/src/ftrule-query.c ++++ b/libapol/src/ftrule-query.c +@@ -45,14 +45,11 @@ struct apol_filename_trans_query + int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * t, apol_vector_t ** v) + { + apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL; +- int retval = -1, source_as_any = 0, is_regex = 0, append_filename_trans; +- char *bool_name = NULL; ++ int retval = -1, source_as_any = 0, is_regex = 0; + *v = NULL; +- unsigned int flags = 0; +- qpol_iterator_t *iter = NULL, *type_iter = NULL; ++ qpol_iterator_t *iter = NULL; + + if (t != NULL) { +- flags = t->flags; + is_regex = t->flags & APOL_QUERY_REGEX; + if (t->source != NULL && + (source_list = +@@ -104,7 +101,7 @@ int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filenam + if (qpol_iterator_get_item(iter, (void **)&filename_trans) < 0) { + goto cleanup; + } +- int match_source = 0, match_target = 0, match_default = 0, match_bool = 0; ++ int match_source = 0, match_target = 0, match_default = 0; + size_t i; + + if (source_list == NULL) { +@@ -265,10 +262,8 @@ char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filena + { + char *tmp = NULL; + const char *tmp_name = NULL; +- const char *filename_trans_type_str; + int error = 0; + size_t tmp_sz = 0; +- uint32_t filename_trans_type = 0; + const qpol_type_t *type = NULL; + const qpol_class_t *obj_class = NULL; + +diff --git a/libqpol/src/ftrule_query.c b/libqpol/src/ftrule_query.c +index d6db848..3148d30 100644 +--- a/libqpol/src/ftrule_query.c ++++ b/libqpol/src/ftrule_query.c +@@ -254,7 +254,6 @@ int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpo + + int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name) + { +- policydb_t *db = NULL; + filename_trans_t *ft = NULL; + + if (name) { +@@ -267,7 +266,6 @@ int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_fi + return STATUS_ERR; + } + +- db = &policy->p->p; + ft = (filename_trans_t *) rule; + + *name = ft->name; +diff --git a/secmds/sesearch.c b/secmds/sesearch.c +index e44b3bc..319ffe7 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; +@@ -293,7 +295,8 @@ 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) ++ goto cleanup; + free(tmp); + tmp = NULL; + if (!expr) +@@ -356,7 +359,8 @@ 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) ++ goto cleanup; + free(tmp); + tmp = NULL; + if (!expr) +@@ -488,7 +492,8 @@ 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) ++ goto cleanup; + free(tmp); + tmp = NULL; + if (!expr) +@@ -553,7 +558,8 @@ 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) ++ goto cleanup; + free(tmp); + tmp = NULL; + if (!expr) +@@ -586,7 +592,7 @@ static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, + return -1; + } + +- if (!opt->type == QPOL_RULE_TYPE_TRANS && !opt->all) { ++ if (!opt->type && !opt->all) { + *v = NULL; + return 0; /* no search to do */ + } +@@ -600,17 +606,44 @@ static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, + + 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)) { ++ 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; +@@ -630,37 +663,36 @@ static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, + + static void print_ft_results(const apol_policy_t * policy, const options_t * opt, const apol_vector_t * v) + { +- qpol_policy_t *q = apol_policy_get_qpol(policy); +- size_t i, num_rules = 0; +- const qpol_filename_trans_t *rule = NULL; +- char *tmp = NULL, *rule_str = NULL, *expr = NULL; ++ size_t i, num_filename_trans = 0; ++ const qpol_filename_trans_t *filename_trans = NULL; ++ char *tmp = NULL, *filename_trans_str = NULL, *expr = NULL; + char enable_char = ' ', branch_char = ' '; + qpol_iterator_t *iter = NULL; + const qpol_cond_t *cond = NULL; + uint32_t enabled = 0, list = 0; + +- if (!(num_rules = apol_vector_get_size(v))) ++ if (!(num_filename_trans = apol_vector_get_size(v))) + goto cleanup; + +- fprintf(stdout, "Found %zd named file transition rules:\n", num_rules); ++ fprintf(stdout, "Found %zd named file transition filename_trans:\n", num_filename_trans); + +- for (i = 0; i < num_rules; i++) { ++ for (i = 0; i < num_filename_trans; i++) { + enable_char = branch_char = ' '; +- if (!(rule = apol_vector_get_element(v, i))) ++ if (!(filename_trans = apol_vector_get_element(v, i))) + goto cleanup; + +- if (!(rule_str = apol_filename_trans_render(policy, rule))) ++ if (!(filename_trans_str = apol_filename_trans_render(policy, filename_trans))) + goto cleanup; +- fprintf(stdout, "%s %s\n", rule_str, expr ? expr : ""); +- free(rule_str); +- rule_str = NULL; ++ fprintf(stdout, "%s %s\n", filename_trans_str, expr ? expr : ""); ++ free(filename_trans_str); ++ filename_trans_str = NULL; + free(expr); + expr = NULL; + } + + cleanup: + free(tmp); +- free(rule_str); ++ free(filename_trans_str); + free(expr); + } + +@@ -930,7 +962,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; +@@ -946,6 +978,18 @@ int main(int argc, char **argv) + exit(1); + } + break; ++ case 'D': /* source */ ++ if (optarg == 0) { ++ usage(argv[0], 1); ++ printf("Missing source default type for -D (--default)\n"); ++ exit(1); ++ } ++ cmd_opts.default_name = strdup(optarg); ++ if (!cmd_opts.default_name) { ++ ++ exit(1); ++ } ++ break; + case 't': /* target */ + if (optarg == 0) { + usage(argv[0], 1); +@@ -1218,7 +1262,7 @@ int main(int argc, char **argv) + fprintf(stdout, "\n"); + } + +- if (cmd_opts.all || cmd_opts.type == QPOL_RULE_TYPE_TRANS) { ++ if (cmd_opts.all || cmd_opts.type) { + apol_vector_destroy(&v); + if (perform_ft_query(policy, &cmd_opts, &v)) { + rt = 1; +-- +1.7.6.2 + diff --git a/setools.spec b/setools.spec index e0ddf53..9e4f55b 100644 --- a/setools.spec +++ b/setools.spec @@ -5,7 +5,7 @@ Name: setools Version: %{setools_maj_ver}.%{setools_min_ver} -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv2 URL: http://oss.tresys.com/projects/setools BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -14,10 +14,13 @@ Source1: setools.pam Source2: apol.desktop Source3: seaudit.desktop Source4: sediffx.desktop -Patch1: setools-python.patch -Patch2: setools-exitstatus.patch -Patch3: setools-neverallow.patch -Patch4: setools-cmdline.patch +Patch1: 0001-add-setools-seinfo-and-sesearch-python-bindings.patch +Patch2: 0002-setools-should-exit-with-an-error-status-if-it-gets-.patch +Patch3: 0003-Since-we-do-not-ship-neverallow-rules-all-always-fai.patch +Patch4: 0004-Fix-man-pages-and-getoptions.patch +Patch5: 0005-Fix-sepol-calls-to-work-with-latest-libsepol.patch +Patch6: 0006-Changes-to-support-named-file_trans-rules.patch +Patch7: 0007-Remove-unused-variables.patch Summary: Policy analysis tools for SELinux Group: System Environment/Base Requires: setools-libs = %{version}-%{release} setools-libs-tcl = %{version}-%{release} setools-gui = %{version}-%{release} setools-console = %{version}-%{release} @@ -192,7 +195,10 @@ This package includes the following graphical tools: %patch1 -p 1 -b .python %patch2 -p 1 -b .exitstatus %patch3 -p 1 -b .neverallow -%patch4 -p 1 -b .cmdline +%patch4 -p 1 -b .manpage +%patch5 -p 1 -b .libsepol +%patch6 -p 1 -b .filenametrans +%patch7 -p 1 -b .unused %ifarch sparc sparcv9 sparc64 s390 s390x for file in `find . -name Makefile.am`; do @@ -359,6 +365,10 @@ rm -rf ${RPM_BUILD_ROOT} %postun libs-tcl -p /sbin/ldconfig %changelog +* Tue Sep 20 2011 Dan Walsh - 3.3.7-17 +- Fix to build with latest libsepol +- Show filename transition files + * Thu Apr 21 2011 Dan Walsh - 3.3.7-16 - Rebuild for new sepol