Пример #1
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;
}
Пример #2
0
static void
vjs_add_effective(priv_set_t *pset, enum jail_gen_e jge)
{
	switch (jge) {
	case JAILG_SUBPROC_VCC:
		// open vmods
		priv_setop_assert(priv_addset(pset, "file_read"));
		// write .c output
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	case JAILG_SUBPROC_CC:
		priv_setop_assert(priv_addset(pset, PRIV_PROC_EXEC));
		priv_setop_assert(priv_addset(pset, PRIV_PROC_FORK));
		priv_setop_assert(priv_addset(pset, "file_read"));
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	case JAILG_SUBPROC_VCLLOAD:
		priv_setop_assert(priv_addset(pset, "file_read"));
		break;
	case JAILG_SUBPROC_WORKER:
		priv_setop_assert(priv_addset(pset, "net_access"));
		priv_setop_assert(priv_addset(pset, "file_read"));
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	default:
		INCOMPL();
	}
}
Пример #3
0
static int privileges_postconf(apr_pool_t *pconf, apr_pool_t *plog,
                               apr_pool_t *ptemp, server_rec *s)
{
    priv_cfg *cfg;
    server_rec *sp;

    /* if we have dtrace enabled, merge it into everything */
    if (dtrace_enabled) {
        for (sp = s; sp != NULL; sp = sp->next) {
            cfg = ap_get_module_config(sp->module_config, &privileges_module);
            CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_KERNEL), APLOGNO(03168));
            CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_PROC), APLOGNO(03169));
            CR_CHECK(priv_addset(cfg->priv, PRIV_DTRACE_USER), APLOGNO(03170));
            CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_KERNEL), APLOGNO(03171));
            CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_PROC), APLOGNO(03172));
            CR_CHECK(priv_addset(cfg->child_priv, PRIV_DTRACE_USER), APLOGNO(03173));
        }
        CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_KERNEL), APLOGNO(03174));
        CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_PROC), APLOGNO(03175));
        CR_CHECK(priv_addset(priv_default, PRIV_DTRACE_USER), APLOGNO(03176));
    }

    /* set up priv_setid for per-request use */
    priv_setid = priv_allocset();
    apr_pool_cleanup_register(pconf, NULL, privileges_term,
                              apr_pool_cleanup_null);
    priv_emptyset(priv_setid);
    if (priv_addset(priv_setid, PRIV_PROC_SETID) == -1) {
        ap_log_perror(APLOG_MARK, APLOG_CRIT, errno, ptemp, APLOGNO(02152)
                      "priv_addset");
        return !OK;
    }
    return OK;
}
Пример #4
0
/*
 * Initialize the device policy code
 */
void
devpolicy_init(void)
{
	rw_init(&policyrw, NULL, RW_DRIVER, NULL);
	mutex_init(&policymutex, NULL, MUTEX_DRIVER, NULL);

	/* The mutex is held here in order to satisfy the ASSERT in dpget() */
	mutex_enter(&policymutex);

	nullpolicy = dpget();
	dfltpolicy = dpget();
	netpolicy = dpget();

	/*
	 * Initially, we refuse access to all devices except
	 * to processes with all privileges.
	 */
	priv_fillset(&dfltpolicy->dp_rdp);
	priv_fillset(&dfltpolicy->dp_wrp);

	totitems = 1;

	devplcy_gen++;
	mutex_exit(&policymutex);

	/* initialize default network privilege */
	priv_emptyset(&netpolicy->dp_rdp);
	priv_emptyset(&netpolicy->dp_wrp);
	priv_addset(&netpolicy->dp_rdp, PRIV_NET_RAWACCESS);
	priv_addset(&netpolicy->dp_wrp, PRIV_NET_RAWACCESS);
}
/* effective during runtime of the child */
static inline void
mgt_sandbox_solaris_add_effective(priv_set_t *pset)
{
	/* PSARC/2009/685 - 8eca52188202 - onnv_132 */
	priv_addset(pset, "net_access");

	/* PSARC/2009/378 - 63678502e95e - onnv_140 */
	priv_addset(pset, "file_read");
	priv_addset(pset, "file_write");
}
Пример #6
0
void
solaris_drop_privs_pinfo_net_fork_exec(void)
{
	priv_set_t *pset = NULL, *npset = NULL;

	/*
	 * Note: this variant avoids dropping DAC filesystem rights, in case
	 * the process calling it is running as root and should have the
	 * ability to read/write/chown any file on the system.
	 *
	 * We start with the basic set, then *add* the DAC rights to it while
	 * taking away other parts of BASIC we don't need. Then we intersect
	 * this with our existing PERMITTED set. In this way we keep any
	 * DAC rights we had before, while otherwise reducing ourselves to
	 * the minimum set of privileges we need to proceed.
	 *
	 * This also means we drop any other parts of "root" that we don't
	 * need (e.g. the ability to kill any process, create new device nodes
	 * etc etc).
	 */

	if ((pset = priv_allocset()) == NULL ||
	    (npset = priv_allocset()) == NULL)
		fatal("priv_allocset: %s", strerror(errno));

	priv_basicset(npset);

	if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
	    priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
	    priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 ||
	    priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 ||
	    priv_addset(npset, PRIV_FILE_OWNER) != 0)
		fatal("priv_addset: %s", strerror(errno));

	if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
	    priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
	    priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
	    priv_delset(npset, PRIV_PROC_FORK) != 0 ||
	    priv_delset(npset, PRIV_PROC_INFO) != 0 ||
	    priv_delset(npset, PRIV_PROC_SESSION) != 0)
		fatal("priv_delset: %s", strerror(errno));

	if (getppriv(PRIV_PERMITTED, pset) != 0)
		fatal("getppriv: %s", strerror(errno));

	priv_intersect(pset, npset);

	if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 ||
	    setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 ||
	    setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0)
		fatal("setppriv: %s", strerror(errno));

	priv_freeset(pset);
	priv_freeset(npset);
}
Пример #7
0
static const char *vhost_secure(cmd_parms *cmd, void *dir, int arg)
{
    priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                         &privileges_module);
    if (!arg) {
        /* add basic privileges, excluding those covered by cgimode */
        CFG_CHECK(priv_addset(cfg->priv, PRIV_FILE_LINK_ANY));
        CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_INFO));
        CFG_CHECK(priv_addset(cfg->priv, PRIV_PROC_SESSION));
    }
    return NULL;
}
Пример #8
0
void
priv_init(void)
{
#ifdef DEBUG
	int alloc_test_priv = 1;
#else
	int alloc_test_priv = priv_debug;
#endif
	rw_init(&privinfo_lock, NULL, RW_DRIVER, NULL);

	PRIV_BASIC_ASSERT(priv_basic);
	PRIV_UNSAFE_ASSERT(&priv_unsafe);
	priv_fillset(&priv_fullset);

	/*
	 * When booting with priv_debug set or in a DEBUG kernel, then we'll
	 * add an additional basic privilege and we verify that it is always
	 * present in E.
	 */
	if (alloc_test_priv != 0 &&
	    (priv_basic_test = priv_getbyname("basic_test", PRIV_ALLOC)) >= 0) {
		priv_addset(priv_basic, priv_basic_test);
	}

	devpolicy_init();
}
Пример #9
0
/*
 * additional privileges needed by vjs_privsep -
 * will get waived in vjs_waive
 */
static void
vjs_add_initial(priv_set_t *pset, enum jail_gen_e jge)
{
	(void)jge;

	/* for setgid/setuid */
	AZ(priv_addset(pset, PRIV_PROC_SETID));
}
Пример #10
0
static void
drop_privileges ()
{
	priv_set_t *pPrivSet = NULL;
	priv_set_t *lPrivSet = NULL;

	/*
	 * Start with the 'basic' privilege set and then remove any
	 * of the 'basic' privileges that will not be needed.
	 */
	if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
		return;
	}

	/* Clear privileges we will not need from the 'basic' set */
	(void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
	(void) priv_delset(pPrivSet, PRIV_PROC_INFO);
	(void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
	(void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
	(void) priv_delset(pPrivSet, PRIV_PROC_FORK);

	/* for uscsi */
	(void) priv_addset(pPrivSet, PRIV_SYS_DEVICES);


	/* to open logindevperm'd devices */
	(void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);

	/* Set the permitted privilege set. */
	if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
		return;
	}

	/* Clear the limit set. */
	if ((lPrivSet = priv_allocset()) == NULL) {
		return;
	}

	priv_emptyset(lPrivSet);

	if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
		return;
	}

	priv_freeset(lPrivSet);
}
Пример #11
0
static const char *vhost_cgiprivs(cmd_parms *cmd, void *dir, const char *arg)
{
    priv_cfg *cfg = ap_get_module_config(cmd->server->module_config,
                                         &privileges_module);
    const char *priv = arg;
    if (*priv == '-') {
        CFG_CHECK(priv_delset(cfg->child_priv, priv+1));
    }
    else if (*priv == '+') {
        CFG_CHECK(priv_addset(cfg->child_priv, priv+1));
    }
    else {
        priv_emptyset(cfg->child_priv);
        CFG_CHECK(priv_addset(cfg->child_priv, priv));
    }
    return NULL;
}
/*
 * additional privileges needed by mgt_sandbox_solaris_privsep -
 * will get waived in mgt_sandbox_solaris_waive
 */
static void
mgt_sandbox_solaris_add_initial(priv_set_t *pset, enum sandbox_e who)
{
	(void)who;

	/* for setgid/setuid */
	AZ(priv_addset(pset, PRIV_PROC_SETID));
}
Пример #13
0
static void
setup_privs()
{
	priv_set_t *privset;

	if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
		die(gettext("seteuid()/setegid() failed"));

	/*
	 * Add our privileges and remove unneeded 'basic' privileges from the
	 * permitted set.
	 */
	if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
		die(gettext("cannot setup privileges"));

	(void) priv_addset(privset, PRIV_SYS_ACCT);
	(void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
	(void) priv_addset(privset, PRIV_SYS_DL_CONFIG);
	(void) priv_delset(privset, PRIV_FILE_LINK_ANY);
	(void) priv_delset(privset, PRIV_PROC_EXEC);
	(void) priv_delset(privset, PRIV_PROC_FORK);
	(void) priv_delset(privset, PRIV_PROC_INFO);
	(void) priv_delset(privset, PRIV_PROC_SESSION);
	priv_inverse(privset);
	if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
		die(gettext("cannot setup privileges"));
	priv_freeset(privset);

	/*
	 * Clear the Inheritable and Limit sets.
	 */
	if ((privset = priv_allocset()) == NULL)
		die(gettext("cannot setup privileges"));
	priv_emptyset(privset);
	if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
	    setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
		die(gettext("cannot setup privileges"));

	/*
	 * Turn off the sys_acct, file_dac_write and dl_config privileges
	 * until needed.
	 */
	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
	    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
}
Пример #14
0
static void
vjs_add_inheritable(priv_set_t *pset, enum jail_gen_e jge)
{
	switch (jge) {
	case JAILG_SUBPROC_VCC:
		break;
	case JAILG_SUBPROC_CC:
		priv_setop_assert(priv_addset(pset, PRIV_PROC_EXEC));
		priv_setop_assert(priv_addset(pset, PRIV_PROC_FORK));
		priv_setop_assert(priv_addset(pset, "file_read"));
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	case JAILG_SUBPROC_VCLLOAD:
		break;
	case JAILG_SUBPROC_WORKER:
		break;
	default:
		INCOMPL();
	}
}
static void
mgt_sandbox_solaris_add_effective(priv_set_t *pset, enum sandbox_e who)
{
	switch (who) {
	case SANDBOX_VCC:
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	case SANDBOX_CC:
		break;
	case SANDBOX_VCLLOAD:
		priv_setop_assert(priv_addset(pset, "file_read"));
	case SANDBOX_WORKER:
		priv_setop_assert(priv_addset(pset, "net_access"));
		priv_setop_assert(priv_addset(pset, "file_read"));
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	default:
		REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__);
		exit(1);
	}
}
Пример #16
0
int
main(int argc, const char *argv[])
{
	int fd, ret;
	char *path;
	priv_set_t *ps;
	vnd_ioc_attach_t via;
	vnd_ioc_link_t vil;

	if (argc < 2) {
		(void) fprintf(stderr, "missing arguments...\n");
		return (1);
	}

	if (strlen(argv[1]) >= VND_NAMELEN) {
		(void) fprintf(stderr, "vnic name too long...\n");
		return (1);
	}

	fd = open(VND_PATH, O_RDWR);
	assert(fd > 0);

	(void) strlcpy(via.via_name, argv[1], VND_NAMELEN);
	via.via_zoneid = 0;
	via.via_errno = 0;

	ret = ioctl(fd, VND_IOC_ATTACH, &via);
	assert(ret == 0);
	assert(via.via_errno == 0);

	(void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN);
	vil.vil_errno = 0;
	ret = ioctl(fd, VND_IOC_LINK, &vil);
	assert(ret == 0);
	assert(vil.vil_errno == 0);

	ret = asprintf(&path, "/dev/vnd/%s", argv[1]);
	assert(ret != -1);

	ps = priv_allocset();
	assert(ps != NULL);
	assert(priv_addset(ps, PRIV_NET_RAWACCESS) == 0);
	assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0);

	ret = open(path, O_RDWR);
	assert(ret == -1);
	assert(errno == EPERM);

	return (0);
}
static void
mgt_sandbox_solaris_add_inheritable(priv_set_t *pset, enum sandbox_e who)
{
	switch (who) {
	case SANDBOX_VCC:
		/* for /etc/resolv.conf and /etc/hosts */
		priv_setop_assert(priv_addset(pset, "file_read"));
		break;
	case SANDBOX_CC:
		priv_setop_assert(priv_addset(pset, PRIV_PROC_EXEC));
		priv_setop_assert(priv_addset(pset, PRIV_PROC_FORK));
		priv_setop_assert(priv_addset(pset, "file_read"));
		priv_setop_assert(priv_addset(pset, "file_write"));
		break;
	case SANDBOX_VCLLOAD:
		break;
	case SANDBOX_WORKER:
		break;
	default:
		REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__);
		exit(1);
	}
}
Пример #18
0
/*
 * Interface to set the effective and permitted privileges for
 * a credential; this interface does no security checks and is
 * intended for kernel (file)servers creating credentials with
 * specific privileges.
 */
int
crsetpriv(cred_t *cr, ...)
{
	va_list ap;
	const char *privnm;

	ASSERT(cr->cr_ref <= 2);

	priv_set_PA(cr);

	va_start(ap, cr);

	while ((privnm = va_arg(ap, const char *)) != NULL) {
		int priv = priv_getbyname(privnm, 0);
		if (priv < 0)
			return (-1);

		priv_addset(&CR_PPRIV(cr), priv);
		priv_addset(&CR_EPRIV(cr), priv);
	}
	priv_adjust_PA(cr);
	va_end(ap);
	return (0);
}
Пример #19
0
static void
vjs_add_permitted(priv_set_t *pset, enum jail_gen_e jge)
{
	switch (jge) {
	case JAILG_SUBPROC_VCC:
	case JAILG_SUBPROC_CC:
	case JAILG_SUBPROC_VCLLOAD:
		break;
	case JAILG_SUBPROC_WORKER:
		/* for raising limits in cache_waiter_ports.c */
		AZ(priv_addset(pset, PRIV_SYS_RESOURCE));
		break;
	default:
		INCOMPL();
	}
}
static void
mgt_sandbox_solaris_add_permitted(priv_set_t *pset, enum sandbox_e who)
{
	switch (who) {
	case SANDBOX_VCC:
	case SANDBOX_CC:
	case SANDBOX_VCLLOAD:
		break;
	case SANDBOX_WORKER:
		/* for raising limits in cache_waiter_ports.c */
		AZ(priv_addset(pset, PRIV_SYS_RESOURCE));
		break;
	default:
		REPORT(LOG_ERR, "INCOMPLETE AT: %s(%d)\n", __func__, __LINE__);
		exit(1);
	}
}
Пример #21
0
static void
vjs_add_permitted(priv_set_t *pset, enum jail_gen_e jge)
{
	(void) pset;
	switch (jge) {
	case JAILG_SUBPROC_VCC:
	case JAILG_SUBPROC_CC:
	case JAILG_SUBPROC_VCLLOAD:
		break;
	case JAILG_SUBPROC_WORKER:
		/* vmod_unix getpeerucred() */
		AZ(priv_addset(pset, PRIV_PROC_INFO));
		break;
	default:
		INCOMPL();
	}
}
Пример #22
0
static void
priv_str_to_set(const char *priv_name, priv_set_t *priv_set)
{
	if (priv_name == NULL || strcmp(priv_name, "none") == 0) {
		priv_emptyset(priv_set);
	} else if (strcmp(priv_name, "all") == 0) {
		priv_fillset(priv_set);
	} else {
		int priv;
		priv = priv_getbyname(priv_name, PRIV_ALLOC);
		if (priv < 0) {
			cmn_err(CE_WARN, "fail to allocate privilege: %s",
			    priv_name);
			return;
		}
		priv_emptyset(priv_set);
		priv_addset(priv_set, priv);
	}
}
Пример #23
0
static int drop_privs()
{
	static const char *privs[] = {
		"file_read",
		"file_write",
		"net_access",
		NULL,
	};

	priv_set_t *wanted;
	int ret;
	int i;

	wanted = priv_allocset();
	if (!wanted)
		return -errno;

	priv_emptyset(wanted);

	for (i = 0; privs[i]; i++) {
		ret = priv_addset(wanted, privs[i]);
		if (ret) {
			ret = -errno;
			goto err_free;
		}
	}

	ret = setppriv(PRIV_SET, PRIV_PERMITTED, wanted);
	if (ret == -1)
		ret = -errno;

err_free:
	priv_freeset(wanted);

	return ret;
}
Пример #24
0
/*
 * Most privileges, except the ones that are required for smbd, are turn off
 * in the effective set.  They will be turn on when needed for command
 * execution during share connection/disconnection.
 */
static void
smbd_daemonize_fini(int fd, int exit_status)
{
	priv_set_t *pset;

	/*
	 * Now that we're running, if a pipe fd was specified, write an exit
	 * status to it to indicate that our parent process can safely detach.
	 * Then proceed to loading the remaining non-built-in modules.
	 */
	if (fd >= 0)
		(void) write(fd, &exit_status, sizeof (exit_status));

	(void) close(fd);

	pset = priv_allocset();
	if (pset == NULL)
		return;

	priv_basicset(pset);

	/* list of privileges for smbd */
	(void) priv_addset(pset, PRIV_NET_MAC_AWARE);
	(void) priv_addset(pset, PRIV_NET_PRIVADDR);
	(void) priv_addset(pset, PRIV_PROC_AUDIT);
	(void) priv_addset(pset, PRIV_SYS_DEVICES);
	(void) priv_addset(pset, PRIV_SYS_SMB);
	(void) priv_addset(pset, PRIV_SYS_MOUNT);

	priv_inverse(pset);

	/* turn off unneeded privileges */
	(void) setppriv(PRIV_OFF, PRIV_EFFECTIVE, pset);

	priv_freeset(pset);

	/* reenable core dumps */
	__fini_daemon_priv(NULL);
}
Пример #25
0
/* Specify what privileges an suid root binary needs.  */
int __init_suid_priv (int flags, ...)
{
  int res = 0;
  priv_set_t *permit = NULL, *inherit = NULL, *scratch = NULL;

  /* Check flags.  */
  if (flags != PU_LIMITPRIVS && flags != PU_CLEARLIMITSET)
    return -1;

  /* We can only initialize once.  */
  if (__suidset)
    return -1;

  /* Do nothing if we are running as root but not setuid root.  */
  uid_t uid = getuid ();
  uid_t euid = geteuid ();
  if (uid == 0 && euid == 0)
    return 0;

  /* Allocate a scratch set.  */
  scratch = priv_allocset ();
  if (!scratch)
    goto error;

  /* Get the basic set.  */
  const priv_data_t *pd = __priv_parse_data_cached ();
  if (!pd)
    goto error;
  priv_set_t *basic = pd->pd_basicprivs;

  /* Get the inherited set.  */
  inherit = priv_allocset ();
  if (!inherit)
    goto error;
  if (getppriv (PRIV_INHERITABLE, inherit) != 0)
    goto error;

  /* Get the permitted set.  */
  permit = priv_allocset ();
  if (!permit)
    goto error;
  if (getppriv (PRIV_PERMITTED, permit) != 0)
    goto error;

  /* Get passed privileges.  */
  __suidset = priv_allocset ();
  if (!__suidset)
    goto error;
  priv_emptyset (__suidset);
  va_list ap;
  va_start (ap, flags);
  const char *priv;
  while ((priv = va_arg (ap, const char *)))
    if (priv_addset (__suidset, priv) != 0)
      goto error;

  /* Make sure that the passed privileges are a subset of the current
     permitted privileges.  */
  if (priv_issubset (__suidset, permit) != _B_TRUE)
    goto error;

  /* Set the effective privileges to the inherited ones.  */
  if (setppriv (PRIV_SET, PRIV_EFFECTIVE, inherit) != 0)
    goto error;

  /* Set the permitted privileges to those currently permitted privileges in
     set of the ones passed in, the inherited ones, and the basic set.  */
  priv_copyset (__suidset, scratch);
  priv_union (inherit, scratch);
  if (basic)
    priv_union (basic, scratch);
  priv_intersect (permit, scratch);
  if (setppriv (PRIV_SET, PRIV_PERMITTED, scratch) != 0)
    goto error;

  /* Check if we need to set the limit set.  */
  if (flags & PU_CLEARLIMITSET)
    {
      priv_emptyset (scratch);
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }
  else if (flags & PU_LIMITPRIVS)
    {
      if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0)
        goto error;
    }

  /* Change the uid to the caller's uid if we're setuid root.  */
  if (euid == 0 && setreuid (uid, uid) != 0)
    goto error;

  goto out;

error:
  res = -1;
  if (__suidset)
    {
      priv_freeset (__suidset);
      __suidset = NULL;
    }
  if (euid == 0)
    setreuid (uid, uid);

out:
  priv_freeset (permit);
  priv_freeset (inherit);
  priv_freeset (scratch);

  return res;
}
Пример #26
0
priv_set_t *priv_str_to_set (const char *buf, const char *sep,
      const char **endptr)
{
  /* Take a copy of the string since strtok_r will modify it.  */
  char *str = strdup (buf);
  if (!str)
    return NULL;

  priv_set_t *set = priv_allocset ();
  if (!set)
    {
      free (str);
      return NULL;
    }
  priv_emptyset (set);
  const priv_data_t *data = __priv_parse_data_cached ();
  if (!data)
    return NULL;
  priv_set_t *basic = data->pd_basicprivs;

  char *saveptr;
  char *priv = strtok_r (str, sep, &saveptr);
  if (!priv)
    return set;
  do
    {
      if (strcmp (priv, "basic") == 0 && basic)
          priv_union (basic, set);
      else if (strcmp (priv, "all") == 0)
          priv_fillset (set);
      else if (strcmp (priv, "none") == 0)
          priv_emptyset (set);
      else if (strcmp (priv, "zone") == 0)
        {
          priv_set_t *zone = priv_allocset ();
          if (!zone)
            goto inval;
          if (zone_getattr (getzoneid (), ZONE_ATTR_PRIVSET,
                zone, __PRIVSETSIZE) == 0)
            priv_union (zone, set);
          priv_freeset (zone);
        }
      else
        {
          int negate = *str == '-' || *str == '!';
          if (negate)
            str++;

          int res;
          if (negate)
            res = priv_delset (set, str);
          else
            res = priv_addset (set, str);
          if (res == -1)
            goto inval;
        }
    }
  while ((priv = strtok_r (NULL, sep, &saveptr))) ;

  free (str);
  return set;

inval:

   priv_freeset (set);
   free (str);
   __set_errno (EINVAL);
  return NULL;
}
Пример #27
0
void checkAsRoot() {
	#ifndef __CYGWIN__
	#ifdef SOLAR_PRIV
	priv_set_t *privset;
	char *p;

	/* Get the basic set */
	privset = priv_str_to_set("basic", ",", NULL);
	if (privset == NULL) {
		die("ERROR: Could not get basic privset from priv_str_to_set().");
	} else {
		p = priv_set_to_str(privset, ',', 0);
		SPINE_LOG_DEBUG(("DEBUG: Basic privset is: '%s'.", p != NULL ? p : "Unknown"));
	}

	/* Add priviledge to send/receive ICMP packets */
	if (priv_addset(privset, PRIV_NET_ICMPACCESS) < 0 ) {
		SPINE_LOG_DEBUG(("Warning: Addition of PRIV_NET_ICMPACCESS to privset failed: '%s'.", strerror(errno)));
	}

	/* Compute the set of privileges that are never needed */
	priv_inverse(privset);

	/* Remove the set of unneeded privs from Permitted (and by
	 * implication from Effective) */
	if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) < 0) {
		SPINE_LOG_DEBUG(("Warning: Dropping privileges from PRIV_PERMITTED failed: '%s'.", strerror(errno)));
	}

	/* Remove unneeded priv set from Limit to be safe */
	if (setppriv(PRIV_OFF, PRIV_LIMIT, privset) < 0) {
		SPINE_LOG_DEBUG(("Warning: Dropping privileges from PRIV_LIMIT failed: '%s'.", strerror(errno)));
	}

	boolean_t pe = priv_ineffect(PRIV_NET_ICMPACCESS);
	SPINE_LOG_DEBUG(("DEBUG: Privilege PRIV_NET_ICMPACCESS is: '%s'.", pe != 0 ? "Enabled" : "Disabled"));

	set.icmp_avail = pe;

	/* Free the privset */
	priv_freeset(privset);
	free(p);
	#else
	if (hasCaps() != TRUE) {
		seteuid(0);
	
		if (geteuid() != 0) {
			SPINE_LOG_DEBUG(("WARNING: Spine NOT running asroot.  This is required if using ICMP.  Please run \"chmod +s;chown root:root spine\" to resolve."));
			set.icmp_avail = FALSE;
		}else{
			SPINE_LOG_DEBUG(("DEBUG: Spine is running asroot."));
			set.icmp_avail = TRUE;
			seteuid(getuid());
		}
	} else {
		SPINE_LOG_DEBUG(("DEBUG: Spine has cap_net_raw capability."));
		set.icmp_avail = TRUE;
	}
	#endif
	#endif
}
/* permitted during runtime of the child - for privilege bracketing */
static inline void
mgt_sandbox_solaris_add_permitted(priv_set_t *pset)
{
	/* for raising limits in cache_waiter_ports.c */
	priv_addset(pset, PRIV_SYS_RESOURCE);
}
/* effective during mgt_sandbox */
static inline void
mgt_sandbox_solaris_add_initial(priv_set_t *pset)
{
	/* for setgid/setuid */
	priv_addset(pset, PRIV_PROC_SETID);
}
Пример #30
0
/**
 * Grabs extra non-root capabilities / privileges that we might require.
 *
 * This is currently only used for being able to do ICMP from the NAT engine.
 *
 * @note We still have root privileges at the time of this call.
 */
static void supR3HardenedMainGrabCapabilites(void)
{
# if defined(RT_OS_LINUX)
    /*
     * We are about to drop all our privileges. Remove all capabilities but
     * keep the cap_net_raw capability for ICMP sockets for the NAT stack.
     */
    if (g_uCaps != 0)
    {
#  ifdef USE_LIB_PCAP
        /* XXX cap_net_bind_service */
        if (!cap_set_proc(cap_from_text("all-eip cap_net_raw+ep")))
            prctl(PR_SET_KEEPCAPS, 1 /*keep=*/, 0, 0, 0);
        prctl(PR_SET_DUMPABLE, 1 /*dump*/, 0, 0, 0);
#  else
        cap_user_header_t hdr = (cap_user_header_t)alloca(sizeof(*hdr));
        cap_user_data_t   cap = (cap_user_data_t)alloca(sizeof(*cap));
        memset(hdr, 0, sizeof(*hdr));
        hdr->version = _LINUX_CAPABILITY_VERSION;
        memset(cap, 0, sizeof(*cap));
        cap->effective = g_uCaps;
        cap->permitted = g_uCaps;
        if (!capset(hdr, cap))
            prctl(PR_SET_KEEPCAPS, 1 /*keep*/, 0, 0, 0);
        prctl(PR_SET_DUMPABLE, 1 /*dump*/, 0, 0, 0);
#  endif /* !USE_LIB_PCAP */
    }

# elif defined(RT_OS_SOLARIS)
    /*
     * Add net_icmpaccess privilege to effective privileges and limit
     * permitted privileges before completely dropping root privileges.
     * This requires dropping root privileges temporarily to get the normal
     * user's privileges.
     */
    seteuid(g_uid);
    priv_set_t *pPrivEffective = priv_allocset();
    priv_set_t *pPrivNew = priv_allocset();
    if (pPrivEffective && pPrivNew)
    {
        int rc = getppriv(PRIV_EFFECTIVE, pPrivEffective);
        seteuid(0);
        if (!rc)
        {
            priv_copyset(pPrivEffective, pPrivNew);
            rc = priv_addset(pPrivNew, PRIV_NET_ICMPACCESS);
            if (!rc)
            {
                /* Order is important, as one can't set a privilege which is
                 * not in the permitted privilege set. */
                rc = setppriv(PRIV_SET, PRIV_EFFECTIVE, pPrivNew);
                if (rc)
                    supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to set effective privilege set.\n");
                rc = setppriv(PRIV_SET, PRIV_PERMITTED, pPrivNew);
                if (rc)
                    supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to set permitted privilege set.\n");
            }
            else
                supR3HardenedError(rc, false, "SUPR3HardenedMain: failed to add NET_ICMPACCESS privilege.\n");
        }
    }
    else
    {
        /* for memory allocation failures just continue */
        seteuid(0);
    }

    if (pPrivEffective)
        priv_freeset(pPrivEffective);
    if (pPrivNew)
        priv_freeset(pPrivNew);
# endif
}