static rpmRC exec_coll_post_any(rpmPlugin plugin) { rpmRC rc = RPMRC_FAIL; const char *options = rpmPluginOpts(plugin); if (rpmChrootIn()) { goto exit; } if (options) { int status = system(options); if (!WIFEXITED(status) || WEXITSTATUS(status)) { rpmlog(RPMLOG_ERR, "%s collection action failed\n", rpmPluginName(plugin)); goto exit; } } rc = RPMRC_OK; exit: if (rpmChrootOut()) { rc = RPMRC_FAIL; } return rc; }
static rpmRC sepolGo(void) { semanage_handle_t *sh; int existingPolicy; char *policytype = NULL; rpmRC rc = RPMRC_FAIL; static int performed = 0; if (performed) { return RPMRC_OK; } performed = 1; if (rpmChrootIn()) { goto exit; } if (selinux_getpolicytype(&policytype) < 0) { goto exit; } sepolPreparePolicies(policiesHead, policytype); /* determine if this is the first time installing policy */ sh = semanage_handle_create(); existingPolicy = (semanage_is_managed(sh) == 1); semanage_handle_destroy(sh); /* now load the policies */ rc = sepolLoadPolicies(policiesHead); /* re-init selinux and re-read the files contexts, since things may have changed */ selinux_reset_config(); if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) { if (rpmtsSELabelInit(ts, selinux_file_context_path()) == RPMRC_OK) { /* if this was the first time installing policy, every package before * policy was installed will be mislabeled (e.g. semodule). So, relabel * the entire filesystem if this is the case */ if (!existingPolicy) { if (sepolRelabelFiles() != RPMRC_OK) { rpmlog(RPMLOG_WARNING, _("Failed to relabel filesystem. Files may be mislabeled\n")); } } } else { rpmlog(RPMLOG_WARNING, _("Failed to reload file contexts. Files may be mislabeled\n")); } } exit: if (rpmChrootOut()) { rc = RPMRC_FAIL; } _free(policytype); return rc; }
rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) { rpmpsm psm = NULL; rpmRC rc = RPMRC_FAIL; /* Psm can't fail in test mode, just return early */ if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) return RPMRC_OK; psm = rpmpsmNew(ts, te); if (rpmChrootIn() == 0) { rpmtsOpX op; psm->goal = goal; psm->goalName = pkgGoalString(goal); switch (goal) { case PKG_INSTALL: case PKG_ERASE: /* Run pre transaction element hook for all plugins */ if (rpmpluginsCallPsmPre(ts->plugins, te) != RPMRC_FAIL) { op = (goal == PKG_INSTALL) ? RPMTS_OP_INSTALL : RPMTS_OP_ERASE; rpmswEnter(rpmtsOp(psm->ts, op), 0); rc = rpmpsmNext(psm, PSM_INIT); if (!rc) rc = rpmpsmNext(psm, PSM_PRE); if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS); if (!rc) rc = rpmpsmNext(psm, PSM_POST); (void) rpmpsmNext(psm, PSM_FINI); rpmswExit(rpmtsOp(psm->ts, op), 0); } /* Run post transaction element hook for all plugins */ rpmpluginsCallPsmPost(ts->plugins, te, rc); break; case PKG_PRETRANS: case PKG_POSTTRANS: case PKG_VERIFY: psm->scriptTag = goal; rc = rpmpsmStage(psm, PSM_SCRIPT); break; default: break; } /* XXX an error here would require a full abort */ (void) rpmChrootOut(); } rpmpsmFree(psm); return rc; }
rpmRC rpmpsmRun(rpmts ts, rpmte te, pkgGoal goal) { rpmpsm psm = NULL; rpmRC rc = RPMRC_FAIL; /* Psm can't fail in test mode, just return early */ if (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) return RPMRC_OK; psm = rpmpsmNew(ts, te, goal); if (rpmChrootIn() == 0) { /* Run pre transaction element hook for all plugins */ rc = rpmpluginsCallPsmPre(rpmtsPlugins(ts), te); if (!rc) { switch (goal) { case PKG_INSTALL: rc = rpmPackageInstall(ts, psm); break; case PKG_ERASE: rc = rpmPackageErase(ts, psm); break; case PKG_PRETRANS: case PKG_POSTTRANS: case PKG_VERIFY: rc = runInstScript(psm, goal); break; case PKG_TRANSFILETRIGGERIN: rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; case PKG_TRANSFILETRIGGERUN: rc = runImmedFileTriggers(ts, te, RPMSENSE_TRIGGERUN, RPMSCRIPT_TRANSFILETRIGGER, 0); break; default: break; } } /* Run post transaction element hook for all plugins */ rpmpluginsCallPsmPost(rpmtsPlugins(ts), te, rc); /* XXX an error here would require a full abort */ (void) rpmChrootOut(); } rpmpsmFree(psm); return rc; }
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv) { rpmVSFlags vsflags, ovsflags; int ec = 0; FD_t scriptFd = fdDup(STDOUT_FILENO); /* * Open the DB + indices explicitly before possible chroot, * otherwises BDB is going to be unhappy... */ rpmtsOpenDB(ts, O_RDONLY); rpmdbOpenAll(rpmtsGetRdb(ts)); if (rpmChrootSet(rpmtsRootDir(ts)) || rpmChrootIn()) { ec = 1; goto exit; } if (qva->qva_showPackage == NULL) qva->qva_showPackage = showVerifyPackage; vsflags = rpmExpandNumeric("%{?_vsflags_verify}"); if (rpmcliQueryFlags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; if (rpmcliQueryFlags & VERIFY_SIGNATURE) vsflags |= _RPMVSF_NOSIGNATURES; if (rpmcliQueryFlags & VERIFY_HDRCHK) vsflags |= RPMVSF_NOHDRCHK; vsflags &= ~RPMVSF_NEEDPAYLOAD; rpmtsSetScriptFd(ts, scriptFd); ovsflags = rpmtsSetVSFlags(ts, vsflags); ec = rpmcliArgIter(ts, qva, argv); vsflags = rpmtsSetVSFlags(ts, ovsflags); rpmtsSetScriptFd(ts, NULL); if (qva->qva_showPackage == showVerifyPackage) qva->qva_showPackage = NULL; rpmtsEmpty(ts); if (rpmChrootOut() || rpmChrootSet(NULL)) ec = 1; exit: Fclose(scriptFd); return ec; }
int runPostUnTransFileTrigs(rpmts ts) { int i; Header trigH; struct rpmtd_s installPrefixes; rpmScript script; rpmtriggers trigs = ts->trigs2run; int nerrors = 0; if (rpmChrootIn() != 0) return -1; rpmtriggersSortAndUniq(trigs); /* Iterate over stored triggers */ for (i = 0; i < trigs->count; i++) { /* Get header containing trigger script */ trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), trigs->triggerInfo[i].hdrNum); /* Maybe package with this trigger is already uninstalled */ if (trigH == NULL) continue; /* Prepare and run script */ script = rpmScriptFromTriggerTag(trigH, RPMSENSE_TRIGGERPOSTUN, RPMSCRIPT_TRANSFILETRIGGER, trigs->triggerInfo[i].tix); headerGet(trigH, RPMTAG_INSTPREFIXES, &installPrefixes, HEADERGET_ALLOC|HEADERGET_ARGV); nerrors += runScript(ts, NULL, installPrefixes.data, script, 0, 0); rpmtdFreeData(&installPrefixes); rpmScriptFree(script); headerFree(trigH); } rpmChrootOut(); return nerrors; }
static int rpmtsPrepare(rpmts ts) { tsMembers tsmem = rpmtsMembers(ts); rpmtsi pi; rpmte p; int rc = 0; uint64_t fileCount = countFiles(ts); const char *dbhome = NULL; struct stat dbstat; fingerPrintCache fpc = fpCacheCreate(fileCount/2 + 10001, rpmtsPool(ts)); rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount); /* Reset actions, set skip for netshared paths and excluded files */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmfiles files = rpmteFiles(p); if (rpmfilesFC(files) > 0) { rpmfs fs = rpmteGetFileStates(p); /* Ensure clean state, this could get called more than once. */ rpmfsResetActions(fs); if (rpmteType(p) == TR_ADDED) { skipInstallFiles(ts, files, fs); } else { skipEraseFiles(ts, files, fs); } } rpmfilesFree(files); } rpmtsiFree(pi); /* Open rpmdb & enter chroot for fingerprinting if necessary */ if (rpmdbOpenAll(ts->rdb) || rpmChrootIn()) { rc = -1; goto exit; } rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, tsmem->orderCount); /* Add fingerprint for each file not skipped. */ fpCachePopulate(fpc, ts, fileCount); /* check against files in the rpmdb */ checkInstalledFiles(ts, fileCount, fpc); dbhome = rpmdbHome(rpmtsGetRdb(ts)); /* If we can't stat, ignore db growth. Probably not right but... */ if (dbhome && stat(dbhome, &dbstat)) dbhome = NULL; pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmfiles files = rpmteFiles(p);; if (files == NULL) continue; /* XXX can't happen */ (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); /* check files in ts against each other and update disk space needs on each partition for this package. */ handleOverlappedFiles(ts, fpc, p, files); /* Check added package has sufficient space on each partition used. */ if (rpmteType(p) == TR_ADDED) { /* * Try to estimate space needed for rpmdb growth: guess that the * db grows 4 times the header size (indexes and all). */ if (dbhome) { int64_t hsize = rpmteHeaderSize(p) * 4; rpmtsUpdateDSI(ts, dbstat.st_dev, dbhome, hsize, 0, 0, FA_CREATE); } rpmtsCheckDSIProblems(ts, p); } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); rpmfilesFree(files); } rpmtsiFree(pi); rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, tsmem->orderCount); /* return from chroot if done earlier */ if (rpmChrootOut()) rc = -1; /* On actual transaction, file info sets are not needed after this */ if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) { pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmteCleanFiles(p); } rpmtsiFree(pi); } exit: fpCacheFree(fpc); rpmtsFreeDSI(ts); return rc; }
rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, rpmscriptTriggerModes tm, int priorityClass) { int nerrors = 0, i; rpmdbIndexIterator ii; const void *key; char *pfx; size_t keylen; Header trigH; int (*matchFunc)(rpmts, rpmte, const char*, rpmsenseFlags sense); rpmTagVal priorityTag; rpmtriggers triggers = rpmtriggersCreate(10); /* Decide if we match triggers against files in te or in whole ts */ if (tm == RPMSCRIPT_FILETRIGGER) { matchFunc = matchFilesInPkg; priorityTag = RPMTAG_FILETRIGGERPRIORITIES; } else { matchFunc = matchFilesInTran; priorityTag = RPMTAG_TRANSFILETRIGGERPRIORITIES; } ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), triggerDsTag(tm)); /* Loop over all file triggers in rpmdb */ while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) { pfx = xmalloc(keylen + 1); memcpy(pfx, key, keylen); pfx[keylen] = '\0'; /* Check if file trigger is fired by any file in ts/te */ if (matchFunc(ts, te, pfx, sense)) { for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++) { struct rpmtd_s priorities; unsigned int priority; unsigned int offset = rpmdbIndexIteratorPkgOffset(ii, i); unsigned int tix = rpmdbIndexIteratorTagNum(ii, i); /* * Don't handle transaction triggers installed in current * transaction to avoid executing the same script two times. * These triggers are handled in runImmedFileTriggers(). */ if (tm == RPMSCRIPT_TRANSFILETRIGGER && (packageHashHasEntry(ts->members->removedPackages, offset) || packageHashHasEntry(ts->members->installedPackages, offset))) continue; /* Get priority of trigger from header */ trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offset); headerGet(trigH, priorityTag, &priorities, HEADERGET_MINMEM); rpmtdSetIndex(&priorities, tix); priority = *rpmtdGetUint32(&priorities); headerFree(trigH); /* Store file trigger in array */ rpmtriggersAdd(triggers, offset, tix, priority); } } free(pfx); } rpmdbIndexIteratorFree(ii); /* Sort triggers by priority, offset, trigger index */ rpmtriggersSortAndUniq(triggers); if (rpmChrootIn() != 0) { rpmtriggersFree(triggers); return RPMRC_FAIL; } /* Handle stored triggers */ for (i = 0; i < triggers->count; i++) { if (priorityClass == 1) { if (triggers->triggerInfo[i].priority < TRIGGER_PRIORITY_BOUND) continue; } else if (priorityClass == 2) { if (triggers->triggerInfo[i].priority >= TRIGGER_PRIORITY_BOUND) continue; } trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), triggers->triggerInfo[i].hdrNum); if (tm == RPMSCRIPT_FILETRIGGER) nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 0, triggers->triggerInfo[i].tix); else nerrors += runHandleTriggersInPkg(ts, te, trigH, sense, tm, 1, triggers->triggerInfo[i].tix); headerFree(trigH); } rpmtriggersFree(triggers); /* XXX an error here would require a full abort */ (void) rpmChrootOut(); return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL; }
static int rpmtsPrepare(rpmts ts) { tsMembers tsmem = rpmtsMembers(ts); rpmtsi pi; rpmte p; rpmfi fi; int rc = 0; uint64_t fileCount = countFiles(ts); fingerPrintCache fpc = fpCacheCreate(fileCount/2 + 10001); rpmFpHash ht = rpmFpHashCreate(fileCount/2+1, fpHashFunction, fpEqual, NULL, NULL); rpmDiskSpaceInfo dsi; rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount); /* Skip netshared paths, not our i18n files, and excluded docs */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { if (rpmfiFC(rpmteFI(p)) == 0) continue; if (rpmteType(p) == TR_ADDED) { skipInstallFiles(ts, p); } else { skipEraseFiles(ts, p); } } rpmtsiFree(pi); /* Open rpmdb & enter chroot for fingerprinting if necessary */ if (rpmdbOpenAll(ts->rdb) || rpmChrootIn()) { rc = -1; goto exit; } rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, tsmem->orderCount); addFingerprints(ts, fileCount, ht, fpc); /* check against files in the rpmdb */ checkInstalledFiles(ts, fileCount, ht, fpc); dsi = rpmtsDbDSI(ts); pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { if ((fi = rpmteFI(p)) == NULL) continue; /* XXX can't happen */ (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); /* check files in ts against each other and update disk space needs on each partition for this package. */ handleOverlappedFiles(ts, ht, p, fi); rpmtsUpdateDSIrpmDBSize(p, dsi); /* Check added package has sufficient space on each partition used. */ if (rpmteType(p) == TR_ADDED) { rpmtsCheckDSIProblems(ts, p); } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); } rpmtsiFree(pi); rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, tsmem->orderCount); /* return from chroot if done earlier */ if (rpmChrootOut()) rc = -1; /* File info sets, fp caches etc not needed beyond here, free 'em up. */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, 0)) != NULL) { rpmteSetFI(p, NULL); } rpmtsiFree(pi); exit: rpmFpHashFree(ht); fpCacheFree(fpc); rpmtsFreeDSI(ts); return rc; }