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; }
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; }
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; }