[Rpm-maint] [PATCH 09/19] Install policies using the new structures
Steve Lawrence
slawrence at tresys.com
Tue Feb 2 20:25:12 UTC 2010
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 | 12 ++++++
lib/rpmte_internal.h | 3 ++
lib/rpmts.h | 1 +
lib/transaction.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/configure.ac b/configure.ac
index 45e7835..7b5b383 100644
--- a/configure.ac
+++ b/configure.ac
@@ -585,8 +585,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 b09556c..a1c952f 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -61,6 +61,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;
};
@@ -280,6 +281,12 @@ static void addTE(rpmte p, Header h, fnpyKey key, rpmRelocation * relocs)
rpmteColorDS(p, RPMTAG_PROVIDENAME);
rpmteColorDS(p, RPMTAG_REQUIRENAME);
+
+#if WITH_SELINUX
+ p->policies = headerIsEntry(h, RPMTAG_POLICIES);
+#else
+ p->policies = 0;
+#endif
return;
}
@@ -722,6 +729,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 357eead..f2019dc 100644
--- a/lib/rpmte_internal.h
+++ b/lib/rpmte_internal.h
@@ -68,6 +68,9 @@ tsortInfo rpmteTSI(rpmte te);
RPM_GNUC_INTERNAL
void rpmteSetTSI(rpmte te, tsortInfo tsi);
+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 e589344..bdec889 100644
--- a/lib/rpmts.h
+++ b/lib/rpmts.h
@@ -57,6 +57,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 d9f4f3d..d94ba9d 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -10,6 +10,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>
@@ -1129,6 +1130,87 @@ 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)
+{
+ rpmRC rc = RPMRC_OK;
+#if WITH_SELINUX
+ rpmtsi pi = NULL;
+ rpmte p = NULL;
+ rpmpol pol;
+ Header h = NULL;
+ char * type = NULL;
+
+ 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, 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);
+#endif /* WITH_SELINUX */
+
+ return rc;
+}
+
/* Add fingerprint for each file not skipped. */
static void addFingerprints(rpmts ts, uint64_t fileCount, rpmFpHash ht, fingerPrintCache fpc)
{
@@ -1207,7 +1289,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. */
@@ -1226,7 +1308,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) {
@@ -1440,6 +1523,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.2.5
More information about the Rpm-maint
mailing list