Exemple #1
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 #2
0
rpmRC rpmtsSELabelInit(rpmts ts, int open_status)
{
#if WITH_SELINUX
    const char * path = selinux_file_context_path();

    if (ts == NULL || path == NULL) {
	return RPMRC_FAIL;
    }

    if (open_status) {
	selinux_status_close();
	if (selinux_status_open(0) < 0) {
	    return RPMRC_FAIL;
	}
    } else if (!selinux_status_updated() && ts->selabelHandle) {
	return RPMRC_OK;
    }

    struct selinux_opt opts[] = {
	{ .type = SELABEL_OPT_PATH, .value = path}
    };
Exemple #3
0
rpmsx rpmsxNew(const char * fn, unsigned int flags)
{
    rpmsx sx = rpmsxGetPool(_rpmsxPool);

    sx->fn = NULL;
    sx->flags = flags;

#if defined(WITH_SELINUX)
    if (fn == NULL)
	fn = selinux_file_context_path();
    if (sx->flags)
	set_matchpathcon_flags(sx->flags);
    {	int rc;
	sx->fn = rpmGetPath(fn, NULL);
	rc = matchpathcon_init(sx->fn);
	/* If matchpathcon_init fails, turn off SELinux functionality. */
	if (rc < 0)
	    sx->fn = _free(sx->fn);
    }
#endif
    return rpmsxLink(sx);
}
Exemple #4
0
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
{
    rpm_tid_t tid = (rpm_tid_t) time(NULL);
    int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) ?  O_RDONLY : (O_RDWR|O_CREAT);

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));

    if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_TEST))
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers | RPMTRANS_FLAG_NOCOLLECTIONS));

    /* if SELinux isn't enabled, init fails or test run, don't bother... */
    if (!is_selinux_enabled() || (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
        rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
    }

    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
	rpmtsSELabelInit(ts, selinux_file_context_path());
    }

    /* 
     * Make sure the database is open RDWR for package install/erase.
     * Note that we initialize chroot state here even if it's just "/" as
     * this ensures we can successfully perform open(".") which is
     * required to reliably restore cwd after Lua scripts.
     */ 
    if (rpmtsOpenDB(ts, dbmode) || rpmChrootSet(rpmtsRootDir(ts)))
	return -1;

    ts->ignoreSet = ignoreSet;
    (void) rpmtsSetTid(ts, tid);

    /* Get available space on mounted file systems. */
    (void) rpmtsInitDSI(ts);

    return 0;
}
Exemple #5
0
static rpmRC sehandle_init(int open_status)
{
    const char * path = selinux_file_context_path();
    struct selinux_opt opts[] = {
	{ .type = SELABEL_OPT_PATH, .value = path }
    };
Exemple #6
0
static int init(struct selabel_handle *rec, struct selinux_opt *opts,
                unsigned n)
{
    struct saved_data *data = (struct saved_data *)rec->data;
    const char *path = NULL;
    const char *prefix = NULL;
    FILE *fp;
    FILE *localfp = NULL;
    FILE *homedirfp = NULL;
    char local_path[PATH_MAX + 1];
    char homedir_path[PATH_MAX + 1];
    char *line_buf = NULL;
    size_t line_len = 0;
    unsigned int lineno, pass, i, j, maxnspec;
    spec_t *spec_copy = NULL;
    int status = -1, baseonly = 0;
    struct stat sb;

    /* Process arguments */
    while (n--)
        switch(opts[n].type) {
        case SELABEL_OPT_PATH:
            path = opts[n].value;
            break;
        case SELABEL_OPT_SUBSET:
            prefix = opts[n].value;
            break;
        case SELABEL_OPT_BASEONLY:
            baseonly = !!opts[n].value;
            break;
        }

    /* Open the specification file. */
    if (!path)
        path = selinux_file_context_path();
    if ((fp = fopen(path, "r")) == NULL)
        return -1;
    __fsetlocking(fp, FSETLOCKING_BYCALLER);

    if (fstat(fileno(fp), &sb) < 0)
        return -1;
    if (!S_ISREG(sb.st_mode)) {
        errno = EINVAL;
        return -1;
    }

    if (!baseonly) {
        snprintf(homedir_path, sizeof(homedir_path), "%s.homedirs",
                 path);
        homedirfp = fopen(homedir_path, "r");
        if (homedirfp != NULL)
            __fsetlocking(homedirfp, FSETLOCKING_BYCALLER);

        snprintf(local_path, sizeof(local_path), "%s.local", path);
        localfp = fopen(local_path, "r");
        if (localfp != NULL)
            __fsetlocking(localfp, FSETLOCKING_BYCALLER);
    }

    /*
     * Perform two passes over the specification file.
     * The first pass counts the number of specifications and
     * performs simple validation of the input.  At the end
     * of the first pass, the spec array is allocated.
     * The second pass performs detailed validation of the input
     * and fills in the spec array.
     */
    maxnspec = UINT_MAX / sizeof(spec_t);
    for (pass = 0; pass < 2; pass++) {
        lineno = 0;
        data->nspec = 0;
        data->ncomp = 0;
        while (getline(&line_buf, &line_len, fp) > 0
                && data->nspec < maxnspec) {
            if (process_line(rec, path, prefix, line_buf,
                             pass, ++lineno) != 0)
                goto finish;
        }
        if (pass == 1) {
            status = nodups_specs(data, path);
            if (status)
                goto finish;
        }
        lineno = 0;
        if (homedirfp)
            while (getline(&line_buf, &line_len, homedirfp) > 0
                    && data->nspec < maxnspec) {
                if (process_line
                        (rec, homedir_path, prefix,
                         line_buf, pass, ++lineno) != 0)
                    goto finish;
            }

        lineno = 0;
        if (localfp)
            while (getline(&line_buf, &line_len, localfp) > 0
                    && data->nspec < maxnspec) {
                if (process_line
                        (rec, local_path, prefix, line_buf,
                         pass, ++lineno) != 0)
                    goto finish;
            }

        if (pass == 0) {
            if (data->nspec == 0) {
                status = 0;
                goto finish;
            }
            if (NULL == (data->spec_arr =
                             malloc(sizeof(spec_t) * data->nspec)))
                goto finish;
            memset(data->spec_arr, 0, sizeof(spec_t)*data->nspec);
            maxnspec = data->nspec;
            rewind(fp);
            if (homedirfp)
                rewind(homedirfp);
            if (localfp)
                rewind(localfp);
        }
    }
    free(line_buf);

    /* Move exact pathname specifications to the end. */
    spec_copy = malloc(sizeof(spec_t) * data->nspec);
    if (!spec_copy)
        goto finish;
    j = 0;
    for (i = 0; i < data->nspec; i++)
        if (data->spec_arr[i].hasMetaChars)
            memcpy(&spec_copy[j++],
                   &data->spec_arr[i], sizeof(spec_t));
    for (i = 0; i < data->nspec; i++)
        if (!data->spec_arr[i].hasMetaChars)
            memcpy(&spec_copy[j++],
                   &data->spec_arr[i], sizeof(spec_t));
    free(data->spec_arr);
    data->spec_arr = spec_copy;

    status = 0;
finish:
    fclose(fp);
    if (data->spec_arr != spec_copy)
        free(data->spec_arr);
    if (homedirfp)
        fclose(homedirfp);
    if (localfp)
        fclose(localfp);
    return status;
}
Exemple #7
0
static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
		unsigned n)
{
	struct saved_data *data = (struct saved_data *)rec->data;
	const char *path = NULL;
	const char *prefix = NULL;
	char subs_file[PATH_MAX + 1];
	int status = -1, baseonly = 0;

	/* Process arguments */
	while (n--)
		switch(opts[n].type) {
		case SELABEL_OPT_PATH:
			path = opts[n].value;
			break;
		case SELABEL_OPT_SUBSET:
			prefix = opts[n].value;
			break;
		case SELABEL_OPT_BASEONLY:
			baseonly = !!opts[n].value;
			break;
		}

	/* Process local and distribution substitution files */
	if (!path) {
		rec->dist_subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->dist_subs);
		rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs);
		path = selinux_file_context_path();
	} else {
		snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path);
		rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs);
		snprintf(subs_file, sizeof(subs_file), "%s.subs", path);
		rec->subs = selabel_subs_init(subs_file, rec->subs);
	}

	rec->spec_file = strdup(path);

	/*
	 * The do detailed validation of the input and fill the spec array
	 */
	status = process_file(path, NULL, rec, prefix);
	if (status)
		goto finish;

	if (rec->validating) {
		status = nodups_specs(data, path);
		if (status)
			goto finish;
	}

	if (!baseonly) {
		status = process_file(path, "homedirs", rec, prefix);
		if (status && errno != ENOENT)
			goto finish;

		status = process_file(path, "local", rec, prefix);
		if (status && errno != ENOENT)
			goto finish;
	}

	status = sort_specs(data);

finish:
	if (status)
		free(data->spec_arr);
	return status;
}
Exemple #8
0
static JSBool
rpmsx_getprop(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmsxClass, NULL);
    jsint tiny = JSVAL_TO_INT(id);
#if defined(WITH_SELINUX)
    security_context_t con = NULL;
#endif

    /* XXX the class has ptr == NULL, instances have ptr != NULL. */
    if (ptr == NULL)
	return JS_TRUE;

    switch (tiny) {
    case _DEBUG:
	*vp = INT_TO_JSVAL(_debug);
	break;
#if defined(WITH_SELINUX)
    case _CURRENT:	*vp = _GET_CON(!getcon(&con));			break;
    case _PID:		*vp = _GET_CON(!getpidcon(getpid(), &con));	break;
    case _PPID:		*vp = _GET_CON(!getpidcon(getppid(), &con));	break;
    case _PREV:		*vp = _GET_CON(!getprevcon(&con));		break;
    case _EXEC:		*vp = _GET_CON(!getexeccon(&con));		break;
    case _FSCREATE:	*vp = _GET_CON(!getfscreatecon(&con));		break;
    case _KEYCREATE:	*vp = _GET_CON(!getkeycreatecon(&con));		break;
    case _SOCKCREATE:	*vp = _GET_CON(!getsockcreatecon(&con));	break;
    case _ENFORCE:	*vp = INT_TO_JSVAL(security_getenforce());	break;
    case _DENY:		*vp = INT_TO_JSVAL(security_deny_unknown());	break;
    case _POLICYVERS:	*vp = INT_TO_JSVAL(security_policyvers());	break;
    case _ENABLED:	*vp = INT_TO_JSVAL(is_selinux_enabled());	break;
    case _MLSENABLED:	*vp = INT_TO_JSVAL(is_selinux_mls_enabled());	break;
#ifdef	NOTYET
    case _BOOLS:	*vp = ;	break;
#endif
    case _ROOT:		*vp = _GET_STR(selinux_policy_root());		break;
    case _BINARY:	*vp = _GET_STR(selinux_binary_policy_path());	break;
    case _FAILSAFE:	*vp = _GET_STR(selinux_failsafe_context_path());break;
    case _REMOVABLE:	*vp = _GET_STR(selinux_removable_context_path());break;
    case _DEFAULT:	*vp = _GET_STR(selinux_default_context_path());	break;
    case _USER:		*vp = _GET_STR(selinux_user_contexts_path());	break;
    case _FCON:		*vp = _GET_STR(selinux_file_context_path());	break;
    case _FCONHOME:	*vp = _GET_STR(selinux_file_context_homedir_path());break;
    case _FCONLOCAL:	*vp = _GET_STR(selinux_file_context_local_path());break;
    case _FCONSUBS:	*vp = _GET_STR(selinux_file_context_subs_path());break;
    case _HOMEDIR:	*vp = _GET_STR(selinux_homedir_context_path());	break;
    case _MEDIA:	*vp = _GET_STR(selinux_media_context_path());	break;
    case _VIRTDOMAIN:	*vp = _GET_STR(selinux_virtual_domain_context_path());break;
    case _VIRTIMAGE:	*vp = _GET_STR(selinux_virtual_image_context_path());break;
    case _X:		*vp = _GET_STR(selinux_x_context_path());	break;
    case _CONTEXTS:	*vp = _GET_STR(selinux_contexts_path());	break;
    case _SECURETTY:	*vp = _GET_STR(selinux_securetty_types_path());	break;
    case _BOOLEANS:	*vp = _GET_STR(selinux_booleans_path());	break;
    case _CUSTOMTYPES:	*vp = _GET_STR(selinux_customizable_types_path());break;
    case _USERS:	*vp = _GET_STR(selinux_users_path());		break;
    case _USERSCONF:	*vp = _GET_STR(selinux_usersconf_path());	break;
    case _XLATIONS:	*vp = _GET_STR(selinux_translations_path());	break;
    case _COLORS:	*vp = _GET_STR(selinux_colors_path());		break;
    case _NETFILTER:	*vp = _GET_STR(selinux_netfilter_context_path());break;
    case _PATH:		*vp = _GET_STR(selinux_path());			break;
#endif
    default:
	break;
    }

#if defined(WITH_SELINUX)
    if (con) {
	freecon(con);
	con = NULL;
    }
#endif

    return JS_TRUE;
}