Beispiel #1
0
static void
linux_minprivs(void) {
	unsigned int caps;

	/*%
	 * Drop all privileges except the ability to bind() to privileged
	 * ports.
	 *
	 * It's important that we drop CAP_SYS_CHROOT.  If we didn't, it
	 * chroot() could be used to escape from the chrooted area.
	 */

	caps = 0;
	caps |= (1 << CAP_NET_BIND_SERVICE);

	/*
	 * XXX  We might want to add CAP_SYS_RESOURCE, though it's not
	 *      clear it would work right given the way linuxthreads work.
	 * XXXDCL But since we need to be able to set the maximum number
	 * of files, the stack size, data size, and core dump size to
	 * support named.conf options, this is now being added to test.
	 */
	caps |= (1 << CAP_SYS_RESOURCE);

	linux_setcaps(caps);
}
Beispiel #2
0
static void
linux_initialprivs(void) {
	unsigned int caps;

	/*%
	 * We don't need most privileges, so we drop them right away.
	 * Later on linux_minprivs() will be called, which will drop our
	 * capabilities to the minimum needed to run the server.
	 */

	caps = 0;

	/*
	 * We need to be able to bind() to privileged ports, notably port 53!
	 */
	caps |= (1 << CAP_NET_BIND_SERVICE);

	/*
	 * We need chroot() initially too.
	 */
	caps |= (1 << CAP_SYS_CHROOT);

#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS)
	/*
	 * We can setuid() only if either the kernel supports keeping
	 * capabilities after setuid() (which we don't know until we've
	 * tried) or we're not using threads.  If either of these is
	 * true, we want the setuid capability.
	 */
	caps |= (1 << CAP_SETUID);
#endif

	/*
	 * Since we call initgroups, we need this.
	 */
	caps |= (1 << CAP_SETGID);

	/*
	 * Without this, we run into problems reading a configuration file
	 * owned by a non-root user and non-world-readable on startup.
	 */
	caps |= (1 << CAP_DAC_READ_SEARCH);

	/*
	 * XXX  We might want to add CAP_SYS_RESOURCE, though it's not
	 *      clear it would work right given the way linuxthreads work.
	 * XXXDCL But since we need to be able to set the maximum number
	 * of files, the stack size, data size, and core dump size to
	 * support named.conf options, this is now being added to test.
	 */
	caps |= (1 << CAP_SYS_RESOURCE);

	linux_setcaps(caps);
}
Beispiel #3
0
Datei: os.c Projekt: 274914765/C
static void linux_minprivs (void)
{
    cap_t caps;

#ifdef HAVE_LIBCAP
    cap_t curcaps;

    cap_value_t capval;

    char strbuf[ISC_STRERRORSIZE];

    int err;
#endif

    INIT_CAP;
    /*%
     * Drop all privileges except the ability to bind() to privileged
     * ports.
     *
     * It's important that we drop CAP_SYS_CHROOT.  If we didn't, it
     * chroot() could be used to escape from the chrooted area.
     */

    SET_CAP (CAP_NET_BIND_SERVICE);

    /*
     * XXX  We might want to add CAP_SYS_RESOURCE, though it's not
     *      clear it would work right given the way linuxthreads work.
     * XXXDCL But since we need to be able to set the maximum number
     * of files, the stack size, data size, and core dump size to
     * support named.conf options, this is now being added to test.
     */
    SET_CAP (CAP_SYS_RESOURCE);

    linux_setcaps (caps);

#ifdef HAVE_LIBCAP
    FREE_CAP;
#endif
}
Beispiel #4
0
static void
linux_setcaps(cap_t caps) {
#ifndef HAVE_LIBCAP
	struct __user_cap_header_struct caphead;
	struct __user_cap_data_struct cap;
#endif
	char strbuf[ISC_STRERRORSIZE];

	if ((getuid() != 0 && !non_root_caps) || non_root)
		return;
#ifndef HAVE_LIBCAP
	memset(&caphead, 0, sizeof(caphead));
	caphead.version = _LINUX_CAPABILITY_VERSION;
	caphead.pid = 0;
	memset(&cap, 0, sizeof(cap));
	cap.effective = caps;
	cap.permitted = caps;
	cap.inheritable = 0;
#endif
#ifdef HAVE_LIBCAP
	if (cap_set_proc(caps) < 0) {
#else
	if (syscall(SYS_capset, &caphead, &cap) < 0) {
#endif
		isc__strerror(errno, strbuf, sizeof(strbuf));
		ns_main_earlyfatal(SETCAPS_FUNC "failed: %s:"
				   " please ensure that the capset kernel"
				   " module is loaded.  see insmod(8)",
				   strbuf);
	}
}

#ifdef HAVE_LIBCAP
#define SET_CAP(flag) \
	do { \
		capval = (flag); \
		cap_flag_value_t curval; \
		err = cap_get_flag(curcaps, capval, CAP_PERMITTED, &curval); \
		if (err != -1 && curval) { \
			err = cap_set_flag(caps, CAP_EFFECTIVE, 1, &capval, CAP_SET); \
			if (err == -1) { \
				isc__strerror(errno, strbuf, sizeof(strbuf)); \
				ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \
			} \
			\
			err = cap_set_flag(caps, CAP_PERMITTED, 1, &capval, CAP_SET); \
			if (err == -1) { \
				isc__strerror(errno, strbuf, sizeof(strbuf)); \
				ns_main_earlyfatal("cap_set_proc failed: %s", strbuf); \
			} \
		} \
	} while (0)
#define INIT_CAP \
	do { \
		caps = cap_init(); \
		if (caps == NULL) { \
			isc__strerror(errno, strbuf, sizeof(strbuf)); \
			ns_main_earlyfatal("cap_init failed: %s", strbuf); \
		} \
		curcaps = cap_get_proc(); \
		if (curcaps == NULL) { \
			isc__strerror(errno, strbuf, sizeof(strbuf)); \
			ns_main_earlyfatal("cap_get_proc failed: %s", strbuf); \
		} \
	} while (0)
#define FREE_CAP \
	{ \
		cap_free(caps); \
		cap_free(curcaps); \
	} while (0)
#else
#define SET_CAP(flag) do { caps |= (1 << (flag)); } while (0)
#define INIT_CAP do { caps = 0; } while (0)
#endif /* HAVE_LIBCAP */

static void
linux_initialprivs(void) {
	cap_t caps;
#ifdef HAVE_LIBCAP
	cap_t curcaps;
	cap_value_t capval;
	char strbuf[ISC_STRERRORSIZE];
	int err;
#endif

	/*%
	 * We don't need most privileges, so we drop them right away.
	 * Later on linux_minprivs() will be called, which will drop our
	 * capabilities to the minimum needed to run the server.
	 */
	INIT_CAP;

	/*
	 * We need to be able to bind() to privileged ports, notably port 53!
	 */
	SET_CAP(CAP_NET_BIND_SERVICE);

	/*
	 * We need chroot() initially too.
	 */
	SET_CAP(CAP_SYS_CHROOT);

#if defined(HAVE_SYS_PRCTL_H) || !defined(HAVE_LINUXTHREADS)
	/*
	 * We can setuid() only if either the kernel supports keeping
	 * capabilities after setuid() (which we don't know until we've
	 * tried) or we're not using threads.  If either of these is
	 * true, we want the setuid capability.
	 */
	SET_CAP(CAP_SETUID);
#endif

	/*
	 * Since we call initgroups, we need this.
	 */
	SET_CAP(CAP_SETGID);

	/*
	 * Without this, we run into problems reading a configuration file
	 * owned by a non-root user and non-world-readable on startup.
	 */
	SET_CAP(CAP_DAC_READ_SEARCH);

	/*
	 * XXX  We might want to add CAP_SYS_RESOURCE, though it's not
	 *      clear it would work right given the way linuxthreads work.
	 * XXXDCL But since we need to be able to set the maximum number
	 * of files, the stack size, data size, and core dump size to
	 * support named.conf options, this is now being added to test.
	 */
	SET_CAP(CAP_SYS_RESOURCE);

	/*
	 * We need to be able to set the ownership of the containing
	 * directory of the pid file when we create it.
	 */
	SET_CAP(CAP_CHOWN);

	linux_setcaps(caps);

#ifdef HAVE_LIBCAP
	FREE_CAP;
#endif
}