示例#1
0
/**
 * \brief   Drop the previliges of the main thread
 */
void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid)
{
    if (sc_set_caps == FALSE)
        return;

    capng_clear(CAPNG_SELECT_BOTH);

    if (run_mode == MODE_PFRING || run_mode == MODE_NFQ) {
        capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                      CAP_NET_RAW,            /* needed for pcap live mode */
                      CAP_NET_ADMIN,          /* needed for nfqueue inline mode */
                      -1);
    } else if (run_mode == MODE_PCAP_DEV) {
        capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
                      CAP_NET_RAW,            /* needed for pcap live mode */
                      -1);
    }

    if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP |
            CAPNG_CLEAR_BOUNDING) < 0)
    {
        SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "capng_change_id for main thread"
                " failed");
        exit(EXIT_FAILURE);
    }

    SCLogInfo("dropped the caps for main thread");
}
示例#2
0
/* Linux specific implementation of daemon_become_new_user()
 * using libcap-ng.   */
static void
daemon_become_new_user_linux(bool access_datapath OVS_UNUSED)
{
#if defined __linux__ &&  HAVE_LIBCAPNG
    int ret;

    ret = capng_get_caps_process();

    if (!ret) {
        if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) {
            const capng_type_t cap_sets = CAPNG_EFFECTIVE|CAPNG_PERMITTED;

            capng_clear(CAPNG_SELECT_BOTH);

            ret = capng_update(CAPNG_ADD, cap_sets, CAP_IPC_LOCK)
                  || capng_update(CAPNG_ADD, cap_sets, CAP_NET_BIND_SERVICE);

            if (access_datapath && !ret) {
                ret = capng_update(CAPNG_ADD, cap_sets, CAP_NET_ADMIN)
                      || capng_update(CAPNG_ADD, cap_sets, CAP_NET_RAW)
                      || capng_update(CAPNG_ADD, cap_sets, CAP_NET_BROADCAST);
            }
        } else {
            ret = -1;
        }
    }

    if (!ret) {
        /* CAPNG_INIT_SUPP_GRP will be a better choice than
         * CAPNG_DROP_SUPP_GRP. However this enum value is only defined
         * with libcap-ng higher than version 0.7.4, which is not wildly
         * available on many Linux distributions yet. Taking a more
         * conservative approach to make sure OVS behaves consistently.
         *
         * XXX We may change this for future OVS releases.
         */
        ret = capng_change_id(uid, gid, CAPNG_DROP_SUPP_GRP
                              | CAPNG_CLEAR_BOUNDING);
    }

    if (ret) {
        VLOG_FATAL("%s: libcap-ng fail to switch to user and group "
                   "%d:%d, aborting", pidfile, uid, gid);
    }
#endif
}
示例#3
0
文件: main.c 项目: Sp1l/heimdal
static void
switch_environment(void)
{
#ifdef HAVE_GETEUID
    if ((runas_string || chroot_string) && geteuid() != 0)
	errx(1, "no running as root, can't switch user/chroot");

    if (chroot_string) {
	if (chroot(chroot_string))
	    err(1, "chroot(%s) failed", chroot_string);
	if (chdir("/"))
	    err(1, "chdir(/) after chroot failed");
    }

    if (runas_string) {
	struct passwd *pw;

	pw = getpwnam(runas_string);
	if (pw == NULL)
	    errx(1, "unknown user %s", runas_string);

	if (initgroups(pw->pw_name, pw->pw_gid) < 0)
	    err(1, "initgroups failed");

#ifndef HAVE_CAPNG
	if (setgid(pw->pw_gid) < 0)
	    err(1, "setgid(%s) failed", runas_string);

	if (setuid(pw->pw_uid) < 0)
	    err(1, "setuid(%s)", runas_string);
#else
	capng_clear (CAPNG_EFFECTIVE | CAPNG_PERMITTED);
	if (capng_updatev (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
	                   CAP_NET_BIND_SERVICE, CAP_SETPCAP, -1) < 0)
	    err(1, "capng_updateev");

	if (capng_change_id(pw->pw_uid, pw->pw_gid,
	                    CAPNG_CLEAR_BOUNDING) < 0)
	    err(1, "capng_change_id(%s)", runas_string);
#endif
    }
#endif
}
int switch_user(uid_t uid, gid_t gid)
{
	capng_clear(CAPNG_SELECT_BOTH);
	return capng_change_id(uid, gid, CAPNG_INIT_SUPP_GRP | CAPNG_CLEAR_BOUNDING);
}
示例#5
0
/**
 * Changes the user and group the bus is running as.
 *
 * @param user the user to become
 * @param error return location for errors
 * @returns #FALSE on failure
 */
dbus_bool_t
_dbus_change_to_daemon_user  (const char    *user,
                              DBusError     *error)
{
  dbus_uid_t uid;
  dbus_gid_t gid;
  DBusString u;

  _dbus_string_init_const (&u, user);

  if (!_dbus_get_user_id_and_primary_group (&u, &uid, &gid))
    {
      dbus_set_error (error, DBUS_ERROR_FAILED,
                      "User '%s' does not appear to exist?",
                      user);
      return FALSE;
    }

  /* If we were root */
  if (_dbus_geteuid () == 0)
    {
      int rc;
      int have_audit_write;

      have_audit_write = capng_have_capability (CAPNG_PERMITTED, CAP_AUDIT_WRITE);
      capng_clear (CAPNG_SELECT_BOTH);
      /* Only attempt to retain CAP_AUDIT_WRITE if we had it when
       * starting.  See:
       * https://bugs.freedesktop.org/show_bug.cgi?id=49062#c9
       */
      if (have_audit_write)
        capng_update (CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
                      CAP_AUDIT_WRITE);
      rc = capng_change_id (uid, gid, CAPNG_DROP_SUPP_GRP);
      if (rc)
        {
          switch (rc) {
            default:
              dbus_set_error (error, DBUS_ERROR_FAILED,
                              "Failed to drop capabilities: %s\n",
                              _dbus_strerror (errno));
              break;
            case -4:
              dbus_set_error (error, _dbus_error_from_errno (errno),
                              "Failed to set GID to %lu: %s", gid,
                              _dbus_strerror (errno));
              break;
            case -5:
              _dbus_warn ("Failed to drop supplementary groups: %s\n",
                          _dbus_strerror (errno));
              break;
            case -6:
              dbus_set_error (error, _dbus_error_from_errno (errno),
                              "Failed to set UID to %lu: %s", uid,
                              _dbus_strerror (errno));
              break;
            case -7:
              dbus_set_error (error, _dbus_error_from_errno (errno),
                              "Failed to unset keep-capabilities: %s\n",
                              _dbus_strerror (errno));
              break;
          }
          return FALSE;
        }
    }

 return TRUE;
}
示例#6
0
int main(int argc, char *argv[])
{
	int which = 0, i;

	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--text") == 0)
			text = 1;
		else if (strcmp(argv[i], "--no-child") == 0)
			no_child = 1;
		else if (strcmp(argv[i], "--lock") == 0)
			lock = 1;
		else if (strcmp(argv[i], "--drop-all") == 0)
			which = 1;
		else if (strcmp(argv[i], "--drop-caps") == 0)
			which = 2;
		else if (strcmp(argv[i], "--id") == 0)
			which = 3;
		else if (strcmp(argv[i], "--init-grp") == 0)
			which = 4;
		else {
			usage();
			return 0;
		}
	}
	switch (which)
	{
		case 1:
			capng_clear(CAPNG_SELECT_BOTH);
			if (lock)
				capng_lock();
			capng_apply(CAPNG_SELECT_BOTH);
			report();
			break;
		case 2:
			capng_clear(CAPNG_SELECT_CAPS);
			if (lock)
				capng_lock();
			capng_apply(CAPNG_SELECT_CAPS);
			report();
			break;
		case 3:
		case 4: {
			int rc;

			capng_clear(CAPNG_SELECT_BOTH);
			capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
					CAP_CHOWN);
			if (which == 4)
				rc = capng_change_id(99, 99,
				CAPNG_INIT_SUPP_GRP | CAPNG_CLEAR_BOUNDING);
			else
				rc = capng_change_id(99, 99,
				CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING);
			if (rc < 0) {
				printf("Error changing uid: %d\n", rc);
				capng_print_caps_text(CAPNG_PRINT_STDOUT,
					CAPNG_EFFECTIVE);
				printf("\n");
				exit(1);
			}
			printf("Keeping CAP_CHOWN to show capabilities across uid change.\n");
			report();
			} break;
		case 0:
			if (lock)
				capng_lock();
			report();
			break;
	}
	return 0;
}