msm: consistency for equally ranked keys
[platform/upstream/rpm.git] / plugins / msm-plugin.c
index cc79bd0..3a1c653 100644 (file)
@@ -25,9 +25,6 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
-#include "plugin.h"
-#include "debug.h"
 
 #include <errno.h>
 #include <sys/types.h>
@@ -38,7 +35,6 @@
 #include <sys/stat.h>
 
 #include <rpm/rpmfileutil.h>
-#include <rpm/rpmmacro.h>
 #include <rpm/rpmpgp.h>
 #include <rpm/rpmkeyring.h>
 #include <rpm/rpmdb.h>
@@ -80,112 +76,179 @@ typedef struct packagecontext {
     struct smack_accesses *smack_accesses;     /*!<  handle to smack_accesses */
 } packagecontext;
 
-static rpmts ts = NULL;
-static int rootSWSource= 0;
-static manifest_x *root = NULL; /* pointer to device security policy file */
+static rpmts ts = NULL;                                /* rpm transaction */
+static manifest_x *dsp = NULL;                         /* pointer to device security policy file */
 static packagecontext *context = NULL;
 static sw_source_x *current = NULL;
 static packagecontext *contextsHead = NULL;
 static packagecontext *contextsTail = NULL;
 static fileconflict *allfileconflicts = NULL;
-static char* ownSmackLabel = NULL;
-static int SmackEnabled = 0;
+static char* ownSmackLabel = NULL;             /* rpm smack security context */
+static int SmackEnabled = 0;                   /* indicates if Smack is enabled in kernel or not */
 static magic_t cookie = NULL;
 static int package_created = 0;
 
-rpmRC PLUGINHOOK_INIT_FUNC(rpmts _ts, const char *name, const char *opts)
+/* Support functions */
+
+/**
+ * Frees the given pointer and sets it to NULL
+ * @param ptr  address of pointer to be freed
+ * @return NULL
+ */
+static packagecontext *msmFree(packagecontext *ctx)
 {
-    ts = _ts;
-    int res = 0;
-    char *fullPath = NULL, *fullPath1 = NULL;
+    while (ctx) {
+        packagecontext *next = ctx->next;
+        msmFreePointer((void**)&ctx->data);
+        ctx->mfx = msmFreeManifestXml(ctx->mfx);
+        if (ctx->smack_accesses) smack_accesses_free(ctx->smack_accesses);
+        msmFreePointer((void**)&ctx);
+        ctx = next;
+    }
+    return NULL;
+}
 
-    if (!ts)
-        return RPMRC_FAIL;
+/**
+ * Frees the given pointer and sets it to NULL
+ * @param ptr  address of pointer to be freed
+ * @return
+ */
+void msmFreePointer(void** ptr)
+{
+    if (*ptr)
+        free(*ptr);
+    *ptr = NULL;
+    return;
+}
+
+/**
+ * Creates a new package context
+ * @param te   rpm te struct
+ * @return created package context
+ */
+static packagecontext *msmNew(rpmte te)
+{
+    Header h;
+    struct rpmtd_s msm;
+    int count;
+    packagecontext *ctx = NULL;
+    const char *sw_source = NULL;
+
+    rpmtdReset(&msm);
     
-    fullPath = rpmGenPath(ts->rootDir, DEVICE_SECURITY_POLICY, NULL);
-    rpmlog(RPMLOG_DEBUG, "fullPath %s\n", fullPath);
-    if (!fullPath) {
-        rpmlog(RPMLOG_ERR, "Building a full path failed for device security policy\n");
-        return RPMRC_FAIL;
+    h = rpmteHeader(te);
+    if (!h) return NULL;
+    
+    ctx = xcalloc(1, sizeof(*ctx));
+    if (!ctx) {
+        goto exit1;
+    }
+    ctx->te = te;
+
+    if (!headerIsEntry(h, RPMTAG_SECMANIFEST)) {
+        goto exit1;
     }
 
-#ifndef ENABLE_DCHECKS
-    rpmlog(RPMLOG_DEBUG, "ENABLE_DCHECKS is undefined!\n");
-#else
-    rpmlog(RPMLOG_DEBUG, "ENABLE_DCHECKS is defined!\n");
-#endif
+    if (!headerGet(h, RPMTAG_SECMANIFEST, &msm, HEADERGET_MINMEM)) {
+        goto exit1;
+    }
 
-    rpmlog(RPMLOG_DEBUG, "reading device security policy from %s\n", fullPath);
-    root = msmProcessDevSecPolicyXml(fullPath);
+    count = rpmtdCount(&msm);
+    if (count != 1) {
+        goto exit2;
+    }
 
-    if (root) {
-        if (msmSetupSWSources(NULL, root, NULL)) {
-           rpmlog(RPMLOG_ERR, "Failed to setup device security policy from %s\n", 
-                  fullPath);
-            return RPMRC_FAIL;
+    ctx->data = xstrdup(rpmtdNextString(&msm));
+    rpmlog(RPMLOG_DEBUG, "%s manifest b64 data: %.40s...\n", 
+          rpmteN(ctx->te), ctx->data);
+ exit2:
+    rpmtdFreeData(&msm);
+ exit1:
+    if (rpmteType(ctx->te) == TR_ADDED) {
+        /* Save sw_source name into database, we need it when package */
+        /* is removed because signature verify is not called then. */
+        if (current) sw_source = current->name;
+        if (!sw_source || !headerPutString(h, RPMTAG_SECSWSOURCE, sw_source)) {
+            rpmlog(RPMLOG_ERR, "Failed to save sw source for %s, sw_source: %s\n", 
+                  rpmteN(ctx->te), sw_source);
+            msmFreePointer((void**)&ctx->data);
+            msmFreePointer((void**)&ctx);
         }
-    } else {
-        /* Do not allow plug-in to proceed without security policy existing */
-        rpmlog(RPMLOG_ERR, "Failed to process sw sources from %s\n", 
-              fullPath);
-        return RPMRC_FAIL;
     }
+    headerFree(h);
 
-    msmFreePointer((void**)&fullPath);
+    return ctx;
+}
 
-    fullPath = rpmGenPath(ts->rootDir, SMACK_LOAD_PATH, NULL);
-    rpmlog(RPMLOG_DEBUG, "fullPath for SMACK_LOAD_PATH %s\n", fullPath);
-    if (!fullPath) {
-        rpmlog(RPMLOG_ERR, "Building a full path for smack load failed\n");
-        return RPMRC_FAIL;
+/**
+ * Creates and adds a te package context to a context list
+ * @param te   rpm te struct
+ * @return created and added package context
+ */
+static packagecontext *msmAddTE(rpmte te)
+{
+    packagecontext *ctx = msmNew(te);
+    if (ctx) {
+        /* add the new policy to the list */
+        if (!contextsHead) {
+            contextsHead = ctx;
+            contextsTail = ctx;
+        } else {
+            if (rpmteType(te) == TR_ADDED) {
+                /* add to the end of the list */
+                contextsTail->next = ctx;
+                contextsTail = ctx;
+            } else {
+                /* add to the beginning of the list */
+                ctx->next = contextsHead;
+                contextsHead = ctx;
+            }
+        }
     }
+    return ctx;
+}
+
+/* -------------------- */
+
+/* Implementation of hooks */
+/* Hooks are listed in the call sequence inside rpm code */
+
+rpmRC PLUGINHOOK_INIT_FUNC(rpmts _ts, const char *name, const char *opts)
+{
+    ts = _ts;
 
-    /* check its own security context and store it for the case when packages without manifest will be installed */
-    struct stat buf;
+    if (!ts)
+        return RPMRC_FAIL;
 
-    if (stat(fullPath, &buf) == 0) {
-        res = smack_new_label_from_self(&ownSmackLabel);
+    if (msmLoadDeviceSecurityPolicy(ts->rootDir, &dsp) == RPMRC_FAIL)
+        return RPMRC_FAIL;
+
+    if (!dsp)
+        return RPMRC_FAIL;
+
+    /* smackfs path doesn't need to be prefixed with ts->rootDir 
+       since it is only used for loading rules to kernel and libsmack will load it
+       by itself to the correct path */
+
+    if (smack_smackfs_path() == NULL) {
+        rpmlog(RPMLOG_INFO, "Smackfs isn't mounted at %s. Going to the image build mode. \n", smack_smackfs_path());
+        ownSmackLabel = strdup("_");
+        SmackEnabled = 0;
+    } else {
+        /* check its own security context and store it for the case when packages without manifest will be installed */
+        int res = smack_new_label_from_self(&ownSmackLabel);
         SmackEnabled = 1;
-        if (res != 0) {
+        if (res < 0) {
             rpmlog(RPMLOG_ERR, "Failed to obtain rpm security context\n");
             return RPMRC_FAIL;
         }
-    } else {
-        rpmlog(RPMLOG_INFO, "Smackfs isn't mounted at %s. Going to the image build mode. \n", fullPath);
-        ownSmackLabel = strdup("_");
-        SmackEnabled = 0;
-    }
-
-    msmFreePointer((void**)&fullPath);    
-    fullPath = rpmGenPath(ts->rootDir, SMACK_RULES_PATH, NULL);
-    fullPath1 = rpmGenPath(ts->rootDir, SMACK_RULES_PATH_BEG, NULL);
-    rpmlog(RPMLOG_DEBUG, "fullPath for SMACK_RULES_PATH %s\n", fullPath);
-    rpmlog(RPMLOG_DEBUG, "fullPath1 for SMACK_RULES_PATH_BEG %s\n", fullPath1);
-    if ((!fullPath) || (!fullPath1)){
-        rpmlog(RPMLOG_ERR, "Building a full path failed for smack rules path\n");
-       return RPMRC_FAIL;
-    }
-
-    if (stat(fullPath, &buf) != 0) {
-        rpmlog(RPMLOG_DEBUG, "A directory for writing smack rules is missing. Creating one.\n");
-        mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH; // 644 -rwer--r--
-        if (stat(fullPath1, &buf) != 0) {
-            if (mkdir(fullPath1, mode) != 0) {
-                rpmlog(RPMLOG_ERR, "Failed to create a sub-directory for smack rules\n");
-                return RPMRC_FAIL;
-            }    
-        }
-        if (mkdir(fullPath, mode) != 0){
-            rpmlog(RPMLOG_ERR, "Failed to create a directory for smack rules\n");
-            return RPMRC_FAIL;
-        } 
     }
 
-    msmFreePointer((void**)&fullPath);    
-    msmFreePointer((void**)&fullPath1);    
-
     rpmlog(RPMLOG_DEBUG, "rpm security context: %s\n", ownSmackLabel);
 
+    if (msmSetupSmackRulesDir(ts->rootDir) == RPMRC_FAIL)
+        return RPMRC_FAIL;
+
     cookie = magic_open(0); 
     if (!cookie)
         return RPMRC_FAIL; 
@@ -200,28 +263,28 @@ rpmRC PLUGINHOOK_INIT_FUNC(rpmts _ts, const char *name, const char *opts)
     return RPMRC_OK;
 }
 
-static int findSWSourceByName(sw_source_x *sw_source, void *param, void* param2)
-{
-    const char *name = (const char *)param;
-    return strcmp(sw_source->name, name); 
-}
-
 rpmRC PLUGINHOOK_FILE_CONFLICT_FUNC(rpmts ts, char* path,
                                      Header oldHeader, rpmfi oldFi, 
                                      int rpmrc)
 {
     fileconflict *fc;
-    if (!path)
-        return rpmrc; 
-    rpmlog(RPMLOG_DEBUG, "FILE_CONFLICT_FUNC hook  path %s\n",path);
+    if ((!path) || (!dsp))
+        return rpmrc;
 
-    const char *name = headerGetString(oldHeader, RPMTAG_SECSWSOURCE);    
-    if (!name || !root) {
-        return rpmrc; /* no sw source(s) - abnormal state */
-    }
+    rpmlog(RPMLOG_DEBUG, "FILE_CONFLICT_FUNC hook path %s\n",path);
+
+    /* uncomment this code if you wish that plugin obeys --replacefiles rpm flag
+    if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES) {
+        return rpmrc;
+    } */
+
+    const char *sw_source_name = headerGetString(oldHeader, RPMTAG_SECSWSOURCE);
     const char *pkg_name = headerGetString(oldHeader, RPMTAG_NAME);
+    if (!sw_source_name || !pkg_name) {
+        return rpmrc; /* no sw source or package name - abnormal state */
+    }
 
-    sw_source_x *sw_source = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceByName, (void *)name, NULL);
+    sw_source_x *sw_source = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceByName, (void *)sw_source_name, NULL);
     if (!sw_source)
         return rpmrc; /* no old sw_source - abnormal state */
 
@@ -232,7 +295,8 @@ rpmRC PLUGINHOOK_FILE_CONFLICT_FUNC(rpmts ts, char* path,
         if (!fc) return RPMRC_FAIL;
         fc->path = path;
         fc->sw_source = sw_source;
-        fc->pkg_name = pkg_name;
+        fc->pkg_name = strdup(pkg_name);
+        if (!fc->pkg_name) return RPMRC_FAIL;
         HASH_ADD_KEYPTR(hh, allfileconflicts, path, strlen(path), fc);
     } else {
         /* Many packages have installed the same file */
@@ -243,77 +307,25 @@ rpmRC PLUGINHOOK_FILE_CONFLICT_FUNC(rpmts ts, char* path,
         msmFreePointer((void**)&path);
     }
 
-    if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES) {
-        /* Conflict has been noted, now return ok. It will be actually */
-        /* resolved later when conflicting package signature is verified */
-        /* and sw_source is known. */
-        return rpmrc;
-    }
     return rpmrc;
 }
 
 rpmRC PLUGINHOOK_TSM_PRE_FUNC(rpmts ts)
 {
-    if (!root) {
-        rpmlog(RPMLOG_DEBUG, "Policy is missing. Ending transaction\n");
+    if (!dsp) {
+        rpmlog(RPMLOG_ERR, "Device security policy is missing. Unable to proceed\n");
         return RPMRC_FAIL;
     }
 
     return RPMRC_OK;
 }
 
-static int findSWSourceBySignature(sw_source_x *sw_source, void *param, void* param2)
-{
-    origin_x *origin;
-    keyinfo_x *keyinfo;
-    pgpDigParams sig = (pgpDigParams)param;
-    DIGEST_CTX ctx = (DIGEST_CTX)param2;
-    pgpDigParams key = NULL;
-
-    for (origin = sw_source->origins; origin; origin = origin->prev) {
-        for (keyinfo = origin->keyinfos; keyinfo; keyinfo = keyinfo->prev) {
-           if (pgpPrtParams(keyinfo->keydata, keyinfo->keylen, PGPTAG_PUBLIC_KEY, &key)) {
-                rpmlog(RPMLOG_ERR, "invalid sw source key\n");
-                return -1;
-            }
-            if (pgpVerifySignature(key, sig, ctx) == RPMRC_OK) {
-                return 0;
-            }
-        }
-    }
-    return 1;
-}
-
 rpmRC PLUGINHOOK_VERIFY_FUNC(rpmKeyring keyring, rpmtd sigtd, pgpDigParams sig, DIGEST_CTX ctx, int rpmrc)
 {
     current = NULL;
 
-#if 0 
-    if (!root) {
-        if (rpmrc == RPMRC_NOKEY) {
-            rpmlog(RPMLOG_INFO, "package verified as root sw source\n");
-            rootSWSource = 1; /* accept any signed package as root */
-            return RPMRC_OK;
-        }
-        rpmlog(RPMLOG_ERR, "No device security policy, cannot verify signature\n");
-        return rpmrc;
-    } 
-
-    // make currently that even non-signed package with root policy will be treated as trusted
-
-    if (!root) {
-        rpmlog(RPMLOG_INFO, "package verified as root sw source\n");
-        rootSWSource = 1; /* accept any signed package as root */
-        return RPMRC_OK;
-    } 
-
-    //------------------
-
-#endif
-
-    if (!root) {
+    if (!dsp) {
         rpmlog(RPMLOG_ERR, "No device policy found\n");
-        rootSWSource = 1; /* accept any signed package as root */
         return rpmrc;
     } 
 
@@ -325,15 +337,15 @@ rpmRC PLUGINHOOK_VERIFY_FUNC(rpmKeyring keyring, rpmtd sigtd, pgpDigParams sig,
     if (rpmrc) {
         /* RPM failed to verify signature */
         rpmlog(RPMLOG_ERR, "Invalid signature, cannot search sw source\n");
-        return rpmrc;
+        goto exit;
     }
     if (sigtd->tag != RPMSIGTAG_RSA) {
         /* Not RSA, revert to unknown sw source. */
-        rpmlog(RPMLOG_DEBUG, "no RSA signature, cannot search sw source\n");
+        rpmlog(RPMLOG_DEBUG, "not an RSA signature, cannot search sw source\n");
         goto exit;
     }
 
-    current = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceBySignature, sig, ctx);
+    current = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceBySignature, sig, ctx);
     if (current)
         rpmlog(RPMLOG_DEBUG, "signature matches sw source %s\n", current->name);
     else
@@ -341,11 +353,11 @@ rpmRC PLUGINHOOK_VERIFY_FUNC(rpmKeyring keyring, rpmtd sigtd, pgpDigParams sig,
 
  exit:
     if (!current) {
-        current = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceByName, (void *)"_default_", NULL);
+        current = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceByName, (void *)"_default_", NULL);
         if (current) {
             rpmlog(RPMLOG_DEBUG, "using _default_ sw source\n");
         } else { // for now in case default sw source isn't there yet, allow to think that it is coming from root
-            current = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceByName, (void *)"root", NULL);
+            current = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceByName, (void *)"root", NULL);
             if (current)
                 rpmlog(RPMLOG_DEBUG, "using _root_ sw source now for testing\n");
         }
@@ -354,85 +366,6 @@ rpmRC PLUGINHOOK_VERIFY_FUNC(rpmKeyring keyring, rpmtd sigtd, pgpDigParams sig,
     return rpmrc;
 }
 
-static packagecontext *msmNew(rpmte te)
-{
-    Header h;
-    struct rpmtd_s msm;
-    int count;
-    packagecontext *ctx = NULL;
-    const char *sw_source = NULL;
-
-    rpmtdReset(&msm);
-    
-    h = rpmteHeader(te);
-    if (!h) return NULL;
-    
-    ctx = xcalloc(1, sizeof(*ctx));
-    if (!ctx) {
-        goto exit1;
-    }
-    ctx->te = te;
-
-    if (!headerIsEntry(h, RPMTAG_SECMANIFEST)) {
-        goto exit1;
-    }
-
-    if (!headerGet(h, RPMTAG_SECMANIFEST, &msm, HEADERGET_MINMEM)) {
-        goto exit1;
-    }
-
-    count = rpmtdCount(&msm);
-    if (count != 1) {
-        goto exit2;
-    }
-
-    ctx->data = xstrdup(rpmtdNextString(&msm));
-    rpmlog(RPMLOG_DEBUG, "%s manifest b64 data: %.40s...\n", 
-          rpmteN(ctx->te), ctx->data);
- exit2:
-    rpmtdFreeData(&msm);
- exit1:
-    if (rpmteType(ctx->te) == TR_ADDED) {
-        /* Save sw_source name into database, we need it when package */
-        /* is removed because signature verify is not called then. */
-        if (current) sw_source = current->name;
-        else if (rootSWSource) sw_source = rpmteN(ctx->te);
-
-        if (!sw_source || !headerPutString(h, RPMTAG_SECSWSOURCE, sw_source)) {
-            rpmlog(RPMLOG_ERR, "Failed to save sw source for %s, sw_source: %s\n", 
-                  rpmteN(ctx->te), sw_source);
-            msmFreePointer((void**)&ctx->data);
-            msmFreePointer((void**)&ctx);
-        }
-    }
-    headerFree(h);
-
-    return ctx;
-}
-
-static packagecontext *msmAddTE(rpmte te)
-{
-    packagecontext *ctx = msmNew(te);
-    if (ctx) {
-        /* add the new policy to the list */
-        if (!contextsHead) {
-            contextsHead = ctx;
-            contextsTail = ctx;
-        } else {
-            if (rpmteType(te) == TR_ADDED) {
-                /* add to the end of the list */
-                contextsTail->next = ctx;
-                contextsTail = ctx;
-            } else {
-                /* add to the beginning of the list */
-                ctx->next = contextsHead;
-                contextsHead = ctx;
-            }
-        }
-    }
-    return ctx;
-}
-
 rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
 {
     packagecontext *ctx = NULL;
@@ -442,18 +375,20 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
     rpmRC rc = RPMRC_OK;
     int ret = 0;
 
-    if (!root && !rootSWSource) {
-        /* no sw source config, just exit */
-        goto exit;
+    package_created = 0;
+
+    if (!dsp) {
+        rpmlog(RPMLOG_ERR, "Device security policy is missing. Unable to proceed\n");
+        return RPMRC_FAIL;
     }
 
     if (!current) {
         /* this means that verify hook has not been called */
-        current = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceByName, (void *)"_default_", NULL);
+        current = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceByName, (void *)"_default_", NULL);
         if (current) {
             rpmlog(RPMLOG_DEBUG, "using _default_ sw source\n");
         } else { 
-            rpmlog(RPMLOG_ERR, "Default source isn't availiable. Package source can't be determined. Abort installation\n");
+            rpmlog(RPMLOG_ERR, "Default source isn't avaliable. Package source can't be determined. Abort installation\n");
             goto fail;
         }
     }
@@ -471,12 +406,13 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
         if (h) {
             const char *name = headerGetString(h, RPMTAG_SECSWSOURCE);
             if (name) { 
-                current = msmSWSourceTreeTraversal(root->sw_sources, findSWSourceByName, (void *)name, NULL);
+                current = msmSWSourceTreeTraversal(dsp->sw_sources, msmFindSWSourceByName, (void *)name, NULL);
                 rpmlog(RPMLOG_DEBUG, "removing %s from sw source %s\n",
                       rpmteN(ctx->te), name);
             }
             headerFree(h);
         }
+        package_created = 1;
         /* if (!current) {
             rpmlog(RPMLOG_INFO, "no sw source for removing %s\n", rpmteN(ctx->te));
             goto exit;
@@ -529,11 +465,12 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
         rpmlog(RPMLOG_DEBUG, "Installing the package\n");
         package_x *package = NULL;
 
-        if (rootSWSource) {
-            /* this is the first package */
+        /*if (rootSWSource) {
+            // this is the first package that brings the policy
             package = msmCreatePackage(mfx->name, mfx->sw_sources, 
                                            mfx->provides, NULL);
-        } else if (mfx->sw_source) {
+        } else */
+        if (mfx->sw_source) {
             /* all packages must have sw_source */
             package = msmCreatePackage(mfx->name, mfx->sw_source, 
                                            mfx->provides, NULL);
@@ -566,35 +503,36 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
             goto fail;
         }
 
-        if (rootSWSource) {
-            /* current is root */
-            root = ctx->mfx;
-        } 
+        package_created = 1;
+        
+        /*if (rootSWSource) {
+            // current configuration becomes dsp
+            dsp = ctx->mfx;
+        } */
 
         rpmlog(RPMLOG_DEBUG, "Starting the security setup...\n");
         unsigned int smackLabel = 0;
 
-        if (rootSWSource || ctx->mfx->sw_source) {
+        /*if (rootSWSource || ctx->mfx->sw_source) {*/
+        if (ctx->mfx->sw_source) {
             if (ctx->mfx->sw_sources) {
                 smackLabel = 1; /* setting this one on since this manifest doesn't have any define/request section */
                 ret = msmSetupSWSources(ctx->smack_accesses, ctx->mfx, ts);
                 if (ret) {
                     rpmlog(RPMLOG_ERR, "SW source setup failed for %s\n",
                            rpmteN(ctx->te));
-                    msmCancelPackage(ctx->mfx->name);
                     goto fail;
                 }
             }           
-            if (ctx->mfx->define) {
-                if (ctx->mfx->define->name)
-                    smackLabel = 1;
-                ret = msmSetupDefine(ctx->smack_accesses, ctx->mfx);
+            if (ctx->mfx->defines) {
+                ret = msmSetupDefines(ctx->smack_accesses, ctx->mfx);
                 if (ret) {
                     rpmlog(RPMLOG_ERR, "AC domain setup failed for %s\n",
                            rpmteN(ctx->te));
-                    msmCancelPackage(ctx->mfx->name);
                     goto fail;
-                }
+                } else {
+                   smackLabel = 1;
+               }
             }           
             if (ctx->mfx->request) {   
                 if (ctx->mfx->request->ac_domain)
@@ -603,7 +541,14 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
                 if (ret) {
                     rpmlog(RPMLOG_ERR, "Request setup failed for %s\n",
                            rpmteN(ctx->te));
-                    msmCancelPackage(ctx->mfx->name);
+                    goto fail;
+                }
+            }
+            if (package->provides) {
+                ret = msmSetupDBusPolicies(package, ctx->mfx);
+                if (ret) {
+                    rpmlog(RPMLOG_ERR, "Setting up dbus policies for %s failed\n",
+                           rpmteN(ctx->te));
                     goto fail;
                 }
             }
@@ -614,30 +559,20 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
                 if (ret) {
                     rpmlog(RPMLOG_ERR, "Setting up smack rules for %s failed\n",
                            rpmteN(ctx->te));
-                    msmCancelPackage(ctx->mfx->name);
                     goto fail; 
                 }
             }
-            if (package->provides) {
-                ret = msmSetupDBusPolicies(package, ctx->mfx);
-                if (ret) {
-                    rpmlog(RPMLOG_ERR, "Setting up dbus policies for %s failed\n",
-                           rpmteN(ctx->te));
-                    msmCancelPackage(ctx->mfx->name);
-                    goto fail;
-                }
-            }
 
             /* last check is needed in order to catch in advance 
                the situation when no ac domain defined or requested */
             if (smackLabel == 0) {
                 rpmlog(RPMLOG_ERR, "No ac domain defined or requested for package %s. Abort.\n",   rpmteN(ctx->te));
-                msmCancelPackage(ctx->mfx->name);
                 goto fail;
             }
         }
 
     } else if (rpmteDependsOn(ctx->te)) { /* TR_REMOVED */
+        package_created = 1;
         rpmlog(RPMLOG_DEBUG, "upgrading package %s by %s\n",
                rpmteNEVR(ctx->te), rpmteNEVR(rpmteDependsOn(ctx->te)));
     } else if (mfx->sw_sources) {
@@ -647,7 +582,6 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
     }
 
     rpmlog(RPMLOG_DEBUG, "Finished with pre psm hook \n");
-    package_created = 1;
 
     goto exit;
 
@@ -663,7 +597,7 @@ rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te)
 
 rpmRC PLUGINHOOK_FSM_INIT_FUNC(const char* path, mode_t mode)
 {
-    //check if there any conflicts that prevent file being written to the disk
+    /* Check if there any conflicts that prevent file being written to the disk */
 
     fileconflict *fc;
     packagecontext *ctx = context;
@@ -679,8 +613,6 @@ rpmRC PLUGINHOOK_FSM_INIT_FUNC(const char* path, mode_t mode)
     if (cleanedPath)
         *cleanedPath = '\0';
 
-    //rpmlog(RPMLOG_DEBUG, "dupapth: %s\n", dupPath);
-
     HASH_FIND(hh, allfileconflicts, dupPath, strlen(dupPath), fc);
     msmFreePointer((void**)&dupPath);
 
@@ -688,9 +620,9 @@ rpmRC PLUGINHOOK_FSM_INIT_FUNC(const char* path, mode_t mode)
         //rpmlog(RPMLOG_DEBUG, "rpmteN(ctx->te) %s fc->pkg_name: %s\n", rpmteN(ctx->te), fc->pkg_name);
         /* There is a conflict, see if we are not allowed to overwrite */
         if ((!current || 
-           (strcmp(current->rankkey, fc->sw_source->rankkey) >= 0)) &&
+           (strcmp(current->rankkey, fc->sw_source->rankkey) > 0)) &&
            (strcmp(rpmteN(ctx->te), fc->pkg_name))) {
-            rpmlog(RPMLOG_ERR, "%s has file conflict in %s from sw source %s\n",
+            rpmlog(RPMLOG_ERR, "%s has file security conflict in %s from sw source %s\n",
                    rpmteN(ctx->te), fc->path, fc->sw_source->name);
             return RPMRC_FAIL;
         }
@@ -705,13 +637,16 @@ rpmRC PLUGINHOOK_FSM_INIT_FUNC(const char* path, mode_t mode)
 
 rpmRC PLUGINHOOK_FSM_COMMIT_FUNC(const char* path, mode_t mode, int type)
 {
+    /* Setup xattrs for the given path */
+
     packagecontext *ctx = context;
+
+    rpmlog(RPMLOG_DEBUG, "Started with FSM_COMMIT_FUNC hook for file: %s\n", path);
+
     if (!ctx) return RPMRC_FAIL;
     if (!path) return RPMRC_FAIL;
 
-    /* the type is ignored for now */
-
-    rpmlog(RPMLOG_DEBUG, "Started with FSM_COMMIT_FUNC hook for file: %s\n", path);
+    /* the type option is ignored for now */
 
     if (ctx->mfx) {
         file_x *file = xcalloc(1, sizeof(*file));
@@ -741,7 +676,6 @@ rpmRC PLUGINHOOK_FSM_COMMIT_FUNC(const char* path, mode_t mode, int type)
 rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te, int rpmrc)
 {
 
-    int ret = 0;
     packagecontext *ctx = context;
     if (!ctx) return RPMRC_FAIL;
 
@@ -754,19 +688,19 @@ rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te, int rpmrc)
         /* failure in rpm psm, rollback */
         if (rpmteType(ctx->te) == TR_ADDED)
             msmCancelPackage(ctx->mfx->name);
-        goto exit;
+        return RPMRC_FAIL;
     }
 
     if (!ctx->mfx){
         rpmlog(RPMLOG_ERR, "Manifest is missing while it should be present for the package %s\n",
                rpmteN(ctx->te));
-        goto exit;
+        return RPMRC_FAIL;
     }
 
-    if (rootSWSource) {
-        /* current is root */
-        root = context->mfx;
-    } 
+    /* if (rootSWSource) {
+        // current configuration becomes dsp
+        dsp = context->mfx;
+    } */
 
     if (rpmteType(ctx->te) == TR_REMOVED) {
         if (ctx->mfx->sw_source) {
@@ -776,7 +710,7 @@ rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te, int rpmrc)
             } else {
                 rpmlog(RPMLOG_DEBUG, "removing %s manifest data\n", 
                        rpmteN(ctx->te));
-                if (ctx->mfx->define || ctx->mfx->provides || ctx->mfx->sw_sources) {
+                if (ctx->mfx->defines || ctx->mfx->provides || ctx->mfx->sw_sources) {
                     msmRemoveRules(ctx->smack_accesses, ctx->mfx, SmackEnabled);
                 }          
                 msmRemoveConfig(ctx->mfx);
@@ -784,45 +718,27 @@ rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te, int rpmrc)
         }
     }
 
- exit:
-    current = NULL;
-
-    if (ret) {
-        return RPMRC_FAIL;
-    }
     return rpmrc;
 }
 
 rpmRC PLUGINHOOK_TSM_POST_FUNC(rpmts ts, int rpmrc)
 {
     packagecontext *ctx = context;
-    if (!ctx) return RPMRC_FAIL;
-    return RPMRC_OK;
-}
+    msmFreeInternalHashes(); // free hash structures first
+
+    if (dsp) {
+        msmSaveDeviceSecPolicyXml(dsp, ts->rootDir);
+        /* if (!rootSWSource) dsp = msmFreeManifestXml(dsp); */
+        dsp = msmFreeManifestXml(dsp);
 
-static packagecontext *msmFree(packagecontext *ctx)
-{
-    while (ctx) {
-        packagecontext *next = ctx->next;
-        msmFreePointer((void**)&ctx->data);
-        ctx->mfx = msmFreeManifestXml(ctx->mfx);
-        if (ctx->smack_accesses) smack_accesses_free(ctx->smack_accesses);
-        msmFreePointer((void**)&ctx);
-        ctx = next;
     }
-    return NULL;
+    if (!ctx) return RPMRC_FAIL;
+    return RPMRC_OK;
 }
 
 rpmRC PLUGINHOOK_CLEANUP_FUNC(void)
 {
 
-    msmFreeInternalHashes(); // free hash structures first
-
-    if (root) {
-        msmSaveDeviceSecPolicyXml(root);
-        if (!rootSWSource) root = msmFreeManifestXml(root);
-    }
-
     ts = NULL;
 
     contextsHead = contextsTail = msmFree(contextsHead);
@@ -833,6 +749,7 @@ rpmRC PLUGINHOOK_CLEANUP_FUNC(void)
         HASH_ITER(hh, allfileconflicts, fc, temp) {
             HASH_DELETE(hh, allfileconflicts, fc);
             msmFreePointer((void**)&fc->path);
+            msmFreePointer((void**)&fc->pkg_name);
             msmFreePointer((void**)&fc);
         }
     }
@@ -842,50 +759,3 @@ rpmRC PLUGINHOOK_CLEANUP_FUNC(void)
 
     return RPMRC_OK;
 }
-
-const char *msmQueryPackageFile(const char *rfor, 
-                                const char **dname, const char **pname)
-{
-    int match = 0;
-    const char *path = NULL;
-
-    if (ts) {
-        char *sep = strchr(rfor, ':');
-        if (sep && sep[1] == ':' && sep[2] == '/') 
-            path = &sep[2];
-        if (!path) return NULL;
-
-        rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, path, 0);
-        if (!mi)
-            mi = rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, path, 0);
-        if (mi) {
-            Header h;
-            const char *name, *sw_source;
-            while ((h = rpmdbNextIterator(mi))) {
-                rpmdbCheckSignals();
-                name = headerGetString(h, RPMTAG_NAME);
-                sw_source = headerGetString(h, RPMTAG_SECSWSOURCE);
-                if (name && sw_source) {
-                    match = !strncmp(rfor, name, path - rfor - 2);
-                    rpmlog(RPMLOG_DEBUG, "file %s belongs to package %s in sw source %s %s\n", 
-                           path, name, sw_source, (match ? "(matched request)" : ""));
-                    if (match) {
-                        *pname = xstrdup(name);
-                        *dname = xstrdup(sw_source);
-                        break;
-                    }
-                }
-            }
-            mi = rpmdbFreeIterator(mi);
-        }
-    }
-    return match ? path : NULL;
-}
-
-void msmFreePointer(void** ptr)
-{
-    if (*ptr)
-        free(*ptr);
-    *ptr = NULL;
-    return;
-}