static void display_boolean(void)
{
	char **bools;
	int i, active, pending, nbool;

	if (security_get_boolean_names(&bools, &nbool) < 0)
		return;

	puts("\nPolicy booleans:");

	for (i = 0; i < nbool; i++) {
		active = security_get_boolean_active(bools[i]);
		if (active < 0)
			goto skip;
		pending = security_get_boolean_pending(bools[i]);
		if (pending < 0)
			goto skip;
		printf(COL_FMT "%s",
		       bools[i], active == 0 ? "off" : "on");
		if (active != pending)
			printf(" (%sactivate pending)", pending == 0 ? "in" : "");
		bb_putchar('\n');
 skip:
		if (ENABLE_FEATURE_CLEAN_UP)
			free(bools[i]);
	}
	if (ENABLE_FEATURE_CLEAN_UP)
		free(bools);
}
示例#2
0
void
SELinuxExtensionInit(INITARGS)
{
    ExtensionEntry *extEntry;

    /* Check SELinux mode on system, configuration file, and boolean */
    if (!is_selinux_enabled()) {
	LogMessage(X_INFO, "SELinux: Disabled on system\n");
	return;
    }
    if (selinuxEnforcingState == SELINUX_MODE_DISABLED) {
	LogMessage(X_INFO, "SELinux: Disabled in configuration file\n");
	return;
    }
    if (!security_get_boolean_active("xserver_object_manager")) {
	LogMessage(X_INFO, "SELinux: Disabled by boolean\n");
        return;
    }

    /* Set up XACE hooks */
    SELinuxLabelInit();
    SELinuxFlaskInit();

    /* Add extension to server */
    extEntry = AddExtension(SELINUX_EXTENSION_NAME,
			    SELinuxNumberEvents, SELinuxNumberErrors,
			    ProcSELinuxDispatch, SProcSELinuxDispatch,
			    SELinuxResetProc, StandardMinorOpcode);

    AddExtensionAlias("Flask", extEntry);
}
示例#3
0
static void rollback(SELboolean *boollist, int end)
{
    int i;

        for(i=0; i<end; i++)
                security_set_boolean(boollist[i].name,
                        security_get_boolean_active(boollist[i].name));
}
示例#4
0
/* Attempt to rollback the transaction. No need to check error
   codes since this is rolling back something that blew up. */
void rollback(int argc, char **argv)
{
	int i;

	for (i = 1; i < argc; i++)
		security_set_boolean(argv[i],
				     security_get_boolean_active(argv[i]));
	exit(1);
}
示例#5
0
int getsebool_main(int argc, char **argv)
{
	int i, rc = 0, active, pending, len = 0;
	char **names;
	unsigned opt;

	selinux_or_die();
	opt = getopt32(argv, "a");

	if (opt) { /* -a */
		if (argc > 2)
			bb_show_usage();

		rc = security_get_boolean_names(&names, &len);
		if (rc)
			bb_perror_msg_and_die("can't get boolean names");

		if (!len) {
			puts("No booleans");
			return 0;
		}
	}

	if (!len) {
		if (argc < 2)
			bb_show_usage();
		len = argc - 1;
		names = xmalloc(sizeof(char *) * len);
		for (i = 0; i < len; i++)
			names[i] = xstrdup(argv[i + 1]);
	}

	for (i = 0; i < len; i++) {
		active = security_get_boolean_active(names[i]);
		if (active < 0) {
			bb_error_msg_and_die("error getting active value for %s", names[i]);
		}
		pending = security_get_boolean_pending(names[i]);
		if (pending < 0) {
			bb_error_msg_and_die("error getting pending value for %s", names[i]);
		}
		printf("%s --> %s", names[i], (active ? "on" : "off"));
		if (pending != active)
			printf(" pending: %s", (pending ? "on" : "off"));
		bb_putchar('\n');
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		for (i = 0; i < len; i++)
			free(names[i]);
		free(names);
	}

	return rc;
}
示例#6
0
/* Attempt to change the label of PATH to TCON.  If OPTIONAL is true,
 * return 1 if labelling was not possible.  Otherwise, require a label
 * change, and return 0 for success, -1 for failure.  */
static int
SELinuxSetFileconHelper(const char *path, char *tcon, bool optional)
{
    security_context_t econ;

    VIR_INFO("Setting SELinux context on '%s' to '%s'", path, tcon);

    if (setfilecon(path, tcon) < 0) {
        int setfilecon_errno = errno;

        if (getfilecon(path, &econ) >= 0) {
            if (STREQ(tcon, econ)) {
                freecon(econ);
                /* It's alright, there's nothing to change anyway. */
                return optional ? 1 : 0;
            }
            freecon(econ);
        }

        /* if the error complaint is related to an image hosted on
         * an nfs mount, or a usbfs/sysfs filesystem not supporting
         * labelling, then just ignore it & hope for the best.
         * The user hopefully set one of the necessary SELinux
         * virt_use_{nfs,usb,pci}  boolean tunables to allow it...
         */
        if (setfilecon_errno != EOPNOTSUPP && setfilecon_errno != ENOTSUP) {
            virReportSystemError(setfilecon_errno,
                                 _("unable to set security context '%s' on '%s'"),
                                 tcon, path);
            if (security_getenforce() == 1)
                return -1;
        } else {
            const char *msg;
            if ((virStorageFileIsSharedFSType(path,
                                              VIR_STORAGE_FILE_SHFS_NFS) == 1) &&
                security_get_boolean_active("virt_use_nfs") != 1) {
                msg = _("Setting security context '%s' on '%s' not supported. "
                        "Consider setting virt_use_nfs");
               if (security_getenforce() == 1)
                   VIR_WARN(msg, tcon, path);
               else
                   VIR_INFO(msg, tcon, path);
            } else {
                VIR_INFO("Setting security context '%s' on '%s' not supported",
                         tcon, path);
            }
            if (optional)
                return 1;
        }
    }
    return 0;
}
/*
 * Function: getBooleanValue
 * Purpose: Gets the value for the given SELinux boolean name.
 * Parameters:
 *            String: The name of the SELinux boolean.
 * Returns: a boolean: (true) boolean is set or (false) it is not.
 * Exceptions: None
 */
static jboolean getBooleanValue(JNIEnv *env, jobject, jstring nameStr) {
    if (isSELinuxDisabled) {
        return false;
    }

    if (nameStr == NULL) {
        return false;
    }

    ScopedUtfChars name(env, nameStr);
    int ret = security_get_boolean_active(name.c_str());

    ALOGV("getBooleanValue(%s) => %d", name.c_str(), ret);
    return (ret == 1) ? true : false;
}
示例#8
0
static int
init_map(void)
{
#ifdef MESA_SELINUX
   if (is_selinux_enabled()) {
      if (!security_get_boolean_active("allow_execmem") ||
	  !security_get_boolean_pending("allow_execmem"))
         return 0;
   }
#endif

   if (!exec_mem)
      exec_mem = mmap(NULL, EXEC_MAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
		      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

   return (exec_mem != MAP_FAILED);
}
  /*
   * Function: getBooleanValue
   * Purpose: Gets the value for the given SELinux boolean name.
   * Parameters:
   *            String: The name of the SELinux boolean.
   * Returns: a boolean: (true) boolean is set or (false) it is not.
   * Exceptions: None
   */
  static jboolean getBooleanValue(JNIEnv *env, jobject clazz, jstring name) {
#ifdef HAVE_SELINUX
    if (isSELinuxDisabled)
      return false;

    const char *boolean_name;
    int ret;

    if (name == NULL)
      return false;
    boolean_name = env->GetStringUTFChars(name, NULL);
    ret = security_get_boolean_active(boolean_name);
    env->ReleaseStringUTFChars(name, boolean_name);
    return (ret == 1) ? true : false;
#else
    return false;
#endif
  }
示例#10
0
文件: trace.c 项目: jkkm/ltrace
void
trace_fail_warning(pid_t pid)
{
	/* This was adapted from GDB.  */
#ifdef HAVE_LIBSELINUX
	static int checked = 0;
	if (checked)
		return;
	checked = 1;

	/* -1 is returned for errors, 0 if it has no effect, 1 if
	 * PTRACE_ATTACH is forbidden.  */
	if (security_get_boolean_active("deny_ptrace") == 1)
		fprintf(stderr,
"The SELinux boolean 'deny_ptrace' is enabled, which may prevent ltrace from\n"
"tracing other processes.  You can disable this process attach protection by\n"
"issuing 'setsebool deny_ptrace=0' in the superuser context.\n");
#endif /* HAVE_LIBSELINUX */
}
示例#11
0
static int
init_heap(void)
{
#ifdef MESA_SELINUX
    if (is_selinux_enabled()) {
        if (!security_get_boolean_active("allow_execmem") ||
                !security_get_boolean_pending("allow_execmem"))
            return 0;
    }
#endif

    if (!exec_heap)
        exec_heap = mmInit( 0, EXEC_HEAP_SIZE );

    if (!exec_mem)
        exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE,
                                          PROT_EXEC | PROT_READ | PROT_WRITE,
                                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    return (exec_mem != NULL);
}
示例#12
0
static int get_selinuxboolean(SEXP_t *ut_ent, probe_ctx *ctx)
{
	int err = 1, active, pending, len, i;
	SEXP_t *boolean, *item;
	char **booleans;

	if ( ! is_selinux_enabled()) {
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_NOT_APPLICABLE);
		return 0;
	}

	if (security_get_boolean_names(&booleans, &len) == -1) {
		probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_ERROR);
		return err;
	}

	for (i = 0; i < len; i++) {
		boolean = SEXP_string_new(booleans[i], strlen(booleans[i]));
		if (probe_entobj_cmp(ut_ent, boolean) == OVAL_RESULT_TRUE) {
			active = security_get_boolean_active(booleans[i]);
			pending = security_get_boolean_pending(booleans[i]);
			item = probe_item_create(
				OVAL_LINUX_SELINUXBOOLEAN, NULL,
				"name", OVAL_DATATYPE_SEXP, boolean,
				"current_status",  OVAL_DATATYPE_BOOLEAN, active,
				"pending_status", OVAL_DATATYPE_BOOLEAN, pending,
			      NULL);
			probe_item_collect(ctx, item);
		}
		SEXP_free(boolean);
	}

	for (i = 0; i < len; i++)
		free(booleans[i]);
        free(booleans);

	return 0;
}
示例#13
0
static int seapp_context_lookup(enum seapp_kind kind,
				uid_t uid,
				int isSystemServer,
				const char *seinfo,
				const char *pkgname,
				const char *path,
				context_t ctx)
{
	const char *username = NULL;
	struct seapp_context *cur = NULL;
	int i;
	size_t n;
	uid_t userid;
	uid_t appid;

	__selinux_once(once, seapp_context_init);

	userid = uid / AID_USER;
	appid = uid % AID_USER;
	if (appid < AID_APP) {
		for (n = 0; n < android_id_count; n++) {
			if (android_ids[n].aid == appid) {
				username = android_ids[n].name;
				break;
			}
		}
		if (!username)
			goto err;
	} else if (appid < AID_ISOLATED_START) {
		username = "******";
		appid -= AID_APP;
	} else {
		username = "******";
		appid -= AID_ISOLATED_START;
	}

	if (appid >= CAT_MAPPING_MAX_ID || userid >= CAT_MAPPING_MAX_ID)
		goto err;

	for (i = 0; i < nspec; i++) {
		cur = seapp_contexts[i];

		if (cur->isSystemServer != isSystemServer)
			continue;

		if (cur->user.str) {
			if (cur->user.is_prefix) {
				if (strncasecmp(username, cur->user.str, cur->user.len-1))
					continue;
			} else {
				if (strcasecmp(username, cur->user.str))
					continue;
			}
		}

		if (cur->seinfo) {
			if (!seinfo || strcasecmp(seinfo, cur->seinfo))
				continue;
		}

		if (cur->name.str) {
			if(!pkgname)
				continue;

			if (cur->name.is_prefix) {
				if (strncasecmp(pkgname, cur->name.str, cur->name.len-1))
					continue;
			} else {
				if (strcasecmp(pkgname, cur->name.str))
					continue;
			}
		}

		if (cur->path.str) {
			if (!path)
				continue;

			if (cur->path.is_prefix) {
				if (strncmp(path, cur->path.str, cur->path.len-1))
					continue;
			} else {
				if (strcmp(path, cur->path.str))
					continue;
			}
		}

		if (kind == SEAPP_TYPE && !cur->type)
			continue;
		else if (kind == SEAPP_DOMAIN && !cur->domain)
			continue;

		if (cur->sebool) {
			int value = security_get_boolean_active(cur->sebool);
			if (value == 0)
				continue;
			else if (value == -1) {
				selinux_log(SELINUX_ERROR, \
				"Could not find boolean: %s ", cur->sebool);
				goto err;
			}
		}

		if (kind == SEAPP_TYPE) {
			if (context_type_set(ctx, cur->type))
				goto oom;
		} else if (kind == SEAPP_DOMAIN) {
			if (context_type_set(ctx, cur->domain))
				goto oom;
		}

		if (cur->levelFrom != LEVELFROM_NONE) {
			char level[255];
			switch (cur->levelFrom) {
			case LEVELFROM_APP:
				snprintf(level, sizeof level, "s0:c%u,c%u",
					 appid & 0xff,
					 256 + (appid>>8 & 0xff));
				break;
			case LEVELFROM_USER:
				snprintf(level, sizeof level, "s0:c%u,c%u",
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			case LEVELFROM_ALL:
				snprintf(level, sizeof level, "s0:c%u,c%u,c%u,c%u",
					 appid & 0xff,
					 256 + (appid>>8 & 0xff),
					 512 + (userid & 0xff),
					 768 + (userid>>8 & 0xff));
				break;
			default:
				goto err;
			}
			if (context_range_set(ctx, level))
				goto oom;
		} else if (cur->level) {
示例#14
0
int main(int argc, char **argv)
{
	/* these vars are reused several times */
	int rc, opt, i, c;
	char *context, *root_path;

	/* files that need context checks */
	char *fc[MAX_CHECK];
	char *cterm = ttyname(0);
	int nfc = 0;
	struct stat m;

	/* processes that need context checks */
	char *pc[MAX_CHECK];
	int npc = 0;

	/* booleans */
	char **bools;
	int nbool;

	int verbose = 0;
	int show_bools = 0;

	/* policy */
	const char *pol_name, *root_dir;
	char *pol_path;


	while (1) {
		opt = getopt(argc, argv, "vb");
		if (opt == -1)
			break;
		switch (opt) {
		case 'v':
			verbose = 1;
			break;
		case 'b':
			show_bools = 1;
			break;
		default:
			/* invalid option */
			printf("\nUsage: %s [OPTION]\n\n", basename(argv[0]));
			printf("  -v  Verbose check of process and file contexts.\n");
			printf("  -b  Display current state of booleans.\n");
			printf("\nWithout options, show SELinux status.\n");
			return -1;
		}
	}
	printf_tab("SELinux status:");
	rc = is_selinux_enabled();

	switch (rc) {
	case 1:
		printf("enabled\n");
		break;
	case 0:
		printf("disabled\n");
		return 0;
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		return 0;
		break;
	}

	printf_tab("SELinuxfs mount:");
	if (selinux_mnt != NULL) {
		printf("%s\n", selinux_mnt);
	} else {
		printf("not mounted\n\n");
		printf("Please mount selinuxfs for proper results.\n");
		return -1;
	}

	printf_tab("SELinux root directory:");
	root_dir = selinux_path();
	if (root_dir == NULL) {
		printf("error (%s)\n", strerror(errno));
		return -1;
	}
	/* The path has a trailing '/' so duplicate to edit */
	root_path = strdup(root_dir);
	if (!root_path) {
		printf("malloc error (%s)\n", strerror(errno));
		return -1;
	}
	/* actually blank the '/' */
	root_path[strlen(root_path) - 1] = '\0';
	printf("%s\n", root_path);
	free(root_path);

	/* Dump all the path information */
	printf_tab("Loaded policy name:");
	pol_path = strdup(selinux_policy_root());
	if (pol_path) {
		pol_name = basename(pol_path);
		puts(pol_name);
		free(pol_path);
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Current mode:");
	rc = security_getenforce();
	switch (rc) {
	case 1:
		printf("enforcing\n");
		break;
	case 0:
		printf("permissive\n");
		break;
	default:
		printf("unknown (%s)\n", strerror(errno));
		break;
	}

	printf_tab("Mode from config file:");
	if (selinux_getenforcemode(&rc) == 0) {
		switch (rc) {
		case 1:
			printf("enforcing\n");
			break;
		case 0:
			printf("permissive\n");
			break;
		case -1:
			printf("disabled\n");
			break;
		}
	} else {
		printf("error (%s)\n", strerror(errno));
	}

	printf_tab("Policy MLS status:");
	rc = is_selinux_mls_enabled();
	switch (rc) {
		case 0:
			printf("disabled\n");
			break;
		case 1:
			printf("enabled\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	printf_tab("Policy deny_unknown status:");
	rc = security_deny_unknown();
	switch (rc) {
		case 0:
			printf("allowed\n");
			break;
		case 1:
			printf("denied\n");
			break;
		default:
			printf("error (%s)\n", strerror(errno));
			break;
	}

	rc = security_policyvers();
	printf_tab("Max kernel policy version:");
	if (rc < 0)
		printf("unknown (%s)\n", strerror(errno));
	else
		printf("%d\n", rc);


	if (show_bools) {
		/* show booleans */
		if (security_get_boolean_names(&bools, &nbool) >= 0) {
			printf("\nPolicy booleans:\n");

			for (i = 0; i < nbool; i++) {
				if (strlen(bools[i]) + 1 > COL)
					COL = strlen(bools[i]) + 1;
			}
			for (i = 0; i < nbool; i++) {
				printf_tab(bools[i]);

				rc = security_get_boolean_active(bools[i]);
				switch (rc) {
				case 1:
					printf("on");
					break;
				case 0:
					printf("off");
					break;
				default:
					printf("unknown (%s)", strerror(errno));
					break;
				}
				c = security_get_boolean_pending(bools[i]);
				if (c != rc)
					switch (c) {
					case 1:
						printf(" (activate pending)");
						break;
					case 0:
						printf(" (inactivate pending)");
						break;
					default:
						printf(" (pending error: %s)",
						       strerror(errno));
						break;
					}
				printf("\n");

				/* free up the booleans */
				free(bools[i]);
			}
			free(bools);
		}
	}
	/* only show contexts if -v is given */
	if (!verbose)
		return 0;

	load_checks(pc, &npc, fc, &nfc);

	printf("\nProcess contexts:\n");

	printf_tab("Current context:");
	if (getcon(&context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	printf_tab("Init context:");
	if (getpidcon(1, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else
		printf("unknown (%s)\n", strerror(errno));

	for (i = 0; i < npc; i++) {
		rc = pidof(pc[i]);
		if (rc > 0) {
			if (getpidcon(rc, &context) < 0)
				continue;

			printf_tab(pc[i]);
			printf("%s\n", context);
			freecon(context);
		}
	}

	printf("\nFile contexts:\n");

	/* controlling term */
	printf_tab("Controlling terminal:");
	if (lgetfilecon(cterm, &context) >= 0) {
		printf("%s\n", context);
		freecon(context);
	} else {
		printf("unknown (%s)\n", strerror(errno));
	}

	for (i = 0; i < nfc; i++) {
		if (lgetfilecon(fc[i], &context) >= 0) {
			printf_tab(fc[i]);

			/* check if this is a symlink */
			if (lstat(fc[i], &m)) {
				printf
				    ("%s (could not check link status (%s)!)\n",
				     context, strerror(errno));
				freecon(context);
				continue;
			}
			if (S_ISLNK(m.st_mode)) {
				/* print link target context */
				printf("%s -> ", context);
				freecon(context);

				if (getfilecon(fc[i], &context) >= 0) {
					printf("%s\n", context);
					freecon(context);
				} else {
					printf("unknown (%s)\n",
					       strerror(errno));
				}
			} else {
				printf("%s\n", context);
				freecon(context);
			}
		}
	}

	return 0;
}
示例#15
0
int selinux_mkload_policy(int preservebools)
{	
	int kernvers = security_policyvers();
	int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers;
	int setlocaldefs = load_setlocaldefs;
	char path[PATH_MAX];
	struct stat sb;
	struct utsname uts;
	size_t size;
	void *map, *data;
	int fd, rc = -1, prot;
	sepol_policydb_t *policydb;
	sepol_policy_file_t *pf;
	int usesepol = 0;
	int (*vers_max)(void) = NULL;
	int (*vers_min)(void) = NULL;
	int (*policy_file_create)(sepol_policy_file_t **) = NULL;
	void (*policy_file_free)(sepol_policy_file_t *) = NULL;
	void (*policy_file_set_mem)(sepol_policy_file_t *, char*, size_t) = NULL;
	int (*policydb_create)(sepol_policydb_t **) = NULL;
	void (*policydb_free)(sepol_policydb_t *) = NULL;
	int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) = NULL;
	int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = NULL;
	int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, void **, size_t *) = NULL;
	int (*genbools_array)(void *data, size_t len, char **names, int *values, int nel) = NULL;
	int (*genusers)(void *data, size_t len, const char *usersdir, void **newdata, size_t * newlen) = NULL;
	int (*genbools)(void *data, size_t len, char *boolpath) = NULL;

#ifdef SHARED
	char *errormsg = NULL;
	void *libsepolh = NULL;
	libsepolh = dlopen("libsepol.so.1", RTLD_NOW);
	if (libsepolh) {
		usesepol = 1;
		dlerror();
#define DLERR() if ((errormsg = dlerror())) goto dlclose;
		vers_max = dlsym(libsepolh, "sepol_policy_kern_vers_max");
		DLERR();
		vers_min = dlsym(libsepolh, "sepol_policy_kern_vers_min");
		DLERR();

		policy_file_create = dlsym(libsepolh, "sepol_policy_file_create");
		DLERR();
		policy_file_free = dlsym(libsepolh, "sepol_policy_file_free");
		DLERR();
		policy_file_set_mem = dlsym(libsepolh, "sepol_policy_file_set_mem");
		DLERR();
		policydb_create = dlsym(libsepolh, "sepol_policydb_create");
		DLERR();
		policydb_free = dlsym(libsepolh, "sepol_policydb_free");
		DLERR();
		policydb_read = dlsym(libsepolh, "sepol_policydb_read");
		DLERR();
		policydb_set_vers = dlsym(libsepolh, "sepol_policydb_set_vers");
		DLERR();
		policydb_to_image = dlsym(libsepolh, "sepol_policydb_to_image");
		DLERR();
		genbools_array = dlsym(libsepolh, "sepol_genbools_array");
		DLERR();
		genusers = dlsym(libsepolh, "sepol_genusers");
		DLERR();
		genbools = dlsym(libsepolh, "sepol_genbools");
		DLERR();

#undef DLERR
	}
#else
	usesepol = 1;
	vers_max = sepol_policy_kern_vers_max;
	vers_min = sepol_policy_kern_vers_min;
	policy_file_create = sepol_policy_file_create;
	policy_file_free = sepol_policy_file_free;
	policy_file_set_mem = sepol_policy_file_set_mem;
	policydb_create = sepol_policydb_create;
	policydb_free = sepol_policydb_free;
	policydb_read = sepol_policydb_read;
	policydb_set_vers = sepol_policydb_set_vers;
	policydb_to_image = sepol_policydb_to_image;
	genbools_array = sepol_genbools_array;
	genusers = sepol_genusers;
	genbools = sepol_genbools;

#endif

	/*
	 * Check whether we need to support local boolean and user definitions.
	 */
	if (setlocaldefs) {
		if (access(selinux_booleans_path(), F_OK) == 0)
			goto checkbool;
		snprintf(path, sizeof path, "%s.local", selinux_booleans_path());
		if (access(path, F_OK) == 0)
			goto checkbool;
		snprintf(path, sizeof path, "%s/local.users", selinux_users_path());
		if (access(path, F_OK) == 0)
			goto checkbool;
		/* No local definition files, so disable setlocaldefs. */
		setlocaldefs = 0;
	}

checkbool:
	/* 
	 * As of Linux 2.6.22, the kernel preserves boolean
	 * values across a reload, so we do not need to 
	 * preserve them in userspace.
	 */
	if (preservebools && uname(&uts) == 0 && strverscmp(uts.release, "2.6.22") >= 0)
		preservebools = 0;

	if (usesepol) {
		maxvers = vers_max();
		minvers = vers_min();
		if (!setlocaldefs && !preservebools)
			maxvers = max(kernvers, maxvers);
	}

	vers = maxvers;
      search:
	snprintf(path, sizeof(path), "%s.%d",
		 selinux_binary_policy_path(), vers);
	fd = open(path, O_RDONLY);
	while (fd < 0 && errno == ENOENT
	       && --vers >= minvers) {
		/* Check prior versions to see if old policy is available */
		snprintf(path, sizeof(path), "%s.%d",
			 selinux_binary_policy_path(), vers);
		fd = open(path, O_RDONLY);
	}
	if (fd < 0) {
		fprintf(stderr,
			"SELinux:  Could not open policy file <= %s.%d:  %s\n",
			selinux_binary_policy_path(), maxvers, strerror(errno));
		goto dlclose;
	}

	if (fstat(fd, &sb) < 0) {
		fprintf(stderr,
			"SELinux:  Could not stat policy file %s:  %s\n",
			path, strerror(errno));
		goto close;
	}

	prot = PROT_READ;
	if (setlocaldefs || preservebools)
		prot |= PROT_WRITE;

	size = sb.st_size;
	data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0);
	if (map == MAP_FAILED) {
		fprintf(stderr,
			"SELinux:  Could not map policy file %s:  %s\n",
			path, strerror(errno));
		goto close;
	}

	if (vers > kernvers && usesepol) {
		/* Need to downgrade to kernel-supported version. */
		if (policy_file_create(&pf))
			goto unmap;
		if (policydb_create(&policydb)) {
			policy_file_free(pf);
			goto unmap;
		}
		policy_file_set_mem(pf, data, size);
		if (policydb_read(policydb, pf)) {
			policy_file_free(pf);
			policydb_free(policydb);
			goto unmap;
		}
		if (policydb_set_vers(policydb, kernvers) ||
		    policydb_to_image(NULL, policydb, &data, &size)) {
			/* Downgrade failed, keep searching. */
			fprintf(stderr,
				"SELinux:  Could not downgrade policy file %s, searching for an older version.\n",
				path);
			policy_file_free(pf);
			policydb_free(policydb);
			munmap(map, sb.st_size);
			close(fd);
			vers--;
			goto search;
		}
		policy_file_free(pf);
		policydb_free(policydb);
	}

	if (usesepol) {
		if (setlocaldefs) {
			void *olddata = data;
			size_t oldsize = size;
			rc = genusers(olddata, oldsize, selinux_users_path(),
				      &data, &size);
			if (rc < 0) {
				/* Fall back to the prior image if genusers failed. */
				data = olddata;
				size = oldsize;
				rc = 0;
			} else {
				if (olddata != map)
					free(olddata);
			}
		}
		
#ifndef DISABLE_BOOL
		if (preservebools) {
			int *values, len, i;
			char **names;
			rc = security_get_boolean_names(&names, &len);
			if (!rc) {
				values = malloc(sizeof(int) * len);
				if (!values)
					goto unmap;
				for (i = 0; i < len; i++)
					values[i] =
						security_get_boolean_active(names[i]);
				(void)genbools_array(data, size, names, values,
						     len);
				free(values);
				for (i = 0; i < len; i++)
					free(names[i]);
				free(names);
			}
		} else if (setlocaldefs) {
			(void)genbools(data, size,
				       (char *)selinux_booleans_path());
		}
#endif
	}


	rc = security_load_policy(data, size);
	
	if (rc)
		fprintf(stderr,
			"SELinux:  Could not load policy file %s:  %s\n",
			path, strerror(errno));

      unmap:
	if (data != map)
		free(data);
	munmap(map, sb.st_size);
      close:
	close(fd);
      dlclose:
#ifdef SHARED
	if (errormsg)
		fprintf(stderr, "libselinux:  %s\n", errormsg);
	if (libsepolh)
		dlclose(libsepolh);
#endif
	return rc;
}
示例#16
0
int main(int argc, char **argv)
{

	int rc, i, commit = 0;

	if (is_selinux_enabled() <= 0) {
		fprintf(stderr, "%s:  SELinux is disabled\n", argv[0]);
		return 1;
	}

	if (argc < 2) {
		printf("Usage:  %s boolname1 [boolname2 ...]\n",
		       basename(argv[0]));
		return 1;
	}

	for (i = 1; i < argc; i++) {
		printf("%s: ", argv[i]);
		rc = security_get_boolean_active(argv[i]);
		switch (rc) {
		case 1:
			if (security_set_boolean(argv[i], 0) >= 0) {
				printf("inactive\n");
				commit++;
			} else {
				printf("%s - rolling back all changes\n",
				       strerror(errno));
				rollback(i, argv);
			}
			break;
		case 0:
			if (security_set_boolean(argv[i], 1) >= 0) {
				printf("active\n");
				commit++;
			} else {
				printf("%s - rolling back all changes\n",
				       strerror(errno));
				rollback(i, argv);
			}
			break;
		default:
			if (errno == ENOENT)
				printf
				    ("Boolean does not exist - rolling back all changes.\n");
			else
				printf("%s - rolling back all changes.\n",
				       strerror(errno));
			rollback(i, argv);
			break;	/* Not reached. */
		}
	}

	if (commit > 0) {
		if (security_commit_booleans() < 0) {
			printf("Commit failed. (%s)  No change to booleans.\n",
			       strerror(errno));
		} else {
			/* syslog all the changes */
			struct passwd *pwd = getpwuid(getuid());
			for (i = 1; i < argc; i++) {
				if (pwd && pwd->pw_name)
					syslog(LOG_NOTICE,
					       "The %s policy boolean was toggled by %s",
					       argv[i], pwd->pw_name);
				else
					syslog(LOG_NOTICE,
					       "The %s policy boolean was toggled by uid:%d",
					       argv[i], getuid());

			}
			return 0;
		}
	}
	return 1;
}