int main(int argc, char **argv) 
{
	char **buf, **ptr;
	int ret;

	if (argc != 3) {
		fprintf(stderr, "usage:  %s context user\n", argv[0]);
		exit(1);
	}

	ret = security_compute_user(argv[1], argv[2], &buf);
	if (ret < 0) {
		fprintf(stderr, "%s:  security_compute_user(%s,%s) failed\n", argv[0], argv[1], argv[2]);
		exit(2);
	}

	if (!buf[0]) {
		printf("none\n");
		exit(0);
	}

	for (ptr = buf; *ptr; ptr++) {
		printf("%s\n", *ptr);
	}
	freeconary(buf);
	exit(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;
}