* 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>
#include <sys/stat.h>
#include <rpm/rpmfileutil.h>
-#include <rpm/rpmmacro.h>
#include <rpm/rpmpgp.h>
#include <rpm/rpmkeyring.h>
#include <rpm/rpmdb.h>
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;
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 */
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 */
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;
}
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
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");
}
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;
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;
}
}
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;
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);
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)
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;
}
}
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) {
}
rpmlog(RPMLOG_DEBUG, "Finished with pre psm hook \n");
- package_created = 1;
goto exit;
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;
if (cleanedPath)
*cleanedPath = '\0';
- //rpmlog(RPMLOG_DEBUG, "dupapth: %s\n", dupPath);
-
HASH_FIND(hh, allfileconflicts, dupPath, strlen(dupPath), fc);
msmFreePointer((void**)&dupPath);
//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;
}
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));
rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te, int rpmrc)
{
- int ret = 0;
packagecontext *ctx = context;
if (!ctx) return RPMRC_FAIL;
/* 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) {
} 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);
}
}
- 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);
HASH_ITER(hh, allfileconflicts, fc, temp) {
HASH_DELETE(hh, allfileconflicts, fc);
msmFreePointer((void**)&fc->path);
+ msmFreePointer((void**)&fc->pkg_name);
msmFreePointer((void**)&fc);
}
}
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;
-}