[Rpm-maint] [PATCH 09/12] Install policies using the new structures

Steve Lawrence slawrence at tresys.com
Thu Oct 22 18:25:46 UTC 2009


Policy is installed at the very beginning of a transaction, before
transaction scripts are executed.

This also adds a --nopolicy option which will skip all policy actions.
---
 configure.ac         |    8 +++-
 lib/poptI.c          |    2 +
 lib/rpmte.c          |    8 ++++
 lib/rpmte_internal.h |    3 ++
 lib/rpmts.h          |    1 +
 lib/transaction.c    |   93 ++++++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 54ec5d1..6231c57 100644
--- a/configure.ac
+++ b/configure.ac
@@ -728,8 +728,12 @@ esac],
 
 AS_IF([test "$with_selinux" = yes],[
   AC_CHECK_HEADER([selinux/selinux.h],[
-    AC_CHECK_LIB(selinux,[is_selinux_enabled],[with_selinux=yes],[
-      AC_MSG_ERROR([--with-selinux given, but libselinux not found])])
+    save_LIBS="$LIBS"
+    AC_CHECK_LIB([selinux],[is_selinux_enabled],[],[
+      AC_MSG_ERROR([--with-selinux given, but is_selinux_enabled not found in libselinux])])
+    AC_CHECK_LIB([selinux],[selinux_getpolicytype],[],[
+      AC_MSG_ERROR([--with-selinux given, but selinux_getpolicytype not found in libselinux])])
+    LIBS="$save_LIBS"
   ],[
     AC_MSG_ERROR([--with-selinux given, but selinux/selinux.h not found])
   ])
diff --git a/lib/poptI.c b/lib/poptI.c
index 5021f17..a64ff6b 100644
--- a/lib/poptI.c
+++ b/lib/poptI.c
@@ -206,6 +206,8 @@ struct poptOption rpmInstallPoptTable[] = {
 	N_("don't verify digest of files (obsolete)"), NULL },
  { "nocontexts", '\0',0,  NULL, RPMCLI_POPT_NOCONTEXTS,
 	N_("don't install file security contexts"), NULL},
+ { "nopolicy", '\0', POPT_BIT_SET, &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPOLICY,
+	N_("don't install selinux policy modules"), NULL},
 
  { "noorder", '\0', POPT_BIT_SET,
 	&rpmIArgs.installInterfaceFlags, INSTALL_NOORDER,
diff --git a/lib/rpmte.c b/lib/rpmte.c
index f25af12..a749994 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -66,6 +66,7 @@ struct rpmte_s {
 #define RPMTE_HAVE_POSTTRANS	(1 << 1)
     int transscripts;		/*!< pre/posttrans script existence */
     int failed;			/*!< (parent) install/erase failed */
+    int policies;		/*!< policy existence */
 
     rpmfs fs;
 };
@@ -278,6 +279,8 @@ static void addTE(rpmts ts, rpmte p, Header h,
     }
     p->fi = getFI(p, ts, h);
 
+    p->policies = headerIsEntry(h, RPMTAG_POLICIES);
+
     /* See if we have pre/posttrans scripts. */
     p->transscripts |= (headerIsEntry(h, RPMTAG_PRETRANS) &&
 			 headerIsEntry(h, RPMTAG_PRETRANSPROG)) ?
@@ -887,6 +890,11 @@ rpmps rpmteProblems(rpmte te)
     return te ? te->probs : NULL;
 }
 
+int rpmteHavePolicies(rpmte te)
+{
+    return (te != NULL && te->policies);
+}
+
 rpmfs rpmteGetFileStates(rpmte te) {
     return te->fs;
 }
diff --git a/lib/rpmte_internal.h b/lib/rpmte_internal.h
index 060405d..90e1bcb 100644
--- a/lib/rpmte_internal.h
+++ b/lib/rpmte_internal.h
@@ -89,6 +89,9 @@ int rpmteHaveTransScript(rpmte te, rpmTag tag);
 RPM_GNUC_INTERNAL
 rpmps rpmteProblems(rpmte te);
 
+RPM_GNUC_INTERNAL
+int rpmteHavePolicies(rpmte te);
+
 //RPM_GNUC_INTERNAL
 rpmfs rpmteGetFileStates(rpmte te);
 
diff --git a/lib/rpmts.h b/lib/rpmts.h
index dcb424d..5382dff 100644
--- a/lib/rpmts.h
+++ b/lib/rpmts.h
@@ -56,6 +56,7 @@ typedef enum rpmtransFlags_e {
     RPMTRANS_FLAG_NOPAYLOAD	= (1 << 24),
     RPMTRANS_FLAG_APPLYONLY	= (1 << 25),
 
+    RPMTRANS_FLAG_NOPOLICY		= (1 << 26),	/*!< from --nopolicy */
     RPMTRANS_FLAG_NOMD5		= (1 << 27),	/*!< from --nomd5 */
     RPMTRANS_FLAG_NOFILEDIGEST	= (1 << 27),	/*!< from --nofiledigest (alias to --nomd5) */
     RPMTRANS_FLAG_NOSUGGEST	= (1 << 28),	/*!< from --nosuggest */
diff --git a/lib/transaction.c b/lib/transaction.c
index 912ca93..4b5ede2 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -9,6 +9,7 @@
 #include <rpm/rpmlog.h>
 #include <rpm/rpmdb.h>
 #include <rpm/rpmds.h>
+#include <rpm/rpmpol.h>
 #include <rpm/rpmfileutil.h>
 #include <rpm/rpmstring.h>
 #include <rpm/argv.h>
@@ -926,6 +927,85 @@ static int runTransScripts(rpmts ts, rpmTag stag)
     return 0;
 }
 
+/*
+ * Extract and load selinux policy for transaction set
+ * @param ts	Transaction set
+ * @return	RPMRC_OK on success, rpmRC error code otherwise
+ */
+static rpmRC rpmtsLoadPolicy(rpmts ts)
+{
+	rpmtsi pi = NULL;
+	rpmte p = NULL;
+	rpmpol pol;
+	Header h = NULL;
+	char * type = NULL;
+	rpmRC rc = RPMRC_OK;
+
+	rpmpols ps = rpmpolsNew();
+
+	/* extract the policies from the header and add to the policy set */
+	pi = rpmtsiInit(ts);
+	while ((p = rpmtsiNext(pi, TR_ADDED))) {
+		if (!rpmteHavePolicies(p)) {
+			continue;
+		}
+
+		if (!rpmteOpen(p, ts, 0)) {
+			rpmlog(RPMLOG_ERR, _("Failed to open %s\n"), rpmteNEVRA(p));
+			goto err;
+		}
+
+		h = rpmteHeader(p);
+		if (!h) {
+			rpmlog(RPMLOG_ERR, _("Failed to get package header from %s\n"), rpmteNEVRA(p));
+			goto err;
+		}
+
+		pol = rpmpolNew(h);
+		if (!pol) {
+			rpmlog(RPMLOG_ERR, _("Failed to get policy from %s\n"), rpmteNEVRA(p));
+			goto err;
+		}
+
+		rpmpolsAdd(ps, pol);
+
+		pol = rpmpolFree(pol);
+		h = headerFree(h);
+		rpmteClose(p, ts, 0);
+	}
+	pi = rpmtsiFree(pi);
+
+	selinux_getpolicytype(&type);
+	rpmpolsSetType(ps, type);
+	type = _free(type);
+
+	rc = rpmpolsPrepare(ps, rpmtsGetRdb(ts));
+	if (rc != RPMRC_OK) {
+		if (rc == RPMRC_NOTFOUND) {
+			rc = RPMRC_OK;
+		}
+		goto err;
+	}
+
+	rc = rpmpolsInstall(ps, rpmtsRootDir(ts), rpmtsCurrDir(ts));
+	if (rc != RPMRC_OK) {
+		goto err;
+	}
+
+	rc = rpmpolsSaveState(ps, rpmtsGetRdb(ts), rpmtsGetTid(ts));
+	if (rc != RPMRC_OK) {
+		goto err;
+	}
+
+err:
+	h = headerFree(h);
+	rpmteClose(p, ts, 0);
+	pi = rpmtsiFree(pi);
+	ps = rpmpolsFree(ps);
+
+	return rc;
+}
+
 /* Add fingerprint for each file not skipped. */
 static void addFingerprints(rpmts ts, uint64_t fileCount, rpmFpHash ht, fingerPrintCache fpc)
 {
@@ -1004,7 +1084,7 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
 
     /* if SELinux isn't enabled or init fails, don't bother... */
     if (!rpmtsSELinuxEnabled(ts)) {
-        rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
+        rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS | RPMTRANS_FLAG_NOPOLICY));
     }
 
     /* XXX Make sure the database is open RDWR for package install/erase. */
@@ -1023,7 +1103,8 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
     (void) rpmtsSetChrootDone(ts, 0);
     (void) rpmtsSetTid(ts, tid);
 
-    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
+    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS) ||
+	    !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOLICY)) {
 	const char * rootDir = rpmtsRootDir(ts);
 	int dochroot = (rootDir != NULL && !rstreq(rootDir, "/") && *rootDir == '/');
 	if (dochroot) {
@@ -1237,6 +1318,14 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
     /* Check package set for problems */
     ts->probs = checkProblems(ts);
 
+    if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPOLICY))
+     	  || (rpmpsNumProblems(ts->probs) &&
+		(okProbs == NULL || rpmpsTrim(ts->probs, okProbs))))) {
+		if (rpmtsLoadPolicy(ts) != RPMRC_OK) {
+			goto exit;
+		}
+	}
+
     /* Run pre-transaction scripts, but only if there are no known
      * problems up to this point and not disabled otherwise. */
     if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPRE))
-- 
1.6.0.6



More information about the Rpm-maint mailing list