Пример #1
0
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);
}
Пример #2
0
int main(int argc, char **argv) 
{
  char *seuser = NULL, *level = NULL;
  security_context_t *contextlist;
  int rc, n, i;
 
  if (argc != 3) {
	fprintf(stderr, "usage:  %s linuxuser fromcon\n", argv[0]);
	exit(1);
  }

  rc = getseuserbyname(argv[1], &seuser, &level);
  if (rc) {
	  fprintf(stderr, "getseuserbyname failed:  %s\n", strerror(errno));
	  exit(2);
  }
  printf("seuser:  %s, level %s\n", seuser, level);
  n = get_ordered_context_list_with_level(seuser, level, argv[2], &contextlist);
  if (n <= 0) {
	  fprintf(stderr, "get_ordered_context_list_with_level failed:  %s\n", strerror(errno));
	  exit(3);
  }
  free(seuser);
  free(level);
  for (i = 0; i < n; i++)
	printf("Context %d\t%s\n", i, contextlist[i]);
  freeconary(contextlist);
  exit(0);
}
Пример #3
0
int main(int argc, char **argv)
{
	security_context_t *list, usercon = NULL, cur_context = NULL;
	char *user = NULL, *level = NULL;
	int ret, i, opt;

	while ((opt = getopt(argc, argv, "l:")) > 0) {
		switch (opt) {
		case 'l':
			level = strdup(optarg);
			break;
		default:
			usage(argv[0], "invalid option", 1);
		}
	}

	if (((argc - optind) < 1) || ((argc - optind) > 2))
		usage(argv[0], "invalid number of arguments", 2);

	/* If selinux isn't available, bail out. */
	if (!is_selinux_enabled()) {
		fprintf(stderr,
			"getconlist may be used only on a SELinux kernel.\n");
		return 1;
	}

	user = argv[optind];

	/* If a context wasn't passed, use the current context. */
	if (((argc - optind) < 2)) {
		if (getcon(&cur_context) < 0) {
			fprintf(stderr, "Couldn't get current context.\n");
			return 2;
		}
	} else
		cur_context = argv[optind + 1];

	/* Get the list and print it */
	if (level)
		ret =
		    get_ordered_context_list_with_level(user, level,
							cur_context, &list);
	else
		ret = get_ordered_context_list(user, cur_context, &list);
	if (ret != -1) {
		for (i = 0; list[i]; i++)
			puts(list[i]);
		freeconary(list);
	}

	free(usercon);

	return 0;
}
Пример #4
0
/*
 *  Launch sulogin and wait it for finish
 */
void initng_main_su_login(void)
{
	pid_t sulogin_pid;
	int status;

#ifdef SELINUX
	if (is_selinux_enabled > 0) {
		security_context_t *contextlist = NULL;

		if (get_ordered_context_list("root", 0, &contextlist) > 0) {
			if (setexeccon(contextlist[0]) != 0)
				fprintf(stderr, "setexeccon failed\n");
			freeconary(contextlist);
		}
	}
#endif
	/* sulogin nicely 2 times */
	if (local_sulogin_count <= TRY_TIMES) {
		printf("This is a sulogin offer,\n"
		       "you will be able to login for %i times (now %i),\n"
		       "and on return initng will try continue where it was,\n"
		       "if the times go out, initng will launch\n"
		       "/sbin/initng-segfault on next su_login request.\n\n",
		       TRY_TIMES, local_sulogin_count);
		sulogin_pid = fork();

		if (sulogin_pid == 0) {
			const char *sulogin_argv[] = { "/sbin/sulogin", NULL };
			const char *sulogin_env[] = { NULL };

			/* launch sulogin */
			execve(sulogin_argv[0], (char **)sulogin_argv,
			       (char **)sulogin_env);

			printf("Unable to execute /sbin/sulogin!\n");
		} else if (sulogin_pid > 0) {
			do {
				sulogin_pid = waitpid(sulogin_pid, &status,
						      WUNTRACED);
			} while (!WIFEXITED(status) && !WIFSIGNALED(status));

			/* increase the sulogin_count */
			local_sulogin_count++;
		}
	}

	/* else run segfault script */
	initng_main_segfault();
}
Пример #5
0
int get_default_context(const char *user,
			security_context_t fromcon, security_context_t * newcon)
{
	security_context_t *conary;
	int rc;

	rc = get_ordered_context_list(user, fromcon, &conary);
	if (rc <= 0)
		return -1;

	*newcon = strdup(conary[0]);
	freeconary(conary);
	if (!(*newcon))
		return -1;
	return 0;
}
Пример #6
0
int get_default_context_with_level(const char *user,
				   const char *level,
				   char * fromcon,
				   char ** newcon)
{
	char **conary;
	int rc;

	rc = get_ordered_context_list_with_level(user, level, fromcon, &conary);
	if (rc <= 0)
		return -1;

	*newcon = strdup(conary[0]);
	freeconary(conary);
	if (!(*newcon))
		return -1;
	return 0;
}
Пример #7
0
int get_default_context_with_role(const char *user,
				  const char *role,
				  char * fromcon,
				  char ** newcon)
{
	char **conary;
	char **ptr;
	context_t con;
	const char *role2;
	int rc;

	rc = get_ordered_context_list(user, fromcon, &conary);
	if (rc <= 0)
		return -1;

	for (ptr = conary; *ptr; ptr++) {
		con = context_new(*ptr);
		if (!con)
			continue;
		role2 = context_role_get(con);
		if (role2 && !strcmp(role, role2)) {
			context_free(con);
			break;
		}
		context_free(con);
	}

	rc = -1;
	if (!(*ptr)) {
		errno = EINVAL;
		goto out;
	}
	*newcon = strdup(*ptr);
	if (!(*newcon))
		goto out;
	rc = 0;
      out:
	freeconary(conary);
	return rc;
}
Пример #8
0
static int get_security_context(char *name, int crontab_fd, security_context_t
                                *rcontext, char *tabname) {
    security_context_t *context_list = NULL;
    security_context_t current_con;
    int list_count = 0;
    security_context_t  file_context=NULL;
    struct av_decision avd;
    int retval=0;
    char *seuser = NULL;
    char *level = NULL;
    int i;

    if (name != NULL) {
        if (getseuserbyname(name, &seuser, &level)) {
            log_it(name, getpid(), "getseuserbyname FAILED", tabname);
            return (security_getenforce() > 0);
        }
    }
    else
    {
        seuser = strdup("system_u");
    }

    *rcontext = NULL;
    if(getcon(&current_con)) {
        log_it(name, getpid(), "Can't get current context", tabname);
        return -1;
    }
    list_count = get_ordered_context_list_with_level(seuser, level, current_con, &context_list);
    freecon(current_con);
    free(seuser);
    free(level);
    if (list_count == -1) {
        if (security_getenforce() > 0) {
            log_it(name, getpid(), "No SELinux security context", tabname);
            return -1;
        } else {
            log_it(name, getpid(),
                   "No security context but SELinux in permissive mode,"
                   " continuing", tabname);
	    return 0;
        }
    }

    if (fgetfilecon(crontab_fd, &file_context) < OK) {
        if (security_getenforce() > 0) {
            log_it(name, getpid(), "getfilecon FAILED", tabname);
            freeconary(context_list);
            return -1;
        } else {
            log_it(name, getpid(), "getfilecon FAILED but SELinux in "
                   "permissive mode, continuing", tabname);
            *rcontext = strdup(context_list[0]);
            freeconary(context_list);
            return 0;
        }
    }

    /*
     * Since crontab files are not directly executed,
     * crond must ensure that the crontab file has
     * a context that is appropriate for the context of
     * the user cron job.  It performs an entrypoint
     * permission check for this purpose.
     */

    for(i = 0; i < list_count; i++)
    {
        retval = security_compute_av(context_list[i],
                                 file_context,
                                 SECCLASS_FILE,
                                 FILE__ENTRYPOINT,
                                 &avd);
        if(!retval && ((FILE__ENTRYPOINT & avd.allowed) == FILE__ENTRYPOINT)) {
            *rcontext = strdup(context_list[i]);
            freecon(file_context);
            freeconary(context_list);
            return 0;
        }
    }
    freecon(file_context);
    if (security_getenforce() > 0) {
        log_it(name, getpid(), "ENTRYPOINT FAILED", tabname);
        freeconary(context_list);
        return -1;
    } else {
        log_it(name, getpid(), "ENTRYPOINT FAILED but SELinux in permissive mode, continuing", tabname);
        *rcontext = strdup(context_list[0]);
        freeconary(context_list);
    }
    return 0;
}
Пример #9
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;
}