]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
document SIGUSR1 in manual page
[tcpdump] / tcpdump.c
index bd1664c5301497efbdef3f450f41b2af34cac9a9..8e07d8f2e1572dc307aafe86e7c40c200f4d3e99 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -750,16 +750,6 @@ droproot(const char *username, const char *chroot_dir)
                else {
                        fprintf(stderr, "dropped privs to %s\n", username);
                }
-               /* We don't need CAP_SETUID and CAP_SETGID */
-               capng_updatev(
-                       CAPNG_DROP,
-                       CAPNG_EFFECTIVE | CAPNG_PERMITTED,
-                       CAP_SETUID,
-                       CAP_SETGID,
-                       -1);
-
-               capng_apply(CAPNG_SELECT_BOTH);
-
 #else
                if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
                    setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
@@ -780,6 +770,17 @@ droproot(const char *username, const char *chroot_dir)
                    username);
                exit(1);
        }
+#ifdef HAVE_LIBCAP_NG
+       /* We don't need CAP_SETUID and CAP_SETGID any more. */
+       capng_updatev(
+               CAPNG_DROP,
+               CAPNG_EFFECTIVE | CAPNG_PERMITTED,
+               CAP_SETUID,
+               CAP_SETGID,
+               -1);
+       capng_apply(CAPNG_SELECT_BOTH);
+#endif /* HAVE_LIBCAP_NG */
+
 }
 #endif /* WIN32 */
 
@@ -1739,20 +1740,25 @@ main(int argc, char **argv)
 
        if (getuid() == 0 || geteuid() == 0) {
 #ifdef HAVE_LIBCAP_NG
-               /* Drop all capabilities from effective set */
-               capng_clear(CAPNG_EFFECTIVE);
-               /* We are running as root and we will be writing to savefile */
-               if (WFileName  && username) {
-                       /* Add capabilities we will need*/
+               /* Initialize capng */
+               capng_clear(CAPNG_SELECT_BOTH);
+               if (username) {
                        capng_updatev(
                                CAPNG_ADD,
                                CAPNG_PERMITTED | CAPNG_EFFECTIVE,
                                CAP_SETUID,
                                CAP_SETGID,
-                               CAP_DAC_OVERRIDE,
                                -1);
-                       capng_apply(CAPNG_SELECT_BOTH);
                }
+
+               if (WFileName) {
+                       capng_update(
+                               CAPNG_ADD,
+                               CAPNG_PERMITTED | CAPNG_EFFECTIVE,
+                               CAP_DAC_OVERRIDE
+                               );
+               }
+               capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
                if (username || chroot_dir)
                        droproot(username, chroot_dir);
@@ -1793,8 +1799,17 @@ main(int argc, char **argv)
 
                p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
 #ifdef HAVE_LIBCAP_NG
-        /* Give up capabilities, clear Effective set */
-        capng_clear(CAPNG_EFFECTIVE);
+               /* Give up CAP_DAC_OVERRIDE capability.
+                * Only allow it to be restored if the -C or -G flag have been
+                * set since we may need to create more files later on.
+                */
+               capng_update(
+                       CAPNG_DROP,
+                       (Cflag || Gflag ? 0 : CAPNG_PERMITTED)
+                               | CAPNG_EFFECTIVE,
+                       CAP_DAC_OVERRIDE
+                       );
+               capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
                if (p == NULL)
                        error("%s", pcap_geterr(pd));
@@ -2211,7 +2226,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
 
 #ifdef HAVE_LIBCAP_NG
                        capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
-                       capng_apply(CAPNG_EFFECTIVE);
+                       capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
 #ifdef HAVE_CAPSICUM
                        fd = openat(dump_info->dirfd,
@@ -2232,7 +2247,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
 #endif
 #ifdef HAVE_LIBCAP_NG
                        capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
-                       capng_apply(CAPNG_EFFECTIVE);
+                       capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
                        if (dump_info->p == NULL)
                                error("%s", pcap_geterr(pd));
@@ -2251,59 +2266,74 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
         * larger than Cflag - the last packet written to the
         * file could put it over Cflag.
         */
-       if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) {
+       if (Cflag != 0) {
+               long size = pcap_dump_ftell(dump_info->p);
+
+               if (size == -1)
+                       error("ftell fails on output file");
+               if (size > Cflag) {
 #ifdef HAVE_CAPSICUM
-               FILE *fp;
-               int fd;
+                       FILE *fp;
+                       int fd;
 #endif
 
-               /*
-                * Close the current file and open a new one.
-                */
-               pcap_dump_close(dump_info->p);
+                       /*
+                        * Close the current file and open a new one.
+                        */
+                       pcap_dump_close(dump_info->p);
 
-               /*
-                * Compress the file we just closed, if the user asked for it
-                */
-               if (zflag != NULL)
-                       compress_savefile(dump_info->CurrentFileName);
+                       /*
+                        * Compress the file we just closed, if the user
+                        * asked for it.
+                        */
+                       if (zflag != NULL)
+                               compress_savefile(dump_info->CurrentFileName);
 
-               Cflag_count++;
-               if (Wflag > 0) {
-                       if (Cflag_count >= Wflag)
-                               Cflag_count = 0;
-               }
-               if (dump_info->CurrentFileName != NULL)
-                       free(dump_info->CurrentFileName);
-               dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
-               if (dump_info->CurrentFileName == NULL)
-                       error("dump_packet_and_trunc: malloc");
-               MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars);
+                       Cflag_count++;
+                       if (Wflag > 0) {
+                               if (Cflag_count >= Wflag)
+                                       Cflag_count = 0;
+                       }
+                       if (dump_info->CurrentFileName != NULL)
+                               free(dump_info->CurrentFileName);
+                       dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
+                       if (dump_info->CurrentFileName == NULL)
+                               error("dump_packet_and_trunc: malloc");
+                       MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars);
+#ifdef HAVE_LIBCAP_NG
+                       capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+                       capng_apply(CAPNG_SELECT_BOTH);
+#endif /* HAVE_LIBCAP_NG */
 #ifdef HAVE_CAPSICUM
-               fd = openat(dump_info->dirfd, dump_info->CurrentFileName,
-                   O_CREAT | O_WRONLY | O_TRUNC, 0644);
-               if (fd < 0) {
-                       error("unable to open file %s",
-                           dump_info->CurrentFileName);
-               }
-               fp = fdopen(fd, "w");
-               if (fp == NULL) {
-                       error("unable to fdopen file %s",
-                           dump_info->CurrentFileName);
-               }
-               dump_info->p = pcap_dump_fopen(dump_info->pd, fp);
+                       fd = openat(dump_info->dirfd, dump_info->CurrentFileName,
+                           O_CREAT | O_WRONLY | O_TRUNC, 0644);
+                       if (fd < 0) {
+                               error("unable to open file %s",
+                                   dump_info->CurrentFileName);
+                       }
+                       fp = fdopen(fd, "w");
+                       if (fp == NULL) {
+                               error("unable to fdopen file %s",
+                                   dump_info->CurrentFileName);
+                       }
+                       dump_info->p = pcap_dump_fopen(dump_info->pd, fp);
 #else  /* !HAVE_CAPSICUM */
-               dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
+                       dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
 #endif
-               if (dump_info->p == NULL)
-                       error("%s", pcap_geterr(pd));
+#ifdef HAVE_LIBCAP_NG
+                       capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+                       capng_apply(CAPNG_SELECT_BOTH);
+#endif /* HAVE_LIBCAP_NG */
+                       if (dump_info->p == NULL)
+                               error("%s", pcap_geterr(pd));
 #ifdef HAVE_CAPSICUM
-               cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
-               if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
-                   &rights) < 0 && errno != ENOSYS) {
-                       error("unable to limit dump descriptor");
-               }
+                       cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
+                       if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)),
+                           &rights) < 0 && errno != ENOSYS) {
+                               error("unable to limit dump descriptor");
+                       }
 #endif
+               }
        }
 
        pcap_dump((u_char *)dump_info->p, h, sp);