Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
bool sechk_lib_check_requirement(sechk_name_value_t * req, sechk_lib_t * lib)
{
	struct stat stat_buf;

	if (!req) {
		fprintf(stderr, "Error: invalid requirement\n");
		errno = EINVAL;
		return false;
	}

	if (!lib || !lib->policy) {
		fprintf(stderr, "Error: invalid library\n");
		errno = EINVAL;
		return false;
	}

	if (!strcmp(req->name, SECHK_REQ_POLICY_CAP)) {
		if (!strcmp(req->value, SECHK_REQ_CAP_ATTRIB_NAMES)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_ATTRIB_NAMES)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_MLS)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MLS)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_SYN_RULES)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_SYN_RULES)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_RULES_LOADED)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_RULES_LOADED)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_LINE_NOS)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_LINE_NUMBERS)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_CONDITIONALS)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_CONDITIONALS)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else if (!strcmp(req->value, SECHK_REQ_CAP_MODULES)) {
			if (!qpol_policy_has_capability(apol_policy_get_qpol(lib->policy), QPOL_CAP_MODULES)) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				}
				return false;
			}
		} else {
			ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
			return false;
		}
	} else if (!strcmp(req->name, SECHK_REQ_DEFAULT_CONTEXTS)) {
#ifdef LIBSELINUX
		if (stat(selinux_default_context_path(), &stat_buf) < 0) {
			if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
				ERR(lib->policy, "Requirement %s not met.", req->name);
			}
			return false;
		}
#else
		if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
			ERR(lib->policy, "Checking requirement %s: %s", req->name, strerror(ENOTSUP));
		}
		return false;
#endif
	} else if (!strcmp(req->name, SECHK_REQ_FILE_CONTEXTS)) {
		if (!lib->fc_entries || !apol_vector_get_size(lib->fc_entries)) {
			if (lib->outputformat & ~(SECHK_OUT_QUIET)) {
				ERR(lib->policy, "Requirement %s not met.", req->name);
			}
		}
	} else if (!strcmp(req->name, SECHK_REQ_SYSTEM)) {
		if (!strcmp(req->value, SECHK_REQ_SYS_SELINUX)) {
#ifdef LIBSELINUX
			if (!is_selinux_mls_enabled() || !is_selinux_enabled()) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET))
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				return false;
			}
#else
			if (lib->outputformat & ~(SECHK_OUT_QUIET))
				ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP));
			return false;
#endif
		} else if (!strcmp(req->value, SECHK_REQ_SYS_MLS)) {
#ifdef LIBSELINUX
			if (!is_selinux_mls_enabled() || !is_selinux_enabled()) {
				if (lib->outputformat & ~(SECHK_OUT_QUIET))
					ERR(lib->policy, "Requirement %s, %s not met.", req->name, req->value);
				return false;
			}
#else
			if (lib->outputformat & ~(SECHK_OUT_QUIET))
				ERR(lib->policy, "Checking requirement %s, %s: %s", req->name, req->value, strerror(ENOTSUP));
			return false;
#endif
		} else {
			ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
			return false;
		}
	} else {
		ERR(lib->policy, "Unknown requirement: %s, %s", req->name, req->value);
		return false;
	}

	return true;
}
Ejemplo n.º 3
0
int get_ordered_context_list(const char *user,
			     security_context_t fromcon,
			     security_context_t ** list)
{
	security_context_t *reachable = NULL;
	unsigned int *ordering = NULL;
	struct context_order *co = NULL;
	char **ptr;
	int rc = 0;
	unsigned int nreach = 0, nordered = 0, freefrom = 0, i;
	FILE *fp;
	char *fname = NULL;
	size_t fname_len;
	const char *user_contexts_path = selinux_user_contexts_path();

	if (!fromcon) {
		/* Get the current context and use it for the starting context */
		rc = getcon(&fromcon);
		if (rc < 0)
			return rc;
		freefrom = 1;
	}

	/* Determine the set of reachable contexts for the user. */
	rc = security_compute_user(fromcon, user, &reachable);
	if (rc < 0) {
		/* Retry with the default SELinux user identity. */
		user = SELINUX_DEFAULTUSER;
		rc = security_compute_user(fromcon, user, &reachable);
		if (rc < 0)
			goto failsafe;
	}
	nreach = 0;
	for (ptr = reachable; *ptr; ptr++)
		nreach++;
	if (!nreach)
		goto failsafe;

	/* Initialize ordering array. */
	ordering = malloc(nreach * sizeof(unsigned int));
	if (!ordering)
		goto oom_order;
	for (i = 0; i < nreach; i++)
		ordering[i] = nreach;

	/* Determine the ordering to apply from the optional per-user config
	   and from the global config. */
	fname_len = strlen(user_contexts_path) + strlen(user) + 2;
	fname = malloc(fname_len);
	if (!fname)
		goto oom_order;
	snprintf(fname, fname_len, "%s%s", user_contexts_path, user);
	fp = fopen(fname, "r");
	if (fp) {
		__fsetlocking(fp, FSETLOCKING_BYCALLER);
		rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
				       &nordered);
		fclose(fp);
		if (rc < 0 && errno != ENOENT) {
			fprintf(stderr,
				"%s:  error in processing configuration file %s\n",
				__FUNCTION__, fname);
			/* Fall through, try global config */
		}
	}
	free(fname);
	fp = fopen(selinux_default_context_path(), "r");
	if (fp) {
		__fsetlocking(fp, FSETLOCKING_BYCALLER);
		rc = get_context_order(fp, fromcon, reachable, nreach, ordering,
				       &nordered);
		fclose(fp);
		if (rc < 0 && errno != ENOENT) {
			fprintf(stderr,
				"%s:  error in processing configuration file %s\n",
				__FUNCTION__, selinux_default_context_path());
			/* Fall through */
		}
	}

	/* Apply the ordering. */
	if (nordered) {
		co = malloc(nreach * sizeof(struct context_order));
		if (!co)
			goto oom_order;
		for (i = 0; i < nreach; i++) {
			co[i].con = reachable[i];
			co[i].order = ordering[i];
		}
		qsort(co, nreach, sizeof(struct context_order), order_compare);
		for (i = 0; i < nreach; i++)
			reachable[i] = co[i].con;
		free(co);
	}

	/* Return the ordered list. 
	   If we successfully ordered it, then only report the ordered entries
	   to the caller.  Otherwise, fall back to the entire reachable list. */
	if (nordered && nordered < nreach) {
		for (i = nordered; i < nreach; i++)
			free(reachable[i]);
		reachable[nordered] = NULL;
		rc = nordered;
	} else {
		rc = nreach;
	}

      out:
	*list = reachable;

	free(ordering);
	if (freefrom)
		freecon(fromcon);

	return rc;

      failsafe:
	/* Unable to determine a reachable context list, try to fall back to
	   the "failsafe" context to at least permit root login
	   for emergency recovery if possible. */
	freeconary(reachable);
	reachable = malloc(2 * sizeof(security_context_t));
	if (!reachable) {
		rc = -1;
		goto out;
	}
	reachable[0] = reachable[1] = 0;
	rc = get_failsafe_context(user, &reachable[0]);
	if (rc < 0) {
		freeconary(reachable);
		reachable = NULL;
		goto out;
	}
	rc = 1;			/* one context in the list */
	goto out;

      oom_order:
	/* Unable to order context list due to OOM condition.
	   Fall back to unordered reachable context list. */
	fprintf(stderr, "%s:  out of memory, unable to order list\n",
		__FUNCTION__);
	rc = nreach;
	goto out;
}