public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Petr Lautrbach <plautrba@redhat.com>
To: git-commits@fedoraproject.org
Subject: [tests/selinux] pr775-checkpolicy-revdeps: Common library for selinux-policy component
Date: Fri, 11 Sep 2026 13:17:44 GMT	[thread overview]
Message-ID: <178913266467.1.6483137332602741153.tests-selinux-af33a2c4be8c@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : tests/selinux
            Branch : pr775-checkpolicy-revdeps
            Commit : af33a2c4be8ce7f382cbcdb122226a3c27eb679b
            Author : Petr Lautrbach <plautrba@redhat.com>
            Date   : 2020-01-13T12:30:56+01:00
            Stats  : +2433/-0 in 4 file(s)
            URL    : https://src.fedoraproject.org/tests/selinux/c/af33a2c4be8ce7f382cbcdb122226a3c27eb679b?branch=pr775-checkpolicy-revdeps

            Log:
            Common library for selinux-policy component

For library documentation run:

    $ perldoc selinux-policy/Library/common/lib.sh

---
diff --git a/selinux-policy/Library/common/Makefile b/selinux-policy/Library/common/Makefile
new file mode 100644
index 0000000..8c2004f
--- /dev/null
+++ b/selinux-policy/Library/common/Makefile
@@ -0,0 +1,64 @@
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   Makefile of /CoreOS/selinux-policy/Library/common
+#   Description: Wrapper library for /CoreOS/selinux-policy/common
+#   Author: David Spurek <dspurek@redhat.com>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   Copyright (c) 2013 Red Hat, Inc. All rights reserved.
+#
+#   This copyrighted material is made available to anyone wishing
+#   to use, modify, copy, or redistribute it subject to the terms
+#   and conditions of the GNU General Public License version 2.
+#
+#   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 Street, Fifth Floor,
+#   Boston, MA 02110-1301, USA.
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+export TEST=/CoreOS/selinux-policy/Library/common
+export TESTVERSION=1.0
+
+BUILT_FILES=
+
+FILES=$(METADATA) lib.sh Makefile runtest.sh mkcache.py
+
+.PHONY: all install download clean
+
+run: $(FILES)
+	./runtest.sh
+
+include /usr/share/rhts/lib/rhts-make.include
+
+$(METADATA): Makefile
+	@echo "Owner:           David Spurek <dspurek@redhat.com>" > $(METADATA)
+	@echo "Name:            $(TEST)" >> $(METADATA)
+	@echo "TestVersion:     $(TESTVERSION)" >> $(METADATA)
+	@echo "Path:            $(TEST_DIR)" >> $(METADATA)
+	@echo "Description:     Common library for SELinux" >> $(METADATA)
+	@echo "Type:            Library" >> $(METADATA)
+	@echo "TestTime:        120m" >> $(METADATA)
+	@echo "Requires:        setools" >> $(METADATA)
+	@echo "Requires:        setools-console" >> $(METADATA)
+	@echo "Requires:        expect" >> $(METADATA)
+	@echo "Requires:        policycoreutils" >> $(METADATA)
+	@echo "Requires:        /usr/sbin/semanage" >> $(METADATA)
+	@echo "Requires:        selinux-policy-devel" >> $(METADATA)
+	@echo "Requires:        yum-utils" >> $(METADATA)
+	@echo "Requires:        python3 sqlite" >> $(METADATA)
+	@echo "Provides:        library(selinux-policy/common)" >> $(METADATA)
+	@echo "RhtsRequires:    library(distribution/epel)" >> $(METADATA)
+	@echo "License:         GPLv2" >> $(METADATA)
+	@echo "Destructive:     no" >> $(METADATA)
+	@echo "Environment:     AVC_ERROR=+no_avc_check" >> $(METADATA)
+
+	rhts-lint $(METADATA)
+

diff --git a/selinux-policy/Library/common/lib.sh b/selinux-policy/Library/common/lib.sh
new file mode 100644
index 0000000..e312b9a
--- /dev/null
+++ b/selinux-policy/Library/common/lib.sh
@@ -0,0 +1,1929 @@
+#!/bin/bash
+# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   lib.sh of /CoreOS/selinux-policy/Library/common
+#   Description: Common library for selinux-policy component
+#   Authors: Milos Malik <mmalik@redhat.com>
+#            Michal Trunecka <mtruneck@redhat.com>
+#            David Spurek <dspurek@redhat.com>
+#            Jiri Jaburek <jjaburek@redhat.com>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#   Copyright (c) 2020 Red Hat, Inc. All rights reserved.
+#
+#   This copyrighted material is made available to anyone wishing
+#   to use, modify, copy, or redistribute it subject to the terms
+#   and conditions of the GNU General Public License version 2.
+#
+#   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 Street, Fifth Floor,
+#   Boston, MA 02110-1301, USA.
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#   library-prefix = rlSE
+#   library-version = 40
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+: <<'=cut'
+=pod
+
+=head1 NAME
+
+selinux-policy/common - BeakerLib extension for managing SELinux
+
+=cut
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#   Variables
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+: <<'=cut'
+=pod
+
+=head1 VARIABLES
+
+=over
+
+=item rlSE_CACHE_DIR
+
+Used by sesearch caching for storing the ~90M cache file. Defaults to
+a subdirectory under /var/tmp.
+
+=back
+
+=cut
+
+rlSE_CACHE_DIR="${rlSE_CACHE_DIR:-$__INTERNAL_PERSISTENT_TMP/BEAKERLIB-rlSE}"
+
+__INTERNAL_rlSE_CACHEFILE="$rlSE_CACHE_DIR/cache.db"
+__INTERNAL_rlSE_SUMFILE="$rlSE_CACHE_DIR/cache.policy-checksum"
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#   Functions
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+true <<'=cut'
+=pod
+
+=head1 FUNCTIONS
+
+=head2 rlSESearchRule
+
+Searches for given SELinux rule. Checks if the rule is in the boolean if given. Checks if the rule is in the current policy, if not given other (e.g. mls).
+
+Usage:
+    rlSESearchRule "RULE" [EXP_RESULT] [DESC]
+    rlSESearchRule "RULE [[BOOLEAN]] [POLICY]" [EXP_RESULT] [DESC]
+
+=over
+
+=item EXP_RESULT
+
+Normally expected is '0' but you can the negation using '1'.
+
+=item DESC
+
+
+
+=back
+
+Examples:
+    rlSESearchRule "dontaudit smbd_t etc_conf_t:dir { getattr open }"
+    rlSESearchRule "dontaudit smbd_t etc_conf_t:dir { getattr open } []"
+    rlSESearchRule "allow ftpd_t public_content_rw_t: dir write [ allow_ftpd_anon_write ]"
+    rlSESearchRule "allow ftpd_t public_content_rw_t: dir write [ allow_ftpd_anon_write ] mls"
+    rlSESearchRule "typeattribute httpd_sys_script_exec_t file_type, exec_type"
+    rlSESearchRule "type_transition initrc_t kdumpgui_exec_t : process kdumpgui_t"
+    rlSESearchRule "type_transition authconfig_t etc_t : file bootloader_etc_t zipl.conf"
+    rlSESearchRule "type_transition authconfig_t etc_t : file bootloader_etc_t [] zipl.conf mls"
+
+=cut
+
+rlSELogVar() {
+  [[ -n "$DEBUG" ]] && {
+    echo -n 'eval '
+    while [[ -n "$1" ]]; do
+      echo -n "rlLogDebug \"\$FUNCNAME(): \$(set | grep -P '^$1=')\";"
+      shift
+    done
+  }
+}
+
+rlSESearchRule() {
+
+  if [ -e /var/run/nosesearch ]; then
+     echo "rlSESearchRule disabled by /var/run/nosesearch"
+     return 0
+  fi
+
+  local LF="
+"
+  local result=0
+  local RULE="$(echo "$1" | tr ',:&;' '    ' | tr -s ' ')"
+  local expected_result="${2:-0}"
+  local comment="$3"
+  # TODO: takes ~1 second, abstract to a separate function that remembers
+  #       the version in some __INTERNAL_rlSE_* variable
+  if sesearch --version 2>&1 | grep -q '3.[0123]' ; then
+    local SETOOLS_VER=3
+    local SESEARCH_OPTS='-C'
+  else # setools v.4
+    local SETOOLS_VER=4
+    local SESEARCH_OPTS=''
+  fi
+  rlIsRHEL '<6' && SESEARCH_OPTS="-i -n $SESEARCH_OPTS"
+
+  rlLogInfo "$FUNCNAME: ${comment:-"checking rule '$1'"}"
+
+  `rlSELogVar 'RULE'`
+  # get policy type
+  local POLICY="$__INTERNAL_POLICY_NAME"
+  local POLICY_PATH=''
+  [[ "$RULE" =~ $(echo '(.*)\s+(mls|targeted|minimum|strict)') ]] && {
+    rlLogDebug "$FUNCNAME: POLICY PARSE"; `rlSELogVar 'BASH_REMATCH'`
+    POLICY="${BASH_REMATCH[2]}"
+    RULE="${BASH_REMATCH[1]}"
+    `rlSELogVar 'RULE'`
+    POLICY_PATH="$__INTERNAL_POLICY_ROOT/$POLICY/policy/policy.$(ls -1 -d $__INTERNAL_POLICY_ROOT/$POLICY/policy/policy.* | sed -r 's/[^.]*\.//' | sort -nr | head -n 1)"
+  }
+  `rlSELogVar 'POLICY' 'POLICY_PATH' RULE`
+
+  # check typeattribute rule
+                 #  -   typeattribute  TYPE      ATTR ...
+  [[ "$RULE" =~ $(echo 'typeattribute\s+(\S+)\s+(\S+.*)') ]] && {
+    rlLogDebug "$FUNCNAME(): typeattribute PARSE"; `rlSELogVar 'BASH_REMATCH'`
+    local TYPE="${BASH_REMATCH[1]}"
+    local ATTRIBUTE=( ${BASH_REMATCH[2]} )
+    `rlSELogVar 'TYPE' 'ATTRIBUTE'`
+    local seinfo_out
+    while [[ -n "$ATTRIBUTE" ]]; do
+      rlLogDebug "$FUNCNAME(): EXECUTING seinfo_out=\"\$(seinfo -xa$ATTRIBUTE $POLICY_PATH)\""
+      seinfo_out="$(seinfo -xa$ATTRIBUTE $POLICY_PATH)"
+      if [[ $? -ne 0 ]] ; then
+        rlLogError "$FUNCNAME: seinfo failed"
+        rlLogError "$FUNCNAME: $seinfo_out"
+        let result++
+      fi
+      rlLogDebug "$FUNCNAME(): EXECUTING echo \"\$seinfo_out\" | grep -q \"\<${TYPE}\>\""
+      echo "$seinfo_out" | grep -q "\<${TYPE}\>"
+      rlAssertEquals "${comment:-"check if type '$TYPE' is present in attribute '$ATTRIBUTE' in policy '$POLICY'"}" $? $expected_result || let result++
+      ATTRIBUTE=( "${ATTRIBUTE[@]:1}" )
+    done
+    return $result
+  }
+
+  # check other rules (allow, dontaudit, type_transition)
+
+  # look for conditional boolean
+  local BOOLEAN='.*'
+  [[ "$RULE" =~ $(echo '(.*)(\s+\[(.*)\])(.*)') ]] && {
+    rlLogDebug "$FUNCNAME(): BOOLEAN PARSE"; `rlSELogVar 'BASH_REMATCH'`
+    BOOLEAN=( ${BASH_REMATCH[3]} )
+    RULE="${BASH_REMATCH[1]}${BASH_REMATCH[4]}"
+  }
+  `rlSELogVar 'BOOLEAN' RULE`
+
+  # actually check the rules
+    # T/F  RULETYPE       SCONTEXT  TCONTEXT  CLASS    <PERM|{ PREMs }>
+  [[ "$RULE" =~ $(echo '((T|F)\s+)?(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)') ]] && {
+    rlLogDebug "$FUNCNAME(): RULE PARSE"; `rlSELogVar 'BASH_REMATCH'`
+    local TF="${BASH_REMATCH[2]}"
+    local RULETYPE="${BASH_REMATCH[3]}"
+    local SCONTEXT="${BASH_REMATCH[4]}"
+    local TCONTEXT="${BASH_REMATCH[5]}"
+    local CLASS="${BASH_REMATCH[6]}"
+    local PERM="${BASH_REMATCH[7]}"
+    local TRANS_FILE=''
+    if rlIsRHEL '<6'; then
+    rlLogDebug "$FUNCNAME(): RULE PARSE"; `rlSELogVar 'BASH_REMATCH'`
+      rlLogDebug "$FUNCNAME(): excluding permission 'open'"
+      # for RHEL < 6 ignore open permission as it isnot defined there
+      local PERM=( $(echo "${PERM}" | tr -d '{}' | sed -r 's/\<open\>//g') )
+    else
+      local PERM=( $(echo "${PERM}" | tr -d '{}') )
+    fi
+
+    local SEARCH_RULETYPE="$RULETYPE"
+    [[ "$RULETYPE" == "dontaudit" ]] && rlIsRHEL '<6' && SEARCH_RULETYPE="audit" # dontaudit rules are in --audit rule type
+    if [[ "$RULETYPE" == "type_transition" ]]; then
+      if [[ ${SETOOLS_VER} == "3" ]]; then
+        SEARCH_RULETYPE="type" # type_transition rules are in --type rule type
+      else # setools v.4
+        SEARCH_RULETYPE="type_trans" # type_transition rules are in --type_trans rule type
+      fi
+      if [[ -n "${PERM[1]}" ]] ; then
+        `rlSELogVar 'PERM'`
+        TRANS_FILE="${PERM[1]}"
+        unset PERM[1]
+      fi
+    fi
+    # sesearch v.3 --type covers type_trans, type_member, type_change
+    # sesearch v.4 recognizes 3 different options for ^^^
+    if [[ "$RULETYPE" == "type_change" ]]; then
+      if [[ ${SETOOLS_VER} == "3" ]]; then
+        SEARCH_RULETYPE="type"
+      else # setools v.4
+        SEARCH_RULETYPE="type_change"
+      fi
+      if [[ -n "${PERM[1]}" ]] ; then
+        `rlSELogVar 'PERM'`
+        TRANS_FILE="${PERM[1]}"
+        unset PERM[1]
+      fi
+    fi
+
+    # replace 'self' target context by source context
+    [[ "$TCONTEXT" == "self" ]] && TCONTEXT="$SCONTEXT"
+    `rlSELogVar 'TF' 'RULETYPE' 'SCONTEXT' 'TCONTEXT' 'CLASS' 'PERM' 'TRANS_FILE' 'SEARCH_RULETYPE'`
+
+    # get rules from sesearch
+    local ssearch="sesearch $SESEARCH_OPTS --$SEARCH_RULETYPE -s $SCONTEXT -t $TCONTEXT -c $CLASS $POLICY_PATH"
+    `rlSELogVar ssearch`
+    local RULES=$(eval $ssearch) || let result++
+    [[ -n "$DEBUG" ]] && echo "ALL RULES${LF}$RULES"
+
+    # filter rules specificly for type_transition
+    if [[ -n "$TRANS_FILE" ]]; then
+      # TODO: setools v4.1 quotes all filenames, v4.2 only those with spaces
+      RULES=$(echo "$RULES" | grep -E "\<${TRANS_FILE}\>")
+    fi
+
+    # filter rules according to BOOLEAN
+    if [[ "$BOOLEAN" == "" ]]; then
+      # filter out all rules depending on booleans
+      rlLogDebug "$FUNCNAME(): excluding conditional rules"
+      rlLogDebug "$FUNCNAME(): EXECUTING echo \"\$RULES\" | grep -v '\['"
+      RULES=$(echo "$RULES" | grep -v '\[')
+      rlLogDebug "$FUNCNAME(): RULES${LF}$RULES"
+    elif [[ "$BOOLEAN" != ".*" ]]; then
+      # filter out rules without boolean $BOOLEAN
+      rlLogDebug "$FUNCNAME(): pick only conditional rules using '$BOOLEAN'"
+      while [[ -n "$BOOLEAN" ]]; do
+        BOOLEAN="$(rlSETranslateBoolean "$BOOLEAN")"
+        rlLogDebug "$FUNCNAME(): EXECUTING echo \"\$RULES\" | grep -E \"\[.*\<${BOOLEAN}\>.*\]\""
+        RULES=$(echo "$RULES" | grep -E "\[.*\<${BOOLEAN}\>.*\]")
+        BOOLEAN=( "${BOOLEAN[@]:1}" )
+      done
+      rlLogDebug "$FUNCNAME(): RULES${LF}$RULES"
+      [[ -n "$TF" ]] && {
+        rlLogDebug "$FUNCNAME(): pick only $TF rules"
+        rlLogDebug "$FUNCNAME(): EXECUTING echo \"\$RULES\" | grep -P \"^[ED]$TF\""
+        RULES=$(echo "$RULES" | grep -P "^[ED]$TF")
+        rlLogDebug "$FUNCNAME(): RULES${LF}$RULES"
+      }
+    fi
+    echo "FILTERED RULES${LF}$RULES"
+
+    # loop over permissions
+    while [[ -n "$PERM" ]]; do
+      local SEARCHFOR="\<${RULETYPE}\>.+\<${CLASS}\>.+\<${PERM}\>"
+      `rlSELogVar SEARCHFOR`
+      echo "$RULES" | grep -Eq "$SEARCHFOR"
+      rlAssertEquals "  check permission '$PERM' is present" $? $expected_result || let result++
+      PERM=( "${PERM[@]:1}" )
+    done
+    return $result
+  }
+
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEMatchPathCon
+
+Runs matchpathcon and checks if matchpathcon called on PATH returns context which
+contains the STRING preceeded by colon. The function prints the result of matchpathcon
+anyway.
+
+If variable COLLECTIONS exists, the function will test all collection paths
+containing requested path.
+
+    rlSEMatchPathCon "/var/www/html" "http_sys_content_t"
+
+=cut
+
+
+function rlSEMatchPathCon() {
+
+    if [ -e /var/run/nomatchpathcon ]; then
+        echo "rlSEMatchPathCon disabled by /var/run/nomatchpathcon"
+        return
+    fi
+
+    local FILE_PATH
+    local LINK_PATH
+    local REAL_TYPE=`rlSETranslateAlias $2`
+
+    FILE_PATH=$1
+    if ! rlIsRHEL '<6'; then
+        local CL=( $COLLECTIONS )
+        while [[ -n "$CL" ]]; do
+           local p="/opt/rh/${CL}/root$1"
+           [[ -e "$p" ]] && FILE_PATH=( "${FILE_PATH[@]}" "$p" )
+           CL=( "${CL[@]:1}" )
+        done
+    fi
+
+    local ec=0
+    while [[ -n "$FILE_PATH" ]]; do
+        if [ -L ${FILE_PATH} ] ; then
+            LINK_PATH=`readlink -f ${FILE_PATH}`
+            matchpathcon ${FILE_PATH} ${LINK_PATH}
+            matchpathcon ${FILE_PATH} ${LINK_PATH} | grep :${REAL_TYPE} > /dev/null
+            rlAssert0 "Results of matchpathcon ${FILE_PATH} ${LINK_PATH} should contain ${REAL_TYPE}" $? || ec=1
+        else
+            matchpathcon ${FILE_PATH}
+            matchpathcon ${FILE_PATH} | grep :${REAL_TYPE} > /dev/null
+            rlAssert0 "Result of matchpathcon ${FILE_PATH} should contain ${REAL_TYPE}" $? || ec=1
+        fi
+        FILE_PATH=( "${FILE_PATH[@]:1}" )
+    done
+
+    return $ec
+}
+
+__INTERNAL_rlSEgetsebool() {
+  getsebool $(rlSETranslateBoolean ${1})
+}
+
+
+__INTERNAL_rlSEGetBooleanName() {
+  __INTERNAL_rlSEgetsebool ${1} | cut -d ' ' -f 1
+}
+
+
+#      boolean name  current  persistent
+# returns <BOOLEAN> <on|off> <on|off>
+__INTERNAL_rlSEBooleanState() {
+  local tmp=''
+  local tmp2=''
+  local boolean="$(rlSETranslateBoolean "$1")"
+  tmp="$(paste <(getsebool ${boolean:--a} | sort) <(seinfo -b$boolean -x $__INTERNAL_POLICY_FILE 2>/dev/null | grep -iE 'true|false' | tr 'A-Z' 'a-z' | sed -r 's/\<false\>/off/g;s/\<true\>/on/g' | sort))"
+  rlLogDebug "$FUNCNAME(): $tmp"
+  tmp2="$(echo "$tmp" | sed -r 's/^(\S+).*\<(on|off)\>.*\<(on|off)\>.*/\1 \2 \3/')"
+  rlLogDebug "$FUNCNAME(): $tmp2"
+  while read -r line; do
+    [[ "$line" =~ ^[a-zA-Z_0-9]+\ +(on|off)\ +(on|off)$ ]] || {
+      rlLogError "error parsing boolean info '$line', expected format is BOOLEAN (on|off) (on|off)"
+      rlLogError "  first state is a current state got from getsebool, second state is a persistent state got from seinfo"
+
+    }
+  done <<< "$tmp2"
+  echo "$tmp2"
+}
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSEBooleanBackup
+
+The function to backup both current and default state of all or specified the
+SELinux booleans, which is then restored by rlSEBooleanRestore function.
+
+    rlSEBooleanBackup [--namespace NAMESPACE] [BOOLEAN ...]
+
+=cut
+
+# Usage: rlSEBooleanBackup
+function rlSEBooleanBackup() {
+    local NAMESPACE="$__INTERNAL_rlSE_NAMESPACE"
+
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              NAMESPACE="$1"
+            ;;
+        esac
+        shift
+    done
+
+    local STATUSFILE="$BEAKERLIB_DIR/sebooleans${NAMESPACE}"
+    local res=0
+    if [[ -z "$1" ]]; then
+      if [ -f $STATUSFILE ]; then
+        rlLogError "$FUNCNAME: Backup file already exists. Backing up all the booleans would erase the current backup."
+        return 33
+      fi
+      touch $STATUSFILE
+      rlLog "$FUNCNAME: Backing up the current state of all the SELinux booleans"
+      __INTERNAL_rlSEBooleanState > $STATUSFILE
+      res=$?
+    else
+      # if we didn't save the status yet, save it now
+      local BOOLEAN
+      while [[ -n "$1" ]]; do
+        BOOLEAN="$1"
+        touch "$STATUSFILE"
+        if ! grep -q "^$BOOLEAN " "$STATUSFILE"; then
+          local tmp="$(__INTERNAL_rlSEBooleanState $BOOLEAN)"
+          [[ -n "$tmp" ]] && echo "$tmp" >> "$STATUSFILE" || let res++
+        fi
+        shift
+      done
+    fi
+    return $res
+}
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSEBooleanOn, rlSEBooleanOff
+
+The functions to switch SELinux booleans (current or default value using -P) on/off. When executed for the first time, it remembers the initial status which is restored later on by rlSEBooleanRestore.
+
+    rlSEBooleanOn [--namespace NAMESPACE] [-P] boolean1 [boolean2 ...]
+    rlSEBooleanOff [--namespace NAMESPACE] [-P] boolean1 [boolean2 ...]
+
+=cut
+
+rlSEBooleanOn() {
+	if [ -z "$1" ]; then
+		rlLogError "$FUNCNAME: Missing arguments"
+		return 1
+	fi
+
+    local PERMANENT=''
+    local PERMANENT_MSG=''
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              local __INTERNAL_rlSE_NAMESPACE="$1"
+            ;;
+          -P)
+              PERMANENT=' -P '
+              PERMANENT_MSG=" permanently"
+            ;;
+        esac
+        shift
+    done
+
+	if [ -z "$1" ]; then
+		rlLogError "$FUNCNAME: Missing arguments"
+		return 1
+	fi
+
+	local new_states=''
+
+	local FAILURES=0
+	rlLog "$FUNCNAME: Setting SELinux booleans$PERMANENT_MSG on: $*"
+	while [ -n "$1" ]; do
+		local BOOLEAN=$(__INTERNAL_rlSEGetBooleanName "$1")
+		[[ -z "$BOOLEAN" ]] && {
+			rlLogError "$FUNCNAME: boolean name '$1' not found."
+			FAILURES=$(( $FAILURES + 1 ))
+			shift
+			continue
+		}
+		[[ "$1" != "$BOOLEAN" ]] && {
+			rlLogInfo "$FUNCNAME: using boolean name '$BOOLEAN' instead of '$1'"
+		}
+		# backup current state
+		if ! rlSEBooleanBackup "$BOOLEAN"; then
+			FAILURES=$(( $FAILURES + 1 ))
+			rlLogError "$FUNCNAME: Backing up the $BOOLEAN boolean failed"
+		fi
+
+		new_states+="$BOOLEAN=on "
+		shift
+	done
+
+	[[ -n "$new_states" ]] && {
+	  setsebool $PERMANENT $new_states || {
+		FAILURES=$(( $FAILURES + 1 ))
+		rlLogError "$FUNCNAME: Setting boolean(s) to true failed"
+	  }
+	}
+	return $FAILURES
+}
+
+rlSEBooleanOff() {
+	if [ -z "$1" ]; then
+		rlLogError "$FUNCNAME: Missing arguments"
+		return 1
+	fi
+
+    local PERMANENT=''
+    local PERMANENT_MSG=''
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              local __INTERNAL_rlSE_NAMESPACE="$1"
+            ;;
+          -P)
+              PERMANENT=' -P '
+              PERMANENT_MSG=" permanently"
+            ;;
+        esac
+        shift
+    done
+
+
+	if [ -z "$1" ]; then
+		rlLogError "$FUNCNAME: Missing arguments"
+		return 1
+	fi
+
+	local new_states=''
+
+	local FAILURES=0
+	rlLog "$FUNCNAME: Setting SELinux booleans$PERMANENT_MSG off: $*"
+
+	while [ -n "$1" ]; do
+
+		local BOOLEAN=$(__INTERNAL_rlSEGetBooleanName "$1")
+		[[ -z "$BOOLEAN" ]] && {
+			rlLogError "$FUNCNAME: boolean name '$1' not found."
+			FAILURES=$(( $FAILURES + 1 ))
+			shift
+			continue
+		}
+		[[ "$1" != "$BOOLEAN" ]] && {
+			rlLogInfo "$FUNCNAME: using boolean name '$BOOLEAN' instead of '$1'"
+		}
+		# backup current state
+		if ! rlSEBooleanBackup "$BOOLEAN"; then
+			FAILURES=$(( $FAILURES + 1 ))
+			rlLogError "$FUNCNAME: Backing up the $BOOLEAN boolean failed"
+		fi
+
+		new_states+="$BOOLEAN=off "
+		shift
+	done
+
+	[[ -n "$new_states" ]] && {
+	  setsebool $PERMANENT $new_states || {
+		FAILURES=$(( $FAILURES + 1 ))
+		rlLogError "$FUNCNAME: Setting boolean(s) to false failed"
+	  }
+	}
+	return $FAILURES
+}
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSEBooleanRestore
+
+Restores the original state of SELinux boolean(s) backed up by rlSEBooleanOn/Off
+or rlSEBooleanBackup - all backed up booleans if none specified.
+If there was no boolean backed up; either by rlSEBooleanOn/Off or
+rlSEBooleanBackup the function logs an error and returns code 99.
+
+    rlSEBooleanRestore [--namespace NAMESPACE] [boolean1 ...]
+
+=cut
+
+function rlSEBooleanRestore() {
+    local NAMESPACE='' tmp
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              NAMESPACE="$1"
+            ;;
+        esac
+        shift
+    done
+
+	local FAILURES=0
+    if [ ! -f $BEAKERLIB_DIR/sebooleans${NAMESPACE} ]; then
+        rlLogError "$FUNCNAME: cannot restore SELinux booleans, saved states are not available"
+        return 99
+    fi
+
+    local STATUSFILE="$(cat $BEAKERLIB_DIR/sebooleans${NAMESPACE})"
+
+    local CHANGED_BOOLEANS=''
+    local CURRENT_STATES=''
+    local persistent_states=''
+    local current_states=''
+    local BOOLEAN
+
+    # populate booleans list and current states
+    if [ -z "$1" ]; then # no booleans specified, restoring all booleans
+        rlLog "$FUNCNAME: restoring all backed up SELinux booleans"
+        CURRENT_STATES="$(__INTERNAL_rlSEBooleanState)"
+        CHANGED_BOOLEANS="$(diff <( echo "$STATUSFILE" ) <( echo "$CURRENT_STATES" ) | grep '<' | sed 's/< //' | awk '{ print $1 }')"
+    else      # restoring only specified booleans
+        rlLog "$FUNCNAME: restoring original status of SELinux booleans: $*"
+        while [ -n "$1" ]; do # process all passed booleans
+            BOOLEAN=$(__INTERNAL_rlSEGetBooleanName "$1")
+            [[ -z "$BOOLEAN" ]] && {
+              let FAILURES++
+              rlLogError "$FUNCNAME: cannot restore SELinux boolean $1, which does not exist!"
+              shift
+              continue
+            }
+            rlLogDebug "$FUNCNAME(): using actual boolean name '$BOOLEAN'"
+            CURRENT_STATES+="$(__INTERNAL_rlSEBooleanState $BOOLEAN)"$'\n'
+            CHANGED_BOOLEANS+="$BOOLEAN"$'\n'
+            shift
+        done
+    fi
+
+    # create lists of pesistent and current states to restore
+    while read BOOLEAN; do
+        [[ -z "$BOOLEAN" ]] && continue
+        `rlSELogVar BOOLEAN`
+        tmp="\<${BOOLEAN} (\S+) (\S+)"
+        if ! [[ "$STATUSFILE" =~ $tmp ]]; then
+          let FAILURES++
+          rlLogError "$FUNCNAME: cannot restore SELinux boolean $BOOLEAN, original state was not saved"
+          shift
+          continue
+        fi
+        BACKUP_STATE="${BASH_REMATCH[1]}"
+        BACKUP_DEFAULT_STATE="${BASH_REMATCH[2]}"
+        `rlSELogVar BASH_REMATCH BACKUP_STATE BACKUP_DEFAULT_STATE`
+        if ! [[ "$CURRENT_STATES" =~ $tmp ]]; then
+          let FAILURES++
+          rlLogError "$FUNCNAME: cannot restore SELinux boolean $BOOLEAN, current state not available"
+          shift
+          continue
+        fi
+        CURRENT_STATE="${BASH_REMATCH[1]}"
+        CURRENT_DEFAULT_STATE="${BASH_REMATCH[2]}"
+        `rlSELogVar BASH_REMATCH CURRENT_STATE CURRENT_DEFAULT_STATE`
+
+        if [[ "$CURRENT_DEFAULT_STATE" != "$BACKUP_DEFAULT_STATE" ]]; then
+          persistent_states+="$BOOLEAN=$BACKUP_DEFAULT_STATE "
+          current_states+="$BOOLEAN=$BACKUP_STATE "
+          CURRENT_STATE=$BACKUP_DEFAULT_STATE
+        fi
+        if [[ "$CURRENT_STATE" != "$BACKUP_STATE" ]]; then
+          current_states+="$BOOLEAN=$BACKUP_STATE "
+        fi
+    done <<< "$CHANGED_BOOLEANS"
+
+    # do the actual restoration
+    [[ -n "$persistent_states" ]] && {
+      rlLogInfo "$FUNCNAME: restoring boolean persistent states"
+      rlLogDebug "$FUNCNAME(): $persistent_states"
+      setsebool -P $persistent_states || {
+        let FAILURES++
+        rlLogError "$FUNCNAME: setting boolean(s) failed"
+      }
+    }
+    [[ -n "$current_states" ]] && {
+      rlLogInfo "$FUNCNAME: restoring boolean current states"
+      rlLogDebug "$FUNCNAME(): $current_states"
+      setsebool $current_states || {
+        let FAILURES++
+        rlLogError "$FUNCNAME: setting boolean(s) failed"
+      }
+    }
+    return $FAILURES
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEMatchPortCon
+
+Runs seinfo and checks if a SELinux port of type $1 (tcp/udp) and of number $2 is known under context type $3.  Required parameters and their order: port type, port number, SELinux context type.
+
+    rlSEMatchPortCon PROTO NUMBER TYPE
+    rlSEMatchPortCon tcp 80 "http_port_t"
+
+=cut
+
+
+function rlSEMatchPortCon() {
+
+    if [ -e /var/run/nomatchportcon ]; then
+        echo "rlSEMatchPortCon disabled by /var/run/nomatchportcon"
+        return
+    fi
+
+    if ! seinfo --version | grep -q '3.[0123]' ; then
+        # setools v.4
+        rlRun "seinfo --portcon=$2 | grep \"portcon $1 .*:$3\""
+    elif rlIsRHEL 5 ; then
+        rlRun "seinfo -l$1 -p$2 | grep \"portcon.*:$3\""
+    else
+        rlRun "seinfo --protocol=$1 --portcon=$2 | grep \"portcon.*:$3\""
+    fi
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEPortAdd
+
+# Add context type to given port if not in the current policy. The current state of the port contexts is backed up and can be restored by rlSEPortRestore.
+
+    rlSEPortAdd PROTO NUMBER CONTEXT_TYPE
+
+=cut
+
+function rlSEPortAdd() {
+    local RES
+    local NAMESPACE=''
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              NAMESPACE="_$1"
+            ;;
+        esac
+        shift
+    done
+
+    if ! seinfo --version | grep -q '3.[0123]' ; then
+        # setools v.4
+        seinfo --portcon=$2 | grep "portcon $1 .*:$3"
+        RES=$?
+    elif rlIsRHEL 5 ; then
+        seinfo -l$1 -p$2 | grep "portcon $1 $2 .*:$3"
+        RES=$?
+    else
+        seinfo --protocol=$1 --portcon=$2 | grep "portcon $1 .*$2.*:$3"
+        RES=$?
+    fi
+
+    if [ $RES -eq 0 ]; then
+        rlLog "$FUNCNAME: The type $3 of $1 port $2 already in policy"
+    else
+
+        if ! seinfo --version | grep -q '3.[0123]' ; then
+            # setools v.4
+            seinfo --portcon=$2 | grep "portcon $1 \<$2\>"
+            RES=$?
+        elif rlIsRHEL 5 ; then
+            seinfo -l$1 -p$2 | grep 'portcon $1 \<$2\>'
+            RES=$?
+        else
+            seinfo --protocol=$1 --portcon=$2 | grep "portcon $1 \<$2\>"
+            RES=$?
+        fi
+
+        local CHANGED_PORT_CONTEXTS="$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} rlSE_CHANGED_PORT_CONTEXTS)"
+
+        if [ $RES -eq 0 ]; then
+            rlLog "$FUNCNAME: Setting context type $3 to $1 port $2"
+            rlRun "semanage port -m -t $3 -p $1 $2"
+            if [ $? -eq 0 ]; then
+                CHANGED_PORT_CONTEXTS="$CHANGED_PORT_CONTEXTS $1:$2:$3"
+            fi
+        else
+            rlLog "$FUNCNAME: Setting context type $3 to $1 port $2"
+            rlRun "semanage port -a -t $3 -p $1 $2"
+            if [ $? -eq 0 ]; then
+                CHANGED_PORT_CONTEXTS="$CHANGED_PORT_CONTEXTS $1:$2:$3"
+            fi
+        fi
+        __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} rlSE_CHANGED_PORT_CONTEXTS "$CHANGED_PORT_CONTEXTS"
+    fi
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEPortRestore
+
+# Rollbacks port contexts set by rlSEPortAdd function. Restore all if not specified.
+
+    rlSEPortRestore
+
+=cut
+
+function rlSEPortRestore() {
+    local ITEM
+    local TYPE
+    local PROTO
+    local PORT
+    local NEWLIST
+    local NAMESPACE=''
+    while [[ "${1:0:1}" == "-" ]]; do
+        case $1 in
+          --namespace)
+              shift
+              NAMESPACE="_$1"
+            ;;
+        esac
+        shift
+    done
+    local CHANGED_PORT_CONTEXTS=$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} rlSE_CHANGED_PORT_CONTEXTS)
+
+    if [ ! $# -lt 1 ]; then
+        NEWLIST=""
+        for ITEM in $CHANGED_PORT_CONTEXTS; do
+            if [ $ITEM == "$1:$2:$3" ]; then
+                rlLog "$FUNCNAME: Removing context type $3 to $1 port $2"
+                rlRun "semanage port -d -t $3 -p $1 $2"
+            else
+                NEWLIST="$NEWLIST $ITEM"
+            fi
+        done
+        CHANGED_PORT_CONTEXTS=$NEWLIST
+
+    else
+
+        for ITEM in $CHANGED_PORT_CONTEXTS; do
+            TYPE=`echo $ITEM | cut -f 3 -d ':'`
+            PROTO=`echo $ITEM | cut -f 1 -d ':'`
+            PORT=`echo $ITEM | cut -f 2 -d ':'`
+            rlLog "$FUNCNAME: Removing context type $TYPE to $PROTO port $PORT"
+            rlRun "semanage port -d -t $TYPE -p $PROTO $PORT"
+
+        done
+        CHANGED_PORT_CONTEXTS=""
+    fi
+    __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} rlSE_CHANGED_PORT_CONTEXTS "$CHANGED_PORT_CONTEXTS"
+}
+
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSESetTimestamp, rlSECheckAVC, rlSEAVCCheck
+
+Pair functions to check AVC messages from the given moment. The starting timestamps can be named to be able to mark more than one moment.
+
+    # Beginning of the phase/test:
+    rlSESetTimestamp [timestamp_name]
+
+    # End of the phase/test, count only unignored AVCs/ERRORs:
+    rlSECheckAVC [--no-ignore] [--ignore REG_EXP [--ignore REG_EXP]] [timestamp_name]
+
+    # or check without assert, prints number of unignored and unexpected AVCs/ERRORs, returns 0 if no unignored AVC/ERROR found:
+    rlSEAVCCheck [--no-ignore] [--ignore REG_EXP [--ignore REG_EXP]] [--expect REG_EXP [--expect REG_EXP]] [timestamp_name]
+
+=cut
+
+function rlSESetTimestamp() {
+
+    local STAMP=`date "+%m/%d/%Y %T"`
+    local NAME="TIMESTAMP"
+
+    [ -z "$1" ] || NAME="${NAME}_$1"
+    eval "export __INTERNAL_rlSE_$NAME='$STAMP'"
+    rlLog "$FUNCNAME: Setting timestamp '$NAME' [$STAMP]"
+
+}
+
+function rlSECheckAVC() {
+
+    rlSEAVCCheck "$@" > /dev/null
+    rlAssert0 'Check there are no unexpected AVCs/ERRORs' $?
+
+}
+
+function rlSEAVCCheck() {
+    local NAME="TIMESTAMP"
+    local ignore=('type=USER_AVC.*received (policyload|setenforce) notice')
+    local ignore_internal='type=(SYSCALL|PATH|CWD|PROCTITLE|SOCKETCALL|OBJ_PID|SOCKADDR)'
+    local expect
+    rlLogDebug "$FUNCNAME(): process options"
+    local GETOPT=$(getopt -q -o ni:e: -l no-ignore,ignore:,expect:,expected: -- "$@")
+    eval set -- "$GETOPT"
+    while [[ -n "$@" ]]; do
+      case $1 in
+      --)
+        shift; break
+        ;;
+      -n|--no-ignore)
+        ignore=()
+        ;;
+      -i|--ignore)
+        shift
+        ignore+=("$1")
+        ;;
+      -e|--expect|--expected)
+        shift
+        expect+=("$1")
+        ;;
+      *)
+        echo "unknown option '$1'"
+        return 1
+        ;;
+      esac
+      shift;
+    done
+
+    [ -z "$1" ] || NAME="${NAME}_$1"
+
+    local STAMP
+    eval "STAMP=\"\$__INTERNAL_rlSE_$NAME\""
+    `rlSELogVar expect ignore ignore_internal STAMP`
+    if [ -z "$STAMP" ]; then
+        rlLogError "$FUNCNAME: Timestamp $NAME is not defined"
+        return 1
+    else
+        rlLog "$FUNCNAME: Search for AVCs, USER_AVCs, SELINUX_ERRs, and USER_SELINUX_ERRs since timestamp '$NAME' [$STAMP]"
+        local ausearch_output=$(LC_TIME='en_US.UTF-8' ausearch -i -m AVC -m USER_AVC -m SELINUX_ERR -m USER_SELINUX_ERR -ts $STAMP 2>&1)
+        echo "$ausearch_output" >&2
+        local res=0
+        # filter out ignored patterns
+        [[ -n "${ignore[*]}" ]] && {
+          rlLogInfo "$FUNCNAME: ignoring patterns:"
+          local i
+          for i in "${ignore[@]}"; do
+            rlLogInfo "$FUNCNAME:     $i"
+            ignore_internal="$ignore_internal|$i"
+          done
+        }
+        rlLogDebug "$FUNCNAME(): filter out ignored patterns"
+        ausearch_output="$(echo "$ausearch_output" | grep -Pi '^type=' | grep -vP "$ignore_internal")"
+        `rlSELogVar ausearch_output`
+        # find expected and filter then out; if not found, count them
+        local exp
+        [[ -n "${expect[*]}" ]] && rlLogInfo "$FUNCNAME: looking for expected patterns:"
+        for exp in "${expect[@]}" ; do
+          if echo "$ausearch_output" | grep -qP "$exp" ; then
+            rlLogInfo    "$FUNCNAME:     ok   ... $exp"
+            ausearch_output="$(echo "$ausearch_output" | grep -vP "$exp")"
+          else
+            rlLogWarning "$FUNCNAME:     fail ... $exp"
+            let res++
+          fi
+        done
+        `rlSELogVar res ausearch_output`
+        # count the rest
+        if [[ -n "$ausearch_output" ]] ; then
+          let res+=$(echo "$ausearch_output" | wc -l)
+          echo "---==============---" >&2
+          echo "UNEXPECTED MESSAGES:" >&2
+          echo "$ausearch_output" >&2
+          echo "---==============---" >&2
+        fi
+        `rlSELogVar res`
+
+        echo "$res"
+        [[ "$res" -eq 0 ]]
+        return $?
+    fi
+
+}
+
+
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSEIsMLS, rlSEIsTargeted, rlSEIsStrict, rlSEIsMinimum
+
+The functions to check if desired policy is active at the moment. Returns 0 if true.
+
+=cut
+
+
+# tests whether MLS policy is used
+function rlSEIsMLS() {
+    sestatus | grep -qi mls$
+}
+
+
+# tests whether targeted policy is used
+function rlSEIsTargeted() {
+    sestatus | grep -qi targeted$
+}
+
+
+# tests whether strict policy is used
+function rlSEIsStrict() {
+    sestatus | grep -qi strict$
+}
+
+
+# tests whether minimum policy is used
+function rlSEIsMinimum() {
+    sestatus | grep -qi minimum$
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEDefined
+
+The functions to check if given types exist in the current policy and returns 0 if true.
+
+    rlSEDefined httpd_t snmpd_t
+=cut
+
+
+# Searches for all the types given in the argument and returns 0 if all
+# of them exist. Returns 1 otherwise.
+function rlSEDefined() {
+    local RET_VAL=0
+    local TYPE
+
+    for TYPE in $1 ; do
+        # there are also type aliases in RHEL-7
+        if seinfo -t$TYPE 2>&1 | grep -qi -e error -e 'types: 0' ; then
+            echo "$TYPE is NOT defined"
+            RET_VAL=1
+        else
+            echo "$TYPE is defined"
+        fi
+    done
+
+    return $RET_VAL;
+}
+
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSEStatus
+
+Prints various SELinux information
+
+   rlSEStatus                 # prints sestatus results
+   rlSEStatus -b [regexp]     # prints all/selected booleans (from getsebool)
+   rlSEStatus -p [regexp]     # prints all/selected ports (from semanage port -l)
+   rlSEStatus -m [regexp]     # prints all/selected selinux modules (from semodule -l)
+   rlSEStatus -em [regexp]    # prints all/selected enabled selinux modules
+   rlSEStatus -dm [regexp]    # prints all/selected disabled selinux modules
+   rlSEStatus -t [regexp]     # prints all/selected context types (from seinfo -t)
+
+=cut
+
+function rlSEStatus() {
+
+    # -b parameter - print booleans
+    if [ "$1" = "-b" ]; then
+        rlRun "getsebool -a | grep \"$2\""
+        return;
+    fi
+
+    # -p parameter - print ports
+    if [ "$1" = "-p" ]; then
+        rlRun "semanage port -l | grep \"$2\""
+        return;
+    fi
+
+    # -m parameter - print selinux modules
+    if [ "$1" = "-m" ]; then
+        rlRun "semodule -l | grep \"$2\""
+        return;
+    fi
+
+    # -em parameter - print enabled selinux modules
+    if [ "$1" = "-em" ]; then
+        rlRun "semodule -l | grep -v -i disabled | grep \"$2\""
+        return;
+    fi
+
+    # -dm parameter - print disabled selinux modules
+    if [ "$1" = "-dm" ]; then
+        rlRun "semodule -l | grep -i disabled | grep \"$2\""
+        return;
+    fi
+
+    # -t parameter - print types
+    if [ "$1" = "-t" ]; then
+        rlRun "seinfo -t | grep \"$2\""
+        return;
+    fi
+
+    # Without any params - run sestatus
+    rlRun "id -Z"
+    rlRun "sestatus"
+    if semodule --help | grep -qi "list-modules.*kind" ; then
+        rlRun "semodule --list-modules=full | grep -i disabled" 0,1
+    else
+        rlRun "semodule -l | grep -i disabled" 0,1
+    fi
+}
+
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSERunWithPassword
+
+The function executes given command and provides the password whenever prompted for password.
+The password can be either stored in PASSWORD global variable or specified using -p parameter.
+
+    rlSERunWithPassword [ -p PASSWORD ] COMMAND
+
+=cut
+
+function rlSERunWithPassword() {
+
+  local PASS="$PASSWORD"
+  # read password parameter
+  if [ "$1" = "-p" ]; then
+      PASS="$2"
+      shift 2
+  fi
+
+  cat <<EOF | expect -
+set timeout 5
+spawn $*
+expect {
+  -re "assword:" { send "$PASS\r"; exp_continue }
+}
+EOF
+
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEService
+
+Runs given service using run_init tool and checks the context of the running process.
+
+Usage:
+    rlSEService ${ROOT_PASSWORD} ${SERVICE_NAME} ${PROCESS_NAME} ${PROCESS_CONTEXT} ${OPERATIONS}
+
+Example:
+    rlSEService "root_passwd" "httpd" "httpd" "httpd_t" "start status stop status"
+
+=cut
+
+
+function rlSEService() {
+    local OPERATION
+    local RET_VAL
+    local REAL_TYPE
+
+    for OPERATION in $5; do
+
+        # Set the return value
+        # Service status can return both 0 and 3
+        if echo $OPERATION | grep -q status; then
+            RET_VAL=0,1,3
+        else
+            RET_VAL=0
+        fi
+
+        # Run the service using run_init tool
+        #rlRun "echo $1 | run_init service $2 $OPERATION" $RET_VAL
+        if rlIsRHEL 5 6 ; then
+            if rlSEIsMLS ; then
+                rlRun "rlSERunWithPassword -p $1 run_init service $2 $OPERATION" $RET_VAL
+            elif rlSEIsStrict ; then
+                rlRun "rlSERunWithPassword -p $1 run_init service $2 $OPERATION" $RET_VAL
+            else
+                rlRun "service $2 $OPERATION" $RET_VAL
+            fi
+        else
+            rlRun "service $2 $OPERATION" $RET_VAL
+        fi
+
+        REAL_TYPE=`rlSETranslateAlias $4`
+        # Check context of the service process
+        if echo $OPERATION | grep -q -e start -e reload ; then
+            sleep $6
+            if [ "$3" != "-" ] ; then
+                rlRun "ps -efZ | grep -v \" grep \" | grep -E \"$3\""
+                rlRun "ps -efZ | grep -v \" grep \" | grep -E \"${REAL_TYPE}.*$3\""
+            fi
+        fi
+
+        # Wait given number of seconds
+        if [ ! -z $6 ]; then
+            sleep $6
+        fi
+
+    done
+}
+
+
+function rlSETransAndRun() {
+  local TMPDIR
+  local SELINUX_TYPE
+  local CURRENT_CONTEXT
+
+  if [ -f testpolicy.te ] ; then
+    rlLog "$FUNCNAME: using a predefined local policy for the test"
+    rlRun "ls -l testpolicy.*"
+    rlRun "make -f /usr/share/selinux/devel/Makefile testpolicy.pp"
+    rlRun "semodule -i testpolicy.pp"
+    rm -rf tmp # by-product of the local policy module compilation
+  else
+    TMPDIR=`mktemp -d`
+    SELINUX_TYPE=`echo $1 | cut -d : -f 3`
+    CURRENT_CONTEXT=`id -Z`
+    rlLog "$FUNCNAME: preparing a local policy which allows transition from $CURRENT_CONTEXT to $1"
+    pushd ${TMPDIR}
+    echo -e "policy_module(testpolicy,1.0)\n\nrequire {\n  type unconfined_t;  type $SELINUX_TYPE;\n  class process { transition };\n}\n\nallow unconfined_t $SELINUX_TYPE : process { transition };\n" > testpolicy.te
+    rlRun "make -f /usr/share/selinux/devel/Makefile"
+    rlRun "semodule -i testpolicy.pp"
+    popd
+    rm -rf ${TMPDIR}
+  fi
+  rlRun "runcon $1 bash -c \"$2\""
+  rlRun "semodule -r testpolicy"
+}
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSERunWithContext
+
+Executes command with a given context. There has to be transition allowed from initrc_exec_t to a desired context available.
+
+    rlSERunWithContext [-u USER] [-r ROLE] [-t TYPE] cmd
+    e.g. rlRun "rlSERunWithContext -t smbd_exec_t stat $TmpDir/testmount"
+
+=cut
+
+
+# OPTIONS are supposed to be passed to chcon command
+function rlSERunWithContext() {
+    local TMPDIR
+    local OPTIONS
+    local COMMAND
+    local RETCODE
+
+    #read and store options
+    while [ "${1:0:1}" = "-" ]; do
+        OPTIONS+=" $1 $2"
+        shift 2
+    done
+    if [ -z "$1" ]; then
+        rlLogError "$FUNCNAME: No command passed to rlRunWithSELinuxContext"
+        return 99
+    else
+        COMMAND=$@ # store command with arguments
+    fi
+
+    TMPDIR=`mktemp -d`
+    chcon -t smbd_tmp_t $TMPDIR
+
+    #prepare launcher scripts - one with initrc_exec_t and other with desired context
+    echo -e "#!/bin/bash\n$TMPDIR/launcher2.sh\n" > $TMPDIR/launcher1.sh
+    echo -e "#!/bin/bash\n$COMMAND" > $TMPDIR/launcher2.sh
+    chcon -t initrc_exec_t $TMPDIR/launcher1.sh
+    chcon $OPTIONS $TMPDIR/launcher2.sh
+    chmod a+x $TMPDIR/*.sh
+    #cat $TMPDIR/launcher1.sh
+    #cat $TMPDIR/launcher2.sh
+
+    $TMPDIR/launcher1.sh # execute the first launcher script
+    RETCODE=$?
+
+    rm -rf $TMPDIR
+    return $RETCODE
+
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSETranslateBoolean
+
+Some booleans were renamed during the time, but already written tests contain
+boolean names which may not be current. The function takes a boolean name as an argument.
+When executed on RHEL-5 or RHEL-6 the function returns old boolean name.
+When executed on RHEL >= 7 the function returns new boolean name.
+If the boolean was not renamed then the same boolean is returned.
+
+    rlSETranslateBoolean BOOL_NAME
+
+=cut
+
+function rlSETranslateBoolean() {
+    local FIELD LINE RENAMED_BOOLEANS
+
+    if rlIsRHEL 5 > /dev/null 2>&1; then
+        FIELD=2
+    elif rlIsRHEL 6  > /dev/null 2>&1; then
+        if [[ $1 == "clamscan_can_scan_system" ]] ||
+           [[ $1 == "antivirus_can_scan_system" ]] ||
+           [[ $1 == "amavis_use_jit" ]] ||
+           [[ $1 == "clamd_use_jit" ]] ||
+           [[ $1 == "antivirus_use_jit" ]] ; then
+            FIELD=1
+        else
+            FIELD=2
+        fi
+    else
+        FIELD=1
+    fi
+
+    RENAMED_BOOLEANS="
+    antivirus_can_scan_system clamscan_can_scan_system
+    antivirus_use_jit amavis_use_jit
+    antivirus_use_jit clamd_use_jit
+    auditadm_exec_content allow_auditadm_exec_content
+    condor_tcp_network_connect condor_domain_can_network_connect
+    cvs_read_shadow allow_cvs_read_shadow
+    daemons_dump_core allow_daemons_dump_core
+    daemons_use_tcp_wrapper allow_daemons_use_tcp_wrapper
+    daemons_use_tty allow_daemons_use_tty
+    domain_fd_use allow_domain_fd_use
+    ftpd_anon_write allow_ftpd_anon_write
+    ftpd_full_access allow_ftpd_full_access
+    ftpd_use_cifs allow_ftpd_use_cifs
+    ftpd_use_nfs allow_ftpd_use_nfs
+    gssd_read_tmp allow_gssd_read_tmp
+    guest_exec_content allow_guest_exec_content
+    httpd_anon_write allow_httpd_anon_write
+    httpd_mod_auth_ntlm_winbind allow_httpd_mod_auth_ntlm_winbind
+    httpd_mod_auth_pam allow_httpd_mod_auth_pam
+    httpd_sys_script_anon_write allow_httpd_sys_script_anon_write
+    icecast_use_any_tcp_ports icecast_connect_any
+    kerberos_enabled allow_kerberos
+    login_console_enabled allow_console_login
+    logwatch_can_network_connect_mail logwatch_can_sendmail
+    mount_anyfile allow_mount_anyfile
+    mplayer_execstack allow_mplayer_execstack
+    named_tcp_bind_http_port named_bind_http_port
+    nfsd_anon_write allow_nfsd_anon_write
+    nis_enabled allow_ypbind
+    polyinstantiation_enabled allow_polyinstantiation
+    postfix_local_write_mail_spool allow_postfix_local_write_mail_spool
+    postgresql_can_rsync sepgsql_enable_pitr_implementation
+    postgresql_selinux_transmit_client_label sepgsql_transmit_client_label
+    postgresql_selinux_unconfined_dbadm sepgsql_unconfined_dbadm
+    postgresql_selinux_users_ddl sepgsql_enable_users_ddl
+    puppetagent_manage_all_files puppet_manage_all_files
+    rsync_anon_write allow_rsync_anon_write
+    saslauthd_read_shadow allow_saslauthd_read_shadow
+    secadm_exec_content allow_secadm_exec_content
+    selinuxuser_direct_dri_enabled user_direct_dri
+    selinuxuser_execheap allow_execheap
+    selinuxuser_execmod allow_execmod
+    selinuxuser_execstack allow_execstack
+    selinuxuser_mysql_connect_enabled allow_user_mysql_connect
+    selinuxuser_ping user_ping
+    selinuxuser_postgresql_connect_enabled allow_user_postgresql_connect
+    selinuxuser_rw_noexattrfile user_rw_noexattrfile
+    selinuxuser_share_music user_share_music
+    selinuxuser_tcp_server user_tcp_server
+    smbd_anon_write allow_smbd_anon_write
+    ssh_keysign allow_ssh_keysign
+    staff_exec_content allow_staff_exec_content
+    sysadm_exec_content allow_sysadm_exec_content
+    user_exec_content allow_user_exec_content
+    xguest_exec_content allow_xguest_exec_content
+    xserver_clients_write_xshm allow_write_xshm
+    xserver_execmem allow_xserver_execmem
+    zebra_write_config allow_zebra_write_config
+    "
+
+    LINE="$(echo "${RENAMED_BOOLEANS}" | grep -E -- "\<${1}\>")"
+    if [ $? -eq 0 ] ; then
+        echo $LINE | cut -d ' ' -f ${FIELD}
+    else
+        echo $1
+    fi
+
+    return 0
+}
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSETranslateAlias
+
+If first parameter is an alias then the function returns the real type.
+If first parameter is a real type then the function returns the real type.
+Limitation: seinfo does not report aliases on RHEL-5 and RHEL-6 now.
+
+    rlSETranslateAlias ALIAS
+
+=cut
+
+function rlSETranslateAlias {
+    if rlIsRHEL 5 ; then
+        echo $1
+        return 0
+    elif rlIsRHEL 6 ; then
+        if seinfo -t$1 2>&1 | grep -q "ERROR:" ; then
+            echo $1
+            return 1
+        elif seinfo -t$1 2>&1 | grep -q " $1" ; then
+            echo $1
+            return 0
+        else # the type should be used either as a source or as a target in an allow rule
+            ( sesearch -s $1 -A | tr -s ' ' | cut -d ' ' -f 3 ; sesearch -t $1 -A | tr -s ' ' | cut -d ' ' -f 4 ) | sort | uniq | grep "^.*_t$"
+            return 0
+        fi
+    else
+        local seinfo_out
+        seinfo_out="$(seinfo -t$1 2>&1 )"
+        if echo "$seinfo_out" | grep -q "ERROR:" ; then
+            # the type was not recognized
+            echo $1
+            return 1
+        elif echo "$seinfo_out" | grep -q "TypeName " ; then
+            seinfo -t$1 2>/dev/null | grep TypeName | tr -s ' ' | cut -d ' ' -f 3
+            return 0
+        elif echo "$seinfo_out" | grep -q "Types: 0" ; then
+            # cannot translate alias, if setools v.4 are used then BZ#1581761
+            echo $1
+            return 1
+        elif seinfo --version | grep -q ^4 ; then
+            # setools v.4
+            seinfo -t$1 2>/dev/null | tail -n 1 | tr -s ' ' | cut -d ' ' -f 2
+            return 0
+        else
+            # setools v.3
+            seinfo -t$1 2>/dev/null | head -n 1 | tr -s ' ' | cut -d ' ' -f 2
+            return 0
+        fi
+    fi
+}
+
+true <<'=cut'
+=pod
+
+=head2 rlSEListServices
+
+There are many services which by default run on the same port.
+The function returns a list of such services which run on given port.
+Otherwise the function returns an empty list.
+
+=cut
+
+function rlSEListServices() {
+    local SERVICES_ARRAY
+
+    if [ $1 -lt 1 -o $1 -gt 65535 ] ; then
+        rlLogError "$FUNCNAME: invalid port number"
+        return 1
+    fi
+
+    SERVICES_ARRAY[21]='vsftpd proftpd pure-ftpd lighttpd' # FTP servers
+    SERVICES_ARRAY[25]='exim postfix sendmail' # SMTP servers
+    SERVICES_ARRAY[53]='named named-sdb unbound yadifad nsd pdns' # DNS servers
+    SERVICES_ARRAY[80]='httpd cherokee lighttpd nginx thttpd' # HTTP servers
+    SERVICES_ARRAY[123]='ntpd chronyd' # NTP servers
+
+    echo -n ${SERVICES_ARRAY[$1]}
+    return 0
+}
+
+
+
+true <<'=cut'
+=pod
+
+=head2 rlSESetEnforce
+
+The functions sets selinux mode to Enforcing unless env. variable ENFORCING is set to 0. Then,
+the permissive mode is set. Moreover, when the test is running in permissive mode, the function
+thrown a WARN.
+
+=cut
+
+function rlSESetEnforce() {
+
+    if [ "x$ENFORCING" != "x0" ]; then
+        ENFORCING=1
+    fi
+
+    rlRun "setenforce $ENFORCING"
+
+    getenforce | grep Permissive && rlLogWarning "$FUNCNAME: The test is running in SELinux permissive mode."
+
+}
+
+
+
+__INTERNAL_rlSEModuleList() {
+  local semodule_list
+  eval semodule_list="\$($__INTERNAL_SEMODULE_LISTING)";
+  local res=$?
+  echo "$semodule_list" | sed -r 's/^[0-9]+\s//'
+  return $res
+}
+
+
+: <<'=cut'
+=pod
+
+=head2 rlSEModuleEnable
+
+The function attempts to enable policy module(s).
+
+    rlSEModuleEnable [--namespace NAMESPACE] MODULE ...
+
+Return number of failures
+
+See also rlSEModuleRestore
+
+=cut
+
+rlSEModuleEnable() {
+  local NAMESPACE='' res=0
+  while [[ "${1:0:1}" == "-" ]]; do
+      case $1 in
+        --namespace)
+            shift
+            NAMESPACE="_$1"
+          ;;
+      esac
+      shift
+  done
+  local module semodule_list to_enable
+  if semodule_list="$(__INTERNAL_rlSEModuleList)"; then
+    for module in "$@" ; do
+      local semodule="$(echo "$semodule_list" | grep -E "^${module}\s")"
+      if [[ -z "$semodule" ]] ; then
+        rlLogError "$FUNCNAME: module '$module' does not exist, skipping"
+        let res++
+      else
+        local state="$(echo "$semodule" | grep -iqE '\sdisabled$' && echo disabled || echo enabled)"
+        [[ -z "$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module)" ]] && \
+          __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module $state
+          __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules "$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules) $module"
+        if [[ "$state" == "enabled" ]]; then
+          rlLogInfo "$FUNCNAME: module '$module' is already enabled"
+        else
+          to_enable="$to_enable $module"
+        fi
+      fi
+    done
+    to_enable="${to_enable:1}"
+    if [[ -n "$to_enable" ]]; then
+      rlLog "$FUNCNAME: enabling '$to_enable' module(s), running 'semodule -e $to_enable'"
+      semodule -e $to_enable
+      local semodule_res=$?
+      if [[ $semodule_res -eq 0 ]] ; then
+        rlLog "$FUNCNAME: semodule enable passed"
+      else
+        rlLog "$FUNCNAME: semodule enable failed with exit code '$semodule_res'"
+        let res++
+      fi
+    fi
+  else
+    rlLogError "$FUNCNAME: could not get modules list"
+    let res++
+  fi
+  return $res
+}
+
+
+: <<'=cut'
+=pod
+
+=head2 rlSEModuleDisable
+
+The function attempts to disable policy module(s).
+
+    rlSEModuleDisable [--namespace NAMESPACE] MODULE ...
+
+Return number of failures
+
+See also rlSEModuleRestore
+
+=cut
+
+rlSEModuleDisable() {
+  local NAMESPACE='' res=0
+  while [[ "${1:0:1}" == "-" ]]; do
+      case $1 in
+        --namespace)
+            shift
+            NAMESPACE="_$1"
+          ;;
+      esac
+      shift
+  done
+  local module semodule_list to_disable
+  if semodule_list="$(__INTERNAL_rlSEModuleList)"; then
+    for module in "$@" ; do
+      local semodule="$(echo "$semodule_list" | grep -E "^${module}\s")"
+      if [[ -z "$semodule" ]] ; then
+        rlLogError "$FUNCNAME: module '$module' does not exist, skipping"
+        let res++
+      else
+        local state="$(echo "$semodule" | grep -iqE '\sdisabled$' && echo disabled || echo enabled)"
+        [[ -z "$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module)" ]] && \
+          __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module $state
+          __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules "$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules) $module"
+        if [[ "$state" == "disabled" ]]; then
+          rlLogInfo "$FUNCNAME: module '$module' is already disabled"
+        else
+          to_disable="$to_disable $module"
+        fi
+      fi
+    done
+    to_disable="${to_disable:1}"
+    if [[ -n "$to_disable" ]]; then
+      rlLog "$FUNCNAME: disabling '$to_disable' module(s), running 'semodule -d $to_disable'"
+      semodule -d $to_disable
+      local semodule_res=$?
+      if [[ $semodule_res -eq 0 ]] ; then
+        rlLog "$FUNCNAME: semodule disable passed"
+      else
+        rlLog "$FUNCNAME: semodule disable failed with exit code '$semodule_res'"
+        let res++
+      fi
+    fi
+  else
+    rlLogError "$FUNCNAME: could not get modules list"
+    let res++
+  fi
+  return $res
+}
+
+
+: <<'=cut'
+=pod
+
+=head2 rlSEModuleRestore
+
+The function attempts to restore policy module(s) state present before
+rlSEModuleEnable/rlSEModuleDisable was firstly called.
+
+If no module is specified, all modules will be restored.
+
+    rlSEModuleRestore [--namespace NAMESPACE] [MODULE ...]
+
+Return number of failures
+
+=cut
+
+rlSEModuleRestore() {
+  local NAMESPACE='' res=0
+  while [[ "${1:0:1}" == "-" ]]; do
+      case $1 in
+        --namespace)
+            shift
+            NAMESPACE="_$1"
+          ;;
+      esac
+      shift
+  done
+  local module semodule_list to_enable to_disable
+  if semodule_list="$(__INTERNAL_rlSEModuleList)"; then
+    local modules="$@"
+    local changed_modules="$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules)"
+    [[ -z "$modules" ]] && modules="$changed_modules"
+    for module in $modules ; do
+      if [[ "$changed_modules" =~ $(echo "\<$module\>") ]] ; then
+        changed_modules="$(echo "$changed_modules" | sed -r "s/\<${module}\>//")"
+        __INTERNAL_ST_PUT ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule changed_modules "$changed_modules"
+        local semodule="$(echo "$semodule_list" | grep -E "^${module}\s")"
+        if [[ -z "$semodule" ]] ; then
+          rlLogError "$FUNCNAME: module '$module' does not exist, skipping"
+          let res++
+        else
+          local state="$(echo "$semodule" | grep -iqE '\sdisabled$' && echo disabled || echo enabled)"
+          local saved_state="$(__INTERNAL_ST_GET ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module)"
+          __INTERNAL_ST_PRUNE ${NAMESPACE:+--namespace "$NAMESPACE"} --section=semodule $module
+          if [[ "$saved_state" == "enabled" ]] ; then
+            if [[ "$state" == "enabled" ]]; then
+              rlLogInfo "$FUNCNAME: module '$module' is already enabled"
+            else
+              to_enable="$to_enable $module"
+            fi
+          elif [[ "$saved_state" == "disabled" ]] ; then
+            if [[ "$state" == "disabled" ]]; then
+              rlLogInfo "$FUNCNAME: module '$module' is already disabled"
+            else
+              to_disable="$to_disable $module"
+            fi
+          else
+            rlLogError "$FUNCNAME: unexpected saved state '$saved_state'"
+            let res++
+          fi
+        fi
+      else
+        rlLogError "$FUNCNAME: there is no state of module '$module' saved, skipping"
+        let res++
+      fi
+    done
+    to_enable="${to_enable:1}"
+    to_disable="${to_disable:1}"
+    if [[ -n "$to_enable" ]]; then
+      rlLog "$FUNCNAME: enabling '$to_enable' module(s), running 'semodule -e $to_enable'"
+      semodule -e $to_enable
+      local semodule_res=$?
+      if [[ $semodule_res -eq 0 ]] ; then
+        rlLog "$FUNCNAME: semodule enable passed"
+      else
+        rlLog "$FUNCNAME: semodule enable failed with exit code '$semodule_res'"
+        let res++
+      fi
+    fi
+    if [[ -n "$to_disable" ]]; then
+      rlLog "$FUNCNAME: disabling '$to_disable' module(s), running 'semodule -d $to_disable'"
+      semodule -d $to_disable
+      local semodule_res=$?
+      if [[ $semodule_res -eq 0 ]] ; then
+        rlLog "$FUNCNAME: semodule disable passed"
+      else
+        rlLog "$FUNCNAME: semodule disable failed with exit code '$semodule_res'"
+        let res++
+      fi
+    fi
+  else
+    rlLogError "$FUNCNAME: could not get modules list"
+    let res++
+  fi
+  return $res
+}
+
+
+__INTERNAL_rlSEenable_full_auditing() {
+  local rules_file=/etc/audit/rules.d/audit.rules
+  if rlIsRHEL '<7'; then
+    rules_file="/etc/audit/audit.rules"
+  fi
+  local final_rules=/etc/audit/audit.rules
+  local config_file=/etc/audit/auditd.conf
+  local auditd_need_restart=0
+  local rules="-D"$'\n'"-w /etc/shadow -p w"
+  local res=0
+  if ! diff -u <(grep -v -e '^$' -e '^#' $final_rules) <(echo "$rules") > /dev/null; then
+    echo "$rules" > ${rules_file} && {
+      auditd_need_restart=1
+    } || {
+      rlLogError "could not enable full path resolving"
+      let res++
+    }
+  fi
+  rlIsRHEL '<7' || {
+    if grep -q "log_format = ENRICHED" $config_file; then
+      rlLog "enriched audit log format already enabled"
+    else
+      rlLog "enabling enriched audit log format"
+      sed -r -i 's/log_format =.*/log_format = ENRICHED/' $config_file && {
+        auditd_need_restart=1
+      } || {
+        rlLogError "could not enable ENRICHED logging"
+        let res++
+      }
+    fi
+  }
+  [[ $auditd_need_restart -eq 1 ]] && {
+    rlLog "stop the audit daemon first"
+    rlRun "service auditd stop"
+    sleep 5
+    rlLog "audit daemon configuration file is updated, starting the audit service"
+    rlServiceStart auditd || {
+      rlLogError "audit daemon was not restarted correctly"
+      let res++
+    }
+  }
+  if ! diff -u <(grep -v -e '^$' -e '^#' $final_rules) <(echo "$rules") > /dev/null; then
+    rlLogError "$final_rules is not updated"
+    let res++
+  fi
+  return $res
+}
+
+
+__INTERNAL_rlSEcache_checksum() {
+    local cachefile="$__INTERNAL_rlSE_CACHEFILE"
+    local sumfile="$__INTERNAL_rlSE_SUMFILE"
+
+    mkdir -p "$rlSE_CACHE_DIR" || {
+        rlLogError "cannot create rule cache dir"
+        return 1
+    }
+    local currentsum=$(sha1sum /sys/fs/selinux/policy) || {
+        rlLogError "cannot sha1sum selinux policy in /sys"
+        return 1
+    }
+    if [ -s "$cachefile" -a -s "$sumfile" ]; then
+        oldsum=$(<"$sumfile")
+        if [ "$currentsum" = "$oldsum" ]; then
+            # checksums identical, cache still valid
+            return 0
+        fi
+    fi
+    # checksum nonexisten / different, overwrite old by current
+    # and trigger cache rebuild
+    echo "$currentsum" > "$sumfile"
+    return 2
+}
+
+#
+# COMPATIBILITY NOTES:
+# - since rlSESearchRule doesn't use -p / --perms, we don't support it here,
+#   but it should be easy to add if needed
+# - multiple permissions of one original rule are split into multiple rows,
+#   each with 1 permission
+# - if searching by attribute in -s / -t, only rules specifying the attribute
+#   are returned, not rules for all types they encompass
+#   - searching by type works as with setools/sesearch
+# - filename in type_transition rules is always returned in double quotes,
+#   like setools v4.1, unlike setools v4.2+
+#
+__INTERNAL_rlSEcache_sesearch() {
+    local opts=$(getopt -o "s:t:c:" -l "allow,dontaudit,type_trans" -- "$@" \
+            2> >(while read -r line; do rlLogError "$FUNCNAME: $line"; done))
+    [ $? -ne 0 ] && return 1
+
+    eval set -- "$opts"
+    local in_source= in_target= in_class= ruletype=
+    while true; do
+        case "$1" in
+            '-s') shift; in_source="$1"; shift ;;
+            '-t') shift; in_target="$1"; shift ;;
+            '-c') shift; in_class="$1"; shift ;;
+            '--allow') ruletype="allow"; shift ;;
+            '--dontaudit') ruletype="dontaudit"; shift ;;
+            '--type_trans') ruletype="type_trans"; shift ;;
+            --) shift; break ;;
+        esac
+    done;
+
+    local cachefile="$__INTERNAL_rlSE_CACHEFILE"
+    if ! __INTERNAL_rlSEcache_checksum; then
+        rlLogInfo "(re)creating selinux-policy rule cache"
+        rm -f "$cachefile"
+        "$rlSELibraryDir/mkcache.py" "$cachefile" || {
+            rlLogError "cannot successfully create rule cache"
+            rm -f "$cachefile"  # in case it is incomplete
+            return 1
+        }
+    else
+        rlLogInfo "using existing selinux-policy rule cache"
+    fi
+
+    case "$ruletype" in
+        allow|dontaudit)
+            local q="SELECT \"source\", \"target\", \"class\",
+                            \"perm\", \"bool\", \"boolstate\"
+                     FROM \"${ruletype}_lookup\"
+                     WHERE
+                         \"source\"='$in_source' AND \"target\"='$in_target'
+                         AND \"class\"='$in_class' "
+            #[ "$in_perm" ] && q+="AND \"perm\" IN ($in_perm) "
+            local ret= row= source= target= class= perm= bool= bstate=
+            while IFS= read -r row; do
+                IFS='|' read -r source target class perm bool bstate <<<"$row"
+                case "$perm" in *\ *) perm="{ $perm }" ;; esac  # more than one
+                ret="$ruletype $source $target:$class $perm;"
+                if [ "$bool" ]; then
+                    ret+=" [ $bool ]:"
+                    [ "$bstate" = "1" ] && ret+="True" || ret+="False"
+                fi
+                echo "$ret"
+            done < <(echo "$q" | sqlite3 "$cachefile")
+            ;;
+        type_trans)
+            local q="SELECT \"source\", \"target\", \"class\", \"default\",
+                            \"filename\", \"bool\", \"boolstate\"
+                     FROM \"${ruletype}_lookup\"
+                     WHERE
+                         \"source\"='$in_source' AND \"target\"='$in_target'
+                         AND \"class\"='$in_class' "
+            local ret= row= source= target= class= default= filename= bool= bstate=
+            while IFS= read -r row; do
+                IFS='|' read -r source target class default filename bool bstate <<<"$row"
+                ret="type_transition $source $target:$class $default"
+                [ "$filename" ] && ret+=" \"$filename\""
+                ret+=';'
+                if [ "$bool" ]; then
+                    ret+=" [ $bool ]:"
+                    [ "$bstate" = "1" ] && ret+="True" || ret+="False"
+                fi
+                echo "$ret"
+            done < <(echo "$q" | sqlite3 "$cachefile")
+            ;;
+        *)
+            rlLogError "unsupported cache rule type: $ruletype"
+            return 1
+            ;;
+    esac
+}
+
+rlSELibraryLoaded() {
+    return 0
+}
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#   Authors
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+: <<'=cut'
+=pod
+
+=head1 AUTHORS
+
+=over
+
+=item *
+
+Milos Malik <mmalik@redhat.com>
+Michal Trunecka <mtruneck@redhat.com>
+David Spurek <dspurek@redhat.com>
+
+=back
+
+=cut

diff --git a/selinux-policy/Library/common/mkcache.py b/selinux-policy/Library/common/mkcache.py
new file mode 100755
index 0000000..61c76d7
--- /dev/null
+++ b/selinux-policy/Library/common/mkcache.py
@@ -0,0 +1,220 @@
+#!/usr/bin/env python3
+#
+# This script generates a sqlite-based rule cache from a selinux policy
+# currently active on the system, to be used by further queries.
+#
+
+import os, sys
+import sqlite3
+import setools
+
+#
+# LIMITATIONS !!!
+# - currently no sql views that would provide functionality matching sesearch
+#   - the current views return only what's searched, not everything around it
+#   - eg. searching attr will return entry for that attr, not for all its types
+#     - searching by types defined using attr works the same as for sesearch
+# - only allow, type_trans, dontaudit
+# - type_trans
+#   - no attributes support
+#
+
+if len(sys.argv) < 2:
+    print("usage: {0} <db_filename>".format(sys.argv[0]), file=sys.stderr)
+    sys.exit(1)
+
+dbfile = sys.argv[1]
+if os.path.lexists(dbfile):
+    print("error: {0} already exists".format(dbfile), file=sys.stderr)
+    sys.exit(1)
+
+conn = sqlite3.connect(dbfile)
+
+cur = conn.cursor()
+#cur.execute('PRAGMA foreign_keys = ON')
+
+#
+## creating tables
+#
+
+cur.executescript("""
+    /*
+     * global rule properties (applicable to any ruletype)
+     */
+    -- indexed by attribute name, maps to one or more "types",
+    -- - also contains entries for non-attributes (regular types), those
+    --   have `attr` == `type`
+    -- - also contains entries for attributes themselves, also with
+    --   `attr` == `type`
+    CREATE TABLE 'attrs' (
+        'attr' VARCHAR NOT NULL,
+        'type' VARCHAR NOT NULL
+    );
+    CREATE TABLE 'perms' (
+        'id' INTEGER UNSIGNED NOT NULL,
+        'perm' VARCHAR NOT NULL
+    );
+    CREATE TABLE 'bools' (
+        'id' INTEGER UNSIGNED NOT NULL,
+        'bool' VARCHAR NOT NULL,
+        'state' BOOLEAN NOT NULL  -- T/F of the whole conditional block
+    );
+    CREATE TABLE 'filenames' (
+        'id' INTEGER UNSIGNED NOT NULL,
+        'filename' VARCHAR NOT NULL
+    );
+
+    /*
+     * per-ruletype tables
+     */
+    CREATE TABLE 'allow' (
+        'id' INTEGER UNSIGNED NOT NULL PRIMARY KEY,
+        'source' VARCHAR NOT NULL,
+        'target' VARCHAR NOT NULL,
+        'class' VARCHAR NOT NULL
+    );
+    CREATE TABLE 'type_trans' (
+        'id' INTEGER UNSIGNED NOT NULL PRIMARY KEY,
+        'source' VARCHAR NOT NULL,
+        'target' VARCHAR NOT NULL,
+        'class' VARCHAR NOT NULL,
+        'default' VARCHAR NOT NULL
+    );
+    CREATE TABLE 'dontaudit' (
+        'id' INTEGER UNSIGNED NOT NULL PRIMARY KEY,
+        'source' VARCHAR NOT NULL,
+        'target' VARCHAR NOT NULL,
+        'class' VARCHAR NOT NULL
+    );
+
+    /*
+     * views for lookup
+     */
+    CREATE VIEW 'allow_lookup' AS
+    SELECT
+        "asrc"."type" AS 'source',
+        "atgt"."type" AS 'target',
+        "a"."class" AS 'class',
+        "p"."perm" AS 'perm',
+        "b"."bool" AS 'bool',
+        "b"."state" AS 'boolstate'
+    FROM "allow" 'a'
+        LEFT JOIN "attrs" 'asrc' ON "a"."source" = "asrc"."attr"
+        LEFT JOIN "attrs" 'atgt' ON "a"."target" = "atgt"."attr"
+        LEFT JOIN "perms" 'p' ON "a"."id" = "p"."id"
+        LEFT JOIN "bools" 'b' ON "a"."id" = "b"."id";
+
+    CREATE VIEW 'type_trans_lookup' AS
+    SELECT
+        "tt"."source" AS 'source',
+        "tt"."target" AS 'target',
+        "tt"."class" AS 'class',
+        "tt"."default" AS 'default',
+        "f"."filename" AS 'filename',
+        "b"."bool" AS 'bool',
+        "b"."state" AS 'boolstate'
+    FROM "type_trans" 'tt'
+        LEFT JOIN "filenames" 'f' ON "tt"."id" = "f"."id"
+        LEFT JOIN "bools" 'b' ON "tt"."id" = "b"."id";
+
+    CREATE VIEW 'dontaudit_lookup' AS
+    SELECT
+        "asrc"."type" AS 'source',
+        "atgt"."type" AS 'target',
+        "da"."class" AS 'class',
+        "p"."perm" AS 'perm',
+        "b"."bool" AS 'bool',
+        "b"."state" AS 'boolstate'
+    FROM "dontaudit" 'da'
+        LEFT JOIN "attrs" 'asrc' ON "da"."source" = "asrc"."attr"
+        LEFT JOIN "attrs" 'atgt' ON "da"."target" = "atgt"."attr"
+        LEFT JOIN "perms" 'p' ON "da"."id" = "p"."id"
+        LEFT JOIN "bools" 'b' ON "da"."id" = "b"."id";
+""")
+
+#
+## filling up the tables
+#
+
+def extract_attrs(rule, known_attrs=set()):
+    try:
+        typeattribute = setools.policyrep.TypeAttribute
+    except AttributeError:
+        # older setools
+        typeattribute = setools.policyrep.typeattr.TypeAttribute
+
+    # treat types as expandable attrs
+    for attr in (rule.source, rule.target):
+        attr_str = str(attr)  # expensive
+        if attr_str not in known_attrs:
+            # attr->attr
+            if isinstance(attr, typeattribute):
+                cur.execute('INSERT INTO "attrs" VALUES (?,?)',
+                            (attr_str, attr_str))
+            # attr->types and type->type
+            for child in attr.expand():
+                cur.execute('INSERT INTO "attrs" VALUES (?,?)',
+                            (attr_str, str(child)))
+            known_attrs.add(attr_str)
+
+known_attrs = set()
+for ruleid, rule in enumerate(setools.SELinuxPolicy().terules()):
+    # rule attributes
+    extract_attrs(rule, known_attrs=known_attrs)
+    # permissions
+    if hasattr(rule, 'perms'):
+        for perm in rule.perms:
+            cur.execute('INSERT INTO "perms" VALUES (?,?)',
+                        (ruleid, str(perm)))
+    # booleans
+    #if hasattr(rule, 'conditional'):
+    #    truth = next(filter(lambda x: x.result == True,
+    #                        rule.conditional.truth_table())).values
+    #    for boolname, boolstate in truth.items():
+    #        cur.execute("INSERT INTO 'bools' VALUES (?,?,?)",
+    #                    (ruleid, boolname, boolstate))
+    # booleans as expression strings, as seen in sesearch output
+    if hasattr(rule, 'conditional'):
+        cur.execute('INSERT INTO "bools" VALUES (?,?,?)',
+                    (ruleid, str(rule.conditional), rule.conditional_block))
+
+    # filename
+    if hasattr(rule, 'filename'):
+        cur.execute('INSERT INTO "filenames" VALUES (?,?)',
+                    (ruleid, rule.filename))
+    # per-ruletype
+    if rule.ruletype == setools.TERuletype.allow:
+        cur.execute('INSERT INTO "allow" VALUES (?,?,?,?)',
+                    (ruleid, str(rule.source), str(rule.target),
+                     str(rule.tclass)))
+    elif rule.ruletype == setools.TERuletype.type_transition:
+        cur.execute('INSERT INTO "type_trans" VALUES (?,?,?,?,?)',
+                    (ruleid, str(rule.source), str(rule.target),
+                     str(rule.tclass), str(rule.default)))
+    elif rule.ruletype == setools.TERuletype.dontaudit:
+        cur.execute('INSERT INTO "dontaudit" VALUES (?,?,?,?)',
+                    (ruleid, str(rule.source), str(rule.target),
+                     str(rule.tclass)))
+
+#
+## creating indices
+#
+
+# separate CREATE INDEX after filling up tables saves about 20% of
+# DB creation time + makes queries cca 30% faster due to better index
+# optimization
+cur.executescript("""
+    CREATE UNIQUE INDEX 'attrs_both' ON "attrs" ("attr", "type");
+    CREATE INDEX 'perms_id' ON "perms" ("id");
+    CREATE INDEX 'perms_perm' ON "perms" ("perm");
+    CREATE INDEX 'bools_id' ON "bools" ("id");
+    CREATE INDEX 'bools_bool' ON "bools" ("bool", "state");
+    CREATE INDEX 'filenames_id' ON "filenames" ("id");
+    CREATE INDEX 'filenames_filename' ON "filenames" ("filename");
+    CREATE INDEX 'allow_cols' ON "allow" ("source", "target", "class");
+    CREATE INDEX 'type_tran_cols' ON "type_trans" ("source", "target", "class", "default");
+    CREATE INDEX 'dontaudit_cols' ON "dontaudit" ("source", "target", "class");
+""")
+
+conn.commit()
+conn.close()

diff --git a/selinux-policy/Library/common/runtest.sh b/selinux-policy/Library/common/runtest.sh
new file mode 100755
index 0000000..46d5d95
--- /dev/null
+++ b/selinux-policy/Library/common/runtest.sh
@@ -0,0 +1,220 @@
+#!/bin/bash
+
+# This is a test file
+
+# Include rhts environment
+. /usr/bin/rhts-environment.sh
+. /usr/share/beakerlib/beakerlib.sh
+
+list_booleans() {
+  semanage boolean -l | sort
+}
+rlIsRHEL 5 && {
+  list_booleans() {
+    paste <(getsebool ${1:--a} | sort) <(seinfo -b$1 -x $__INTERNAL_POLICY_FILE 2>/dev/null | sed -r '/^\S/d;/^\s*$/d;s/\<[Ff][Aa][Ll][Ss][Ee]\>/off/;s/\<[Tt][Rr][Uu][Ee]\>/on/' | sort) | sed -r 's/^(\S+).*\<(on|off)\>.*\<(on|off)\>.*/\1 (\2,\3)/;s/on,/on   ,/;s/off,/off  ,/;s/,on/,   on/;s/,off/,  off/'
+  }
+}
+
+rlJournalStart
+    rlPhaseStartSetup
+        rlRun "rlImport selinux-policy/common"
+    rlPhaseEnd
+
+    rlPhaseStartTest "rlSEBoolean test"
+        if ! selinuxenabled
+        then
+            rlLogWarning "SELinux disabled: test was not run" "WARN"
+        else
+            rlRun 'rlSEBooleanRestore a-boolean' 1-255 "rlSEBooleanRestore should fail when no rlSEBoolean functions were run"
+            rlRun 'rlSEBooleanOn' 1-255 "rlSEBooleanOn should fail when no boolean is given"
+            rlRun 'rlSEBooleanOff' 1-255 "rlSEBooleanOff should fail when no boolean is given"
+            rlRun 'rlSEBooleanOn i_do_not_exist' 1-255 "rlSEBooleanOn should fail for non-existent boolean"
+            rlRun 'rlSEBooleanOff i_do_not_exist' 1-255 "rlSEBooleanOff should fail for non-existent boolean"
+            rlRun 'rlSEBooleanOn -P' 1-255 "rlSEBooleanOn -P should fail when no boolean is given"
+            rlRun 'rlSEBooleanOff -P' 1-255 "rlSEBooleanOff -P should fail when no boolean is given"
+            rlRun 'rlSEBooleanOn -P i_do_not_exist' 1-255 "rlSEBooleanOn -P should fail for non-existent boolean"
+            rlRun 'rlSEBooleanOff -P i_do_not_exist' 1-255 "rlSEBooleanOff -P should fail for non-existent boolean"
+
+            BOOL=( $(getsebool -a | grep ftp -m 4 | cut -d ' ' -f 1 | tr '\n' ' ') )
+            tmp="$(list_booleans | grep ftp)"
+            booleans_cleanup=''
+            booleans_cleanupP=''
+            for bool in ${BOOL[@]}; do
+              [[ "$(echo "$tmp" | grep $bool)" =~ $(echo '(\S+)\)') ]] && booleans_cleanupP+="$bool=${BASH_REMATCH[1]} "
+              [[ "$(echo "$tmp" | grep $bool)" =~ $(echo '\((\S+)') ]] && booleans_cleanup+="$bool=${BASH_REMATCH[1]} "
+            done
+
+            #Set initial state of booleans (all combinations - 00 01 10 11)
+            rlRun "setsebool -P ${BOOL[0]}=off ${BOOL[1]}=on ${BOOL[2]}=off ${BOOL[3]}=on"
+            rlRun "setsebool ${BOOL[1]}=off ${BOOL[2]}=on"
+
+            # Change the booleans using rlSEBooleanOn/Off which includes backup
+            rlRun "rlSEBooleanOn -P ${BOOL[0]} ${BOOL[2]}"
+            rlRun "rlSEBooleanOff -P ${BOOL[1]} ${BOOL[3]}"
+            rlRun "rlSEBooleanOn ${BOOL[1]} ${BOOL[2]}"
+            rlRun "rlSEBooleanOff ${BOOL[0]} ${BOOL[3]}"
+
+            # Check the correct values were set
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(on   ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(on   ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(off  ,  off)'"
+
+            rlRun "rlSEBooleanRestore"
+
+            # Check the values was restored correctly
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(on   ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(on   ,   on)'"
+
+            # Backup should fail because there already is a backup file
+            rlRun "rlSEBooleanBackup" 33
+            rlRun "rm -f $BEAKERLIB_DIR/sebooleans"
+            
+            # Backup all the booleans
+            rlRun "rlSEBooleanBackup"
+
+            # Change them using setsebool
+            rlRun "setsebool ${BOOL[0]}=on ${BOOL[1]}=on ${BOOL[2]}=off ${BOOL[3]}=off"
+
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(on   ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(on   ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(off  ,   on)'"
+
+            # Restore only two of them
+            rlRun "rlSEBooleanRestore ${BOOL[0]} ${BOOL[1]}"
+
+            # Check only the two were restored
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(off  ,   on)'"
+
+            # Change two bools using rlSEBooleanOn/Off to make sure it won't rewrite the backup
+            rlRun "rlSEBooleanOn -P ${BOOL[0]}"
+            rlRun "rlSEBooleanOff -P ${BOOL[1]}"
+
+            # Restore all by listing them
+            rlRun "rlSEBooleanRestore ${BOOL[0]} ${BOOL[1]} ${BOOL[2]} ${BOOL[3]}"
+
+            # ..and check it all is restored correctly
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(on   ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(on   ,   on)'"
+
+            rlRun "rm -f $BEAKERLIB_DIR/sebooleans"
+            # Now backup only two booleans
+            # Change them all
+            rlRun "rlSEBooleanOn -P ${BOOL[0]}"
+            rlRun "rlSEBooleanOff -P ${BOOL[1]}"
+            rlRun "setsebool -P ${BOOL[2]}=on ${BOOL[3]}=off"
+            rlRun "setsebool ${BOOL[2]}=off ${BOOL[3]}=on"
+
+            # Check they are changed
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(on   ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(on   ,  off)'"
+
+            # Restoring not backed up booleans should fail
+            rlRun "rlSEBooleanRestore ${BOOL[2]} ${BOOL[3]}" 1-255
+
+            # And this should restore only the backed up booleans
+            rlRun "rlSEBooleanRestore"
+
+            # Check only backed up booleans were restored
+            tmp="$(list_booleans)"
+            echo "$tmp" | grep "\<${BOOL[0]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[0]}\>' | grep '(off  ,  off)'"
+            echo "$tmp" | grep "\<${BOOL[1]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[1]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[2]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[2]}\>' | grep '(off  ,   on)'"
+            echo "$tmp" | grep "\<${BOOL[3]}\>"
+            rlRun "echo \"\$tmp\" | grep '\<${BOOL[3]}\>' | grep '(on   ,  off)'"
+
+            # Cleanup - set all the booleans back to off-off
+            rlRun "setsebool -P $booleans_cleanupP"
+            rlRun "setsebool $booleans_cleanup"
+        fi
+    rlPhaseEnd
+
+    rlPhaseStartTest "rlSESearchRule test"
+        rlSESearchRule "allow winbind_t port_t : tcp_socket name_connect"  
+        rlSESearchRule "allow unconfined_t smbcontrol_t : fd use targeted" 0
+        rlSESearchRule "allow unconfined_t smbcontrol_t : fd use mls" 1
+        rlSESearchRule "allow ftpd_t public_content_rw_t : dir { create write }"
+        rlSESearchRule "allow ftpd_t public_content_rw_t : dir { create write } [ rsync_client ]" 1
+        rlSESearchRule "allow ftpd_t public_content_rw_t : dir { create write } [ allow_ftpd_anon_write ]" 0
+    rlPhaseEnd
+
+    if rlIsRHEL '>=8'; then
+        cache_echo() {
+            echo CACHED:
+            echo "$1"
+            echo SESEARCH:
+            echo "$2"
+        }
+        rlPhaseStartTest "sesearch cache demo"
+            rlRun "cached=\$(__INTERNAL_rlSEcache_sesearch --allow -s winbind_t -t port_t -c tcp_socket)"
+            rlRun "real=\$(sesearch --allow -s winbind_t -t port_t -c tcp_socket)"
+            cache_echo "$cached" "$real"
+            rlRun "cached=\$(__INTERNAL_rlSEcache_sesearch --allow -s nsswitch_domain -t port_type -c tcp_socket)"
+            rlRun "real=\$(sesearch --allow -s nsswitch_domain -t port_type -c tcp_socket -ds -dt)"
+            cache_echo "$cached" "$real"
+            rlRun "cached=\$(__INTERNAL_rlSEcache_sesearch --type_trans -s xguest_t -t httpd_sys_ra_content_t -c process)"
+            rlRun "real=\$(sesearch --type_trans -s xguest_t -t httpd_sys_ra_content_t -c process)"
+            cache_echo "$cached" "$real"
+            rlRun "cached=\$(__INTERNAL_rlSEcache_sesearch --dontaudit -s abrt_helper_t -t domain -c rose_socket)"
+            rlRun "real=\$(sesearch --dontaudit -s abrt_helper_t -t domain -c rose_socket)"
+            cache_echo "$cached" "$real"
+        rlPhaseEnd
+    fi
+
+    rlPhaseStartTest "timestamps test"
+        rlSESetTimestamp
+        sleep 2
+        rlSESetTimestamp mine
+        sleep 2
+        rlSECheckAVC
+        rlSECheckAVC mine
+    rlPhaseEnd
+
+    rlPhaseStartCleanup
+    rlPhaseEnd
+    rlJournalPrintText
+rlJournalEnd
+

                 reply	other threads:[~2026-09-11 13:17 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178913266467.1.6483137332602741153.tests-selinux-af33a2c4be8c@fedoraproject.org \
    --to=plautrba@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox