Index: configure.ac =================================================================== --- configure.ac (revision 22990) +++ configure.ac (working copy) @@ -189,6 +189,10 @@ AST_EXT_LIB([tonezone], [tone_zone_find], [zaptel.h], [ZAPTEL], [Zaptel]) fi +if test "x${PBX_OSTYPE}" = "xLinux" ; then + AST_EXT_LIB([cap], [cap_from_text], [sys/capability.h], [POSIX1E], [Linux POSIX.1e Capabilities]) +fi + GSM_INTERNAL="yes" GSM_SYSTEM="yes" AC_ARG_WITH([gsm], AC_HELP_STRING([--with-gsm=PATH], [use libgsm files in PATH, or 'internal']), [ Index: Makefile =================================================================== --- Makefile (revision 22990) +++ Makefile (working copy) @@ -367,6 +367,9 @@ ifeq ($(OSARCH),Linux) LIBS+=-ldl -lpthread -lncurses -lm -lresolv #-lnjamd + ifneq (x$(CAP_LIB),x) + LIBS+=$(CAP_LIB) + endif else LIBS+=-lncurses -lm endif Index: makeopts.in =================================================================== --- makeopts.in (revision 22990) +++ makeopts.in (working copy) @@ -104,3 +104,6 @@ NCURSES_LIB=@ncurses_LIB@ NCURSES_INCLUDE=@ncurses_INCLUDE@ + +CAP_LIB=@cap_LIB@ +CAP_INCLUDE=@cap_INCLUDE@ Index: asterisk.c =================================================================== --- asterisk.c (revision 22990) +++ asterisk.c (working copy) @@ -76,7 +76,10 @@ #include #ifdef linux #include -#endif +#ifdef HAVE_POSIX1E +#include +#endif /* HAVE_POSIX1E */ +#endif /* linux */ #include #ifdef linux @@ -2401,10 +2404,19 @@ if (!is_child_of_nonroot && runuser) { struct passwd *pw; pw = getpwnam(runuser); +#ifdef HAVE_POSIX1E + cap_t cap; +#endif /* HAVE_POSIX1E */ if (!pw) { ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); exit(1); } +#ifdef HAVE_POSIX1E + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { + ast_log(LOG_WARNING, "Unable to keep capabilities.\n"); + exit(1); + } +#endif /* HAVE_POSIX1E */ if (!rungroup) { if (setgid(pw->pw_gid)) { ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); @@ -2419,6 +2431,17 @@ ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser); exit(1); } +#ifdef HAVE_POSIX1E + cap = cap_from_text("cap_net_admin=ep"); + if (cap_set_proc(cap)) { + ast_log(LOG_WARNING, "Unable to install capabilities.\n"); + exit(1); + } + if (cap_free(cap)) { + ast_log(LOG_WARNING, "Unable to drop capabilities.\n"); + exit(1); + } +#endif /* HAVE_POSIX1E */ setenv("ASTERISK_ALREADY_NONROOT", "yes", 1); if (option_verbose) ast_verbose("Running as user '%s'\n", runuser); Index: README =================================================================== --- README (revision 22990) +++ README (working copy) @@ -9,7 +9,13 @@ * SECURITY It is imperative that you read and fully understand the contents of the security information file (doc/security.txt) before you attempt -to configure and run an Asterisk server. +to configure and run an Asterisk server. By default, if you have libcap +available, Asterisk will try to retain the CAP_NET_ADMIN capability +when running as a non-root user. If you do not need that capability you +may want to configure Asterisk with --without-cap however this will +prevent Asterisk from being able to mark high ToS bits under Linux. +More information on CAP_NET_ADMIN is available at: +http://www.lids.org/lids-howto/node48.html * WHAT IS ASTERISK ? Asterisk is an Open Source PBX and telephony toolkit. It is, in a