Skip to content

Commit

Permalink
permission denied on Solaris when '-w dump.pkt' option is used
Browse files Browse the repository at this point in the history
tcpdump should open file, where captured packets are going to be written to,
before it switches to user nobody.

patch has been submitted to upstream:
the-tcpdump-group#637
  • Loading branch information
alexandr nedvedicky - Sun Microsystems - Prague Czech Republic committed Apr 17, 2019
1 parent 016f440 commit 9779061
Showing 1 changed file with 76 additions and 76 deletions.
152 changes: 76 additions & 76 deletions tcpdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1786,82 +1786,6 @@ main(int argc, char **argv)
(void)setsignal(SIGHUP, oldhandler);
#endif /* _WIN32 */

#ifndef _WIN32
/*
* If a user name was specified with "-Z", attempt to switch to
* that user's UID. This would probably be used with sudo,
* to allow tcpdump to be run in a special restricted
* account (if you just want to allow users to open capture
* devices, and can't just give users that permission,
* you'd make tcpdump set-UID or set-GID).
*
* Tcpdump doesn't necessarily write only to one savefile;
* the general only way to allow a -Z instance to write to
* savefiles as the user under whose UID it's run, rather
* than as the user specified with -Z, would thus be to switch
* to the original user ID before opening a capture file and
* then switch back to the -Z user ID after opening the savefile.
* Switching to the -Z user ID only after opening the first
* savefile doesn't handle the general case.
*/

if (getuid() == 0 || geteuid() == 0) {
#ifdef HAVE_LIBCAP_NG
/* Initialize capng */
capng_clear(CAPNG_SELECT_BOTH);
if (username) {
capng_updatev(
CAPNG_ADD,
CAPNG_PERMITTED | CAPNG_EFFECTIVE,
CAP_SETUID,
CAP_SETGID,
-1);
}
if (chroot_dir) {
capng_update(
CAPNG_ADD,
CAPNG_PERMITTED | CAPNG_EFFECTIVE,
CAP_SYS_CHROOT
);
}

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);

}
#endif /* _WIN32 */

if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd));
#ifdef HAVE_CAPSICUM
if (RFileName == NULL && VFileName == NULL) {
static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };

/*
* The various libpcap devices use a combination of
* read (bpf), ioctl (bpf, netmap), poll (netmap)
* so we add the relevant access rights.
*/
cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
if (cap_ioctls_limit(pcap_fileno(pd), cmds,
sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
error("unable to limit ioctls on pcap descriptor");
}
}
#endif
if (WFileName) {
pcap_dumper_t *p;
/* Do not exceed the default PATH_MAX for files. */
Expand Down Expand Up @@ -1940,6 +1864,82 @@ main(int argc, char **argv)
pcap_userdata = (u_char *)ndo;
}

#ifndef _WIN32
/*
* If a user name was specified with "-Z", attempt to switch to
* that user's UID. This would probably be used with sudo,
* to allow tcpdump to be run in a special restricted
* account (if you just want to allow users to open capture
* devices, and can't just give users that permission,
* you'd make tcpdump set-UID or set-GID).
*
* Tcpdump doesn't necessarily write only to one savefile;
* the general only way to allow a -Z instance to write to
* savefiles as the user under whose UID it's run, rather
* than as the user specified with -Z, would thus be to switch
* to the original user ID before opening a capture file and
* then switch back to the -Z user ID after opening the savefile.
* Switching to the -Z user ID only after opening the first
* savefile doesn't handle the general case.
*/

if (getuid() == 0 || geteuid() == 0) {
#ifdef HAVE_LIBCAP_NG
/* Initialize capng */
capng_clear(CAPNG_SELECT_BOTH);
if (username) {
capng_updatev(
CAPNG_ADD,
CAPNG_PERMITTED | CAPNG_EFFECTIVE,
CAP_SETUID,
CAP_SETGID,
-1);
}
if (chroot_dir) {
capng_update(
CAPNG_ADD,
CAPNG_PERMITTED | CAPNG_EFFECTIVE,
CAP_SYS_CHROOT
);
}

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);

}
#endif /* _WIN32 */

if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd));
#ifdef HAVE_CAPSICUM
if (RFileName == NULL && VFileName == NULL) {
static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };

/*
* The various libpcap devices use a combination of
* read (bpf), ioctl (bpf, netmap), poll (netmap)
* so we add the relevant access rights.
*/
cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
if (cap_ioctls_limit(pcap_fileno(pd), cmds,
sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
error("unable to limit ioctls on pcap descriptor");
}
}
#endif
#ifdef SIGNAL_REQ_INFO
/*
* We can't get statistics when reading from a file rather
Expand Down

0 comments on commit 9779061

Please sign in to comment.