Add ability to set high ToS bits as non-root on Linux using libcap (issue #7047 repor...
[asterisk/asterisk.git] / main / asterisk.c
index 2ece4c7..91d4513 100644 (file)
@@ -80,13 +80,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <sys/stat.h>
 #ifdef linux
 #include <sys/prctl.h>
 #include <sys/stat.h>
 #ifdef linux
 #include <sys/prctl.h>
-#endif
+#ifdef HAVE_CAP
+#include <sys/capability.h>
+#endif /* HAVE_CAP */
+#endif /* linux */
 #include <regex.h>
 
 #include <regex.h>
 
-#ifdef linux
-#include <sys/prctl.h>
-#endif
-
 #if  defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS)
 #include <netdb.h>
 #if defined(SOLARIS)
 #if  defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS)
 #include <netdb.h>
 #if defined(SOLARIS)
@@ -2521,12 +2520,22 @@ int main(int argc, char *argv[])
        }
 
        if (!is_child_of_nonroot && runuser) {
        }
 
        if (!is_child_of_nonroot && runuser) {
+#ifdef HAVE_CAP
+               cap_t cap;
+               int has_cap = 1;
+#endif /* HAVE_CAP */
                struct passwd *pw;
                pw = getpwnam(runuser);
                if (!pw) {
                        ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
                        exit(1);
                }
                struct passwd *pw;
                pw = getpwnam(runuser);
                if (!pw) {
                        ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
                        exit(1);
                }
+#ifdef HAVE_CAP
+               if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
+                       ast_log(LOG_WARNING, "Unable to keep capabilities.\n");
+                       has_cap  = 0;
+               }
+#endif /* HAVE_CAP */
                if (!rungroup) {
                        if (setgid(pw->pw_gid)) {
                                ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
                if (!rungroup) {
                        if (setgid(pw->pw_gid)) {
                                ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid);
@@ -2544,6 +2553,18 @@ int main(int argc, char *argv[])
                setenv("ASTERISK_ALREADY_NONROOT", "yes", 1);
                if (option_verbose)
                        ast_verbose("Running as user '%s'\n", runuser);
                setenv("ASTERISK_ALREADY_NONROOT", "yes", 1);
                if (option_verbose)
                        ast_verbose("Running as user '%s'\n", runuser);
+#ifdef HAVE_CAP
+               if (has_cap) {
+                       cap = cap_from_text("cap_net_admin=ep");
+                       if (cap_set_proc(cap)) {
+                               ast_log(LOG_WARNING, "Unable to install capabilities.\n");
+                               break;
+                       }
+                       if (cap_free(cap)) {
+                               ast_log(LOG_WARNING, "Unable to drop capabilities.\n");
+                       }
+               }
+#endif /* HAVE_CAP */
        }
 
 #endif /* __CYGWIN__ */
        }
 
 #endif /* __CYGWIN__ */