[Rpm-maint] [PATCH 11/12] Parse new policy requires header and check policy dependencies
Steve Lawrence
slawrence at tresys.com
Thu Oct 22 18:25:48 UTC 2009
After a policy set has been prepared (rpmpolsPrepare), a call to
rpmpolsCheckDeps will determine if PolicyReuqires: dependencies are met.
This function only checks against packages currently installed.
Also, PolicyRequires are merged into Requires, so if normal dependency
checks pass, we know the PolicyRequries packages will be installed by the
end of the transaction.
---
lib/rpmds.c | 4 +++
lib/rpmpol.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/rpmpol.h | 17 +++++++++++++++
lib/rpmte.c | 6 +++++
lib/rpmtypes.h | 3 +-
lib/transaction.c | 5 ++++
6 files changed, 91 insertions(+), 1 deletions(-)
diff --git a/lib/rpmds.c b/lib/rpmds.c
index aec5f6a..7371d86 100644
--- a/lib/rpmds.c
+++ b/lib/rpmds.c
@@ -54,6 +54,10 @@ static int dsType(rpmTag tag,
t = "Requires";
evr = RPMTAG_REQUIREVERSION;
f = RPMTAG_REQUIREFLAGS;
+ } else if (tag == RPMTAG_POLICYREQUIRENAME) {
+ t = "PolicyRequires";
+ evr = RPMTAG_POLICYREQUIREVERSION;
+ f = RPMTAG_POLICYREQUIREFLAGS;
} else if (tag == RPMTAG_CONFLICTNAME) {
t = "Conflicts";
evr = RPMTAG_CONFLICTVERSION;
diff --git a/lib/rpmpol.c b/lib/rpmpol.c
index 7bc01d7..ef13b55 100644
--- a/lib/rpmpol.c
+++ b/lib/rpmpol.c
@@ -12,6 +12,7 @@
#include <rpm/rpmfileutil.h>
#include <rpm/rpmmacro.h>
#include <rpm/rpmdb.h>
+#include <rpm/rpmds.h>
#include "rpmio/base64.h"
@@ -83,6 +84,7 @@ rpmpol rpmpolFree(rpmpol pol)
pol->names = _free(pol->names);
pol->flags = _free(pol->flags);
pol->actions = _free(pol->actions);
+ pol->requires = rpmdsFree(pol->requires);
if(pol->types) {
for (i = 0; i < pol->count; i++) {
@@ -201,6 +203,7 @@ rpmpol rpmpolNew(Header h)
pol->flags = flags.data;
pol->types = typeslist;
pol->obsoletes = obslist;
+ pol->requires = rpmdsNew(h, RPMTAG_POLICYREQUIRENAME, 0);
pol->actions = xcalloc(pol->count, sizeof(*pol->actions));
for (i = 0; i < pol->count; i++) {
pol->actions[i] = RPMPOL_ACTION_IGNORE;
@@ -335,6 +338,11 @@ void rpmpolSetAction(rpmpol pol, rpmpolAction action)
}
}
+rpmds rpmpolGetRequires(const rpmpol pol)
+{
+ return pol ? pol->requires : NULL;
+}
+
rpm_time_t rpmpolGetTime(const rpmpol pol)
{
return pol ? pol->time : 0;
@@ -1035,6 +1043,55 @@ exit:
return rc;
}
+rpmRC rpmpolsCheckDeps(rpmpols ps, rpmdb db)
+{
+ unsigned int i;
+
+ if (!ps || !db) {
+ return RPMRC_FAIL;
+ }
+
+ for (i = 0; i < ps->count; i++) {
+ rpmpol pol = ps->pols[i];
+
+ int policyIgnored = 1;
+ rpmpolInitIterator(pol);
+ while (rpmpolNext(pol) >= 0) {
+ rpmpolAction action = rpmpolGetAction(pol);
+ if (action == RPMPOL_ACTION_INSTALL || action == RPMPOL_ACTION_UPGRADE) {
+ policyIgnored = 0;
+ break;
+ }
+ }
+ if (policyIgnored) {
+ continue;
+ }
+
+ rpmds req = rpmpolGetRequires(pol);
+ rpmdsInit(req);
+ while (rpmdsNext(req) >= 0) {
+ Header h;
+ int depMet = 0;
+ rpmdbMatchIterator mi = rpmdbInitIterator(db, RPMTAG_PROVIDENAME, rpmdsN(req), 0);
+ while ((h = rpmdbNextIterator(mi)) != NULL) {
+ if (rpmdsAnyMatchesDep(h, req, 0)) {
+ depMet = 1;
+ break;
+ }
+ }
+ mi = rpmdbFreeIterator(mi);
+ if (!depMet) {
+ goto missing;
+ }
+ }
+ }
+
+ return RPMRC_OK;
+
+missing:
+ return RPMRC_MISSINGDEPS;
+}
+
rpmRC rpmpolsSaveState(rpmpols ps, rpmdb db, rpm_tid_t tid)
{
Header h;
diff --git a/lib/rpmpol.h b/lib/rpmpol.h
index 6d9d1d2..b6909d4 100644
--- a/lib/rpmpol.h
+++ b/lib/rpmpol.h
@@ -139,6 +139,14 @@ rpmpolAction rpmpolGetAction(const rpmpol pol);
RPM_GNUC_INTERNAL
void rpmpolSetAction(rpmpol pol, rpmpolAction action);
+/*
+ * Get the requires dependency set for the policy
+ * @param pol policy set
+ * @return policy requires dependency set
+ */
+RPM_GNUC_INTERNAL
+rpmds rpmpolGetRequires(const rpmpol pol);
+
/** \ingroup rpmpol
* Get the time the policy was installed
* @param pol policy set
@@ -316,6 +324,15 @@ RPM_GNUC_INTERNAL
rpmRC rpmpolsPrepare(rpmpols ps, rpmdb db);
/** \ingroup rpmpol
+ * Perform dependency checks of installed/upgraded policies
+ * @param ps rpm policy set
+ * @param db rpm database
+ * @return RPMRC_OK on success, RPMRC_FAIL if missing deps
+ */
+RPM_GNUC_INTERNAL
+rpmRC rpmpolsCheckDeps(rpmpols ps, rpmdb db);
+
+/** \ingroup rpmpol
* Write the policy set to the rpm database
* @param ps rpm policy set
* @param db rpm database
diff --git a/lib/rpmte.c b/lib/rpmte.c
index a749994..899bd99 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -291,6 +291,12 @@ static void addTE(rpmts ts, rpmte p, Header h,
rpmteColorDS(p, RPMTAG_PROVIDENAME);
rpmteColorDS(p, RPMTAG_REQUIRENAME);
+
+ if (p->policies && rpmtsSELinuxEnabled(ts) && !(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOLICY)) {
+ rpmds polreqs = rpmdsNew(h, RPMTAG_POLICYREQUIRENAME, 0);
+ rpmdsMerge(&p->requires, polreqs);
+ rpmdsFree(polreqs);
+ }
return;
}
diff --git a/lib/rpmtypes.h b/lib/rpmtypes.h
index 8ba0df8..70fbe16 100644
--- a/lib/rpmtypes.h
+++ b/lib/rpmtypes.h
@@ -92,7 +92,8 @@ typedef enum rpmRC_e {
RPMRC_NOTFOUND = 1, /*!< Generic not found code. */
RPMRC_FAIL = 2, /*!< Generic failure code. */
RPMRC_NOTTRUSTED = 3, /*!< Signature is OK, but key is not trusted. */
- RPMRC_NOKEY = 4 /*!< Public key is unavailable. */
+ RPMRC_NOKEY = 4, /*!< Public key is unavailable. */
+ RPMRC_MISSINGDEPS = 5 /*!< Missing dependencies error code. */
} rpmRC;
#ifdef __cplusplus
diff --git a/lib/transaction.c b/lib/transaction.c
index 4b5ede2..74dbeea 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -987,6 +987,11 @@ static rpmRC rpmtsLoadPolicy(rpmts ts)
goto err;
}
+ rc = rpmpolsCheckDeps(ps, rpmtsGetRdb(ts));
+ if (rc != RPMRC_OK) {
+ goto err;
+ }
+
rc = rpmpolsInstall(ps, rpmtsRootDir(ts), rpmtsCurrDir(ts));
if (rc != RPMRC_OK) {
goto err;
--
1.6.0.6
More information about the Rpm-maint
mailing list