コード例 #1
0
ファイル: ppriv.c プロジェクト: bahamas10/openzfs
static int
dumppriv(char **argv)
{
	int rc = 0;
	const char *pname;
	int i;

	if (argv[0] == NULL) {
		for (i = 0; ((pname = priv_getbynum(i++)) != NULL); )
			rc += dopriv(pname);
	} else {
		for (; *argv; argv++) {
			priv_set_t *pset = priv_str_to_set(*argv, ",", NULL);

			if (pset == NULL) {
				(void) fprintf(stderr, "%s: %s: bad privilege"
				    " list\n", command, *argv);
				rc++;
				continue;
			}
			for (i = 0; ((pname = priv_getbynum(i++)) != NULL); )
				if (priv_ismember(pset, pname))
					rc += dopriv(pname);
		}
	}
	return (rc);
}
コード例 #2
0
/* Try to remove priv from the effective set.
   Returns 0 if priv was removed.
   Returns -1 on error with errno set appropriately.  */
int
priv_set_remove (const char *priv)
{
  if (! initialized && priv_set_initialize () != 0)
    return -1;

  if (priv_ismember (eff_set, priv))
    {
      /* priv_addset/priv_delset can only fail if priv is invalid, which is
         checked above by the priv_ismember call.  */
      priv_delset (eff_set, priv);
      if (setppriv (PRIV_SET, PRIV_EFFECTIVE, eff_set) != 0)
        {
          priv_addset (eff_set, priv);
          return -1;
        }
      priv_addset (rem_set, priv);
    }
  else
    {
      errno = EINVAL;
      return -1;
    }

  return 0;
}
コード例 #3
0
ファイル: test-priv-set.c プロジェクト: djmitche/gnulib
int
main (void)
{
#if HAVE_GETPPRIV && HAVE_PRIV_H
    priv_set_t *set;

    ASSERT (set = priv_allocset ());
    ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
    ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 1);

    /* Do a series of removes and restores making sure that the results are
       consistent with our ismember function and solaris' priv_ismember.  */
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 1);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 1);
    ASSERT (priv_set_restore (PRIV_PROC_EXEC) == -1);
        ASSERT (errno == EINVAL);
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 1);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 1);
    ASSERT (priv_set_remove (PRIV_PROC_EXEC) == 0);
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 0);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 0);
    ASSERT (priv_set_remove (PRIV_PROC_EXEC) == -1);
        ASSERT (errno == EINVAL);
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 0);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 0);
    ASSERT (priv_set_restore (PRIV_PROC_EXEC) == 0);
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 1);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 1);
    ASSERT (priv_set_restore (PRIV_PROC_EXEC) == -1);
        ASSERT (errno == EINVAL);
    ASSERT (priv_set_ismember (PRIV_PROC_EXEC) == 1);
        ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
        ASSERT (priv_ismember (set, PRIV_PROC_EXEC) == 1);

    /* Test the priv_set_linkdir wrappers.  */
    ASSERT (getppriv (PRIV_EFFECTIVE, set) == 0);
    if (priv_ismember (set, PRIV_SYS_LINKDIR))
      {
        ASSERT (priv_set_restore_linkdir () == -1);
            ASSERT (errno == EINVAL);
        ASSERT (priv_set_remove_linkdir () == 0);
        ASSERT (priv_set_remove_linkdir () == -1);
            ASSERT (errno == EINVAL);
        ASSERT (priv_set_restore_linkdir () == 0);
      }
#else
    ASSERT (priv_set_restore_linkdir () == -1);
    ASSERT (priv_set_remove_linkdir () == -1);
#endif

    return 0;
}
コード例 #4
0
/* Check if priv is in the effective set.
   Returns 1 if priv is a member and 0 if not.
   Returns -1 on error with errno set appropriately.  */
int
priv_set_ismember (const char *priv)
{
  if (! initialized && priv_set_initialize () != 0)
    return -1;

  return priv_ismember (eff_set, priv);
}
コード例 #5
0
static void
N2N_check_priv(
	void			*buf,
	char			*dc_str)
{
	nss_pheader_t		*phdr = (nss_pheader_t *)buf;
	ucred_t			*uc = NULL;
	const priv_set_t	*eset;
	zoneid_t		zoneid;
	int			errnum;
	char			*me = "N2N_check_priv";

	if (door_ucred(&uc) != 0) {
		errnum = errno;
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
		(me, "door_ucred: %s\n", strerror(errno));

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, errnum);
	}

	eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
	zoneid = ucred_getzoneid(uc);

	if ((zoneid != GLOBAL_ZONEID && zoneid != getzoneid()) ||
	    eset != NULL ? !priv_ismember(eset, PRIV_SYS_ADMIN) :
	    ucred_geteuid(uc) != 0) {

		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ALERT)
		(me, "%s call failed(cred): caller pid %d, uid %d, "
		    "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
		    ucred_getruid(uc), ucred_geteuid(uc), zoneid);
		ucred_free(uc);

		NSCD_RETURN_STATUS(phdr, NSS_ERROR, EACCES);
	}

	_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
	(me, "nscd received %s cmd from pid %d, uid %d, "
	    "euid %d, zoneid %d\n", dc_str, ucred_getpid(uc),
	    ucred_getruid(uc), ucred_geteuid(uc), zoneid);

	ucred_free(uc);

	NSCD_RETURN_STATUS_SUCCESS(phdr);
}
コード例 #6
0
/*
 * Check to see if the door client's euid is 0 or if it has required_priv
 * privilege. Return 0 if yes, -1 otherwise.
 * Supported values for required_priv are:
 *    - NSCD_ALL_PRIV: for all zones privileges
 *    - NSCD_READ_PRIV: for PRIV_FILE_DAC_READ privilege
 */
int
_nscd_check_client_priv(int required_priv)
{
	int			rc = 0;
	ucred_t			*uc = NULL;
	const priv_set_t	*eset;
	char			*me = "_nscd_check_client_read_priv";
	priv_set_t		*zs;	/* zone */

	if (door_ucred(&uc) != 0) {
		_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
		(me, "door_ucred: %s\n", strerror(errno));
		return (-1);
	}

	if (ucred_geteuid(uc) == 0) {
		ucred_free(uc);
		return (0);
	}

	eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
	switch (required_priv) {
		case NSCD_ALL_PRIV:
			zs = priv_str_to_set("zone", ",", NULL);
			if (!priv_isequalset(eset, zs)) {
				_NSCD_LOG(NSCD_LOG_FRONT_END,
				    NSCD_LOG_LEVEL_ERROR)
				(me, "missing all zones privileges\n");
				rc = -1;
			}
			priv_freeset(zs);
			break;
		case NSCD_READ_PRIV:
			if (!priv_ismember(eset, PRIV_FILE_DAC_READ))
				rc = -1;
			break;
		default:
			_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
			(me, "unknown required_priv: %d\n", required_priv);
			rc = -1;
			break;
	}
	ucred_free(uc);
	return (rc);
}
コード例 #7
0
void
dump_privs(void)
{
    const char *pname;
    int i;

    priv_set_t *pset = priv_str_to_set("zone", ",", NULL);
    if (pset == NULL) {
        (void) fprintf(stderr, "unable to create priv_set for 'zone'\n");
        return;
    }
    (void) puts("== Zone privileges ==");
    for (i = 0; ((pname = priv_getbynum(i++)) != NULL); ) {
        if (priv_ismember(pset, pname)) {
            (void) puts(pname);
        }
    }
}
コード例 #8
0
ファイル: fmd_rpc.c プロジェクト: andreiw/polaris
/*
 * Utillity function to fetch the XPRT's ucred and determine if we should deny
 * the request.  For now, we implement a simple policy of rejecting any caller
 * who does not have the PRIV_SYS_CONFIG bit in their Effective privilege set,
 * unless the caller is loading a module, which requires all privileges.
 */
int
fmd_rpc_deny(struct svc_req *rqp)
{
	ucred_t *ucp = alloca(ucred_size());
	const priv_set_t *psp;

	if (svc_getcallerucred(rqp->rq_xprt, &ucp) != 0 ||
	    (psp = ucred_getprivset(ucp, PRIV_EFFECTIVE)) == NULL)
		return (1); /* deny access if we can't get credentials */

#ifndef DEBUG
	/*
	 * For convenience of testing, we only require all privileges for a
	 * module load when running a non-DEBUG fault management daemon.
	 */
	if (rqp->rq_proc == FMD_ADM_MODLOAD)
		return (!priv_isfullset(psp));
#endif
	return (!priv_ismember(psp, PRIV_SYS_CONFIG));
}
コード例 #9
0
ファイル: mgmt_remove.c プロジェクト: alhazred/onarm
/*
 * remove_zfs -- unshare a ZVOL from the target
 */
static char *
remove_zfs(tgt_node_t *x, ucred_t *cred)
{
	char		*prop;
	char		*msg		= NULL;
	tgt_node_t		*targ = NULL;
	libzfs_handle_t		*zh = NULL;
	const priv_set_t	*eset;

	if (tgt_find_value_str(x, XML_ELEMENT_NAME, &prop) == False) {
		xml_rtn_msg(&msg, ERR_SYNTAX_MISSING_NAME);
		return (msg);
	}

	if ((zh = libzfs_init()) == NULL) {
		xml_rtn_msg(&msg, ERR_INTERNAL_ERROR);
		free(prop);
		return (msg);
	}

	eset = ucred_getprivset(cred, PRIV_EFFECTIVE);
	if (eset != NULL ? !priv_ismember(eset, PRIV_SYS_CONFIG) :
	    ucred_geteuid(cred) != 0) {
		/*
		 * See if user has ZFS dataset permissions to do operation
		 */
		if (zfs_iscsi_perm_check(zh, prop, cred) != 0) {
			xml_rtn_msg(&msg, ERR_NO_PERMISSION);
			free(prop);
			libzfs_fini(zh);
			return (msg);
		}
	}

	libzfs_fini(zh);

	while ((targ = tgt_node_next(targets_config, XML_ELEMENT_TARG, targ))
	    != NULL) {
		if (strcmp(targ->x_value, prop) == 0)
			break;
	}
	free(prop);
	if (targ == NULL) {
		/*
		 * We're unsharing a target. If we don't have a reference
		 * then there's no problem.
		 */
		xml_rtn_msg(&msg, ERR_SUCCESS);
		return (msg);
	}
	if (tgt_find_value_str(targ, XML_ELEMENT_INAME, &prop) ==
	    False) {
		xml_rtn_msg(&msg, ERR_TARGCFG_MISSING_INAME);
		return (msg);
	}

	tgt_node_remove(targets_config, targ, MatchBoth);

	/*
	 * Wait until here to issue a logout to any initiators that
	 * might be logged into the target. Certain initiators are
	 * sneaky in that if asked to logout they will, but turn right
	 * around and log back into the target. By waiting until here
	 * to issue the logout we'll have removed reference to the target
	 * such that this can't happen.
	 */
	if (isns_enabled() == True) {
		if (isns_dereg(prop) != 0)
			syslog(LOG_INFO, "ISNS dereg failed\n");
	}
	logout_targ(prop);
	free(prop);

	xml_rtn_msg(&msg, ERR_SUCCESS);
	return (msg);
}
コード例 #10
0
token_t *
au_to_privset(
    const char *set,
    const priv_set_t *pset,
    char data_header,
    int success)
{
	token_t *token, *m;
	adr_t adr;
	int priv;
	const char *pname;
	char sf = (char)success;
	char *buf, *q;
	short sz;
	boolean_t full;

	token = au_getclr();

	adr_start(&adr, memtod(token, char *));
	adr_char(&adr, &data_header, 1);
	/*
	 * set is not used for AUT_UPRIV and sf (== success) is not
	 * used for AUT_PRIV
	 */
	if (data_header == AUT_UPRIV) {
		adr_char(&adr, &sf, 1);
	} else {
		sz = strlen(set) + 1;
		adr_short(&adr, &sz, 1);

		token->len = (uchar_t)adr_count(&adr);
		m = au_getclr();

		(void) au_append_buf(set, sz, m);
		(void) au_append_rec(token, m, AU_PACK);
		adr.adr_now += sz;
	}

	full = priv_isfullset(pset);

	if (full) {
		buf = "ALL";
		sz = strlen(buf) + 1;
	} else {
		q = buf = kmem_alloc(maxprivbytes, KM_SLEEP);
		*buf = '\0';

		for (priv = 0; (pname = priv_getbynum(priv)) != NULL; priv++) {
			if (priv_ismember(pset, priv)) {
				if (q != buf)
					*q++ = ',';
				(void) strcpy(q, pname);
				q += strlen(q);
			}
		}
		sz = (q - buf) + 1;
	}

	adr_short(&adr, &sz, 1);
	token->len = (uchar_t)adr_count(&adr);

	m = au_getclr();
	(void) au_append_buf(buf, sz, m);
	(void) au_append_rec(token, m, AU_PACK);

	if (!full)
		kmem_free(buf, maxprivbytes);

	return (token);
}
コード例 #11
0
int
main(int argc, char **argv)
{
#if !defined(__APPLE__)
	ucred_t *ucp;
#endif
	int err;
	int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0;
	char c, *p, *end;
	struct sigaction act;
	int done = 0;

	g_pname = basename(argv[0]);
	argv[0] = g_pname; /* rewrite argv[0] for getopt errors */

	/*
	 * Make sure we have the required dtrace_proc privilege.
	 */
#if !defined(__APPLE__)
	if ((ucp = ucred_get(getpid())) != NULL) {
		const priv_set_t *psp;
		if ((psp = ucred_getprivset(ucp, PRIV_EFFECTIVE)) != NULL &&
		    !priv_ismember(psp, PRIV_DTRACE_PROC)) {
			fatal("dtrace_proc privilege required\n");
		}

		ucred_free(ucp);
	}
#endif

	while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) {
		switch (c) {
		case 'n':
			errno = 0;
			g_nent = strtoul(optarg, &end, 10);
			if (*end != '\0' || errno != 0) {
				(void) fprintf(stderr, "%s: invalid count "
				    "'%s'\n", g_pname, optarg);
				usage();
			}
			break;

		case 'p':
			opt_p = 1;
			break;

		case 'v':
			opt_v = 1;
			break;

		case 'A':
			opt_C = opt_H = 1;
			break;

		case 'C':
			opt_C = 1;
			break;

		case 'H':
			opt_H = 1;
			break;

		case 'V':
			g_opt_V = 1;
			break;

		default:
			if (strchr(PLOCKSTAT_OPTSTR, c) == NULL)
				usage();
		}
	}

	/*
	 * We need a command or at least one pid.
	 */
	if (argc == optind)
		usage();

	if (opt_C == 0 && opt_H == 0)
		opt_C = 1;

	if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL)
		fatal("failed to initialize dtrace: %s\n",
		    dtrace_errmsg(NULL, err));

	/*
	 * The longest string we trace is 23 bytes long -- so 32 is plenty.
	 */
	if (dtrace_setopt(g_dtp, "strsize", "32") == -1)
		dfatal("failed to set 'strsize'");

	/*
	 * 1k should be more than enough for all trace() and printa() actions.
	 */
	if (dtrace_setopt(g_dtp, "bufsize", "1k") == -1)
		dfatal("failed to set 'bufsize'");

	/*
	 * The table we produce has the hottest locks at the top.
	 */
	if (dtrace_setopt(g_dtp, "aggsortrev", NULL) == -1)
		dfatal("failed to set 'aggsortrev'");

	/*
	 * These are two reasonable defaults which should suffice.
	 */
	if (dtrace_setopt(g_dtp, "aggsize", "256k") == -1)
		dfatal("failed to set 'aggsize'");
	if (dtrace_setopt(g_dtp, "aggrate", "1sec") == -1)
		dfatal("failed to set 'aggrate'");

	/*
	 * Take a second pass through to look for options that set options now
	 * that we have an open dtrace handle.
	 */
	optind = 1;
	while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) {
		switch (c) {
		case 's':
			g_opt_s = 1;
			if (dtrace_setopt(g_dtp, "ustackframes", optarg) == -1)
				dfatal("failed to set 'ustackframes'");
			break;

		case 'x':
			if ((p = strchr(optarg, '=')) != NULL)
				*p++ = '\0';

			if (dtrace_setopt(g_dtp, optarg, p) != 0)
				dfatal("failed to set -x %s", optarg);
			break;

		case 'e':
			errno = 0;
			(void) strtoul(optarg, &end, 10);
			if (*optarg == '-' || *end != '\0' || errno != 0) {
				(void) fprintf(stderr, "%s: invalid timeout "
				    "'%s'\n", g_pname, optarg);
				usage();
			}

			/*
			 * Construct a DTrace enabling that will exit after
			 * the specified number of seconds.
			 */
			dprog_add("BEGIN\n{\n\tend = timestamp + ");
			dprog_add(optarg);
			dprog_add(" * 1000000000;\n}\n");
			dprog_add("tick-10hz\n/timestamp >= end/\n");
			dprog_add("{\n\texit(0);\n}\n");
			break;
		}
	}

	argc -= optind;
	argv += optind;

	if (opt_H) {
		dprog_add(g_hold_init);
		if (g_opt_s == NULL)
			dprog_add(g_hold_times);
		else
			dprog_add(g_hold_histogram);
	}

	if (opt_C) {
		dprog_add(g_ctnd_init);
		if (g_opt_s == NULL)
			dprog_add(g_ctnd_times);
		else
			dprog_add(g_ctnd_histogram);
	}

	if (opt_p) {
		ulong_t pid;

		if (argc > 1) {
			(void) fprintf(stderr, "%s: only one pid is allowed\n",
			    g_pname);
			usage();
		}

		errno = 0;
		pid = strtoul(argv[0], &end, 10);
		if (*end != '\0' || errno != 0 || (pid_t)pid != pid) {
			(void) fprintf(stderr, "%s: invalid pid '%s'\n",
			    g_pname, argv[0]);
			usage();
		}

		if ((g_pr = dtrace_proc_grab(g_dtp, (pid_t)pid, 0)) == NULL)
			dfatal(NULL);
	} else {
		if ((g_pr = dtrace_proc_create(g_dtp, argv[0], argv)) == NULL)
			dfatal(NULL);
	}

	dprog_compile();

	if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1)
		dfatal("failed to establish proc handler");

	(void) sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = intr;
	(void) sigaction(SIGINT, &act, NULL);
	(void) sigaction(SIGTERM, &act, NULL);

	if (dtrace_go(g_dtp) != 0)
		dfatal("dtrace_go()");

	if (dtrace_getopt(g_dtp, "ustackframes", &g_nframes) != 0)
		dfatal("failed to get 'ustackframes'");

	dtrace_proc_continue(g_dtp, g_pr);

	if (opt_v)
		(void) printf("%s: tracing enabled for pid %d\n", g_pname,
		    (int)Pstatus(g_pr)->pr_pid);

	do {
		if (!g_intr && !done)
			dtrace_sleep(g_dtp);

		if (done || g_intr || g_exited) {
			done = 1;
			if (dtrace_stop(g_dtp) == -1)
				dfatal("couldn't stop tracing");
		}

		switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) {
		case DTRACE_WORKSTATUS_DONE:
			done = 1;
			break;
		case DTRACE_WORKSTATUS_OKAY:
			break;
		default:
			dfatal("processing aborted");
		}

	} while (!done);

	dtrace_close(g_dtp);

	return (0);
}