Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}