]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/options.c
Check the result of seteuid(), just to be paranoid.
[ppp.git] / pppd / options.c
index 7f4f5eb80af4d68004811a868b4f11e9c7651119..5c9d3a0d9534345460c7dc247521506d59bd630d 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: options.c,v 1.90 2002/12/04 23:03:32 paulus Exp $"
+#define RCSID  "$Id: options.c,v 1.99 2006/06/04 07:04:57 paulus Exp $"
 
 #include <ctype.h>
 #include <stdio.h>
 #ifdef PLUGIN
 #include <dlfcn.h>
 #endif
+
 #ifdef PPP_FILTER
 #include <pcap.h>
-#include <pcap-int.h>  /* XXX: To get struct pcap */
+/*
+ * There have been 3 or 4 different names for this in libpcap CVS, but
+ * this seems to be what they have settled on...
+ * For older versions of libpcap, use DLT_PPP - but that means
+ * we lose the inbound and outbound qualifiers.
+ */
+#ifndef DLT_PPP_PPPD
+#ifdef DLT_PPP_WITHDIRECTION
+#define DLT_PPP_PPPD   DLT_PPP_WITHDIRECTION
+#else
+#define DLT_PPP_PPPD   DLT_PPP
 #endif
+#endif
+#endif /* PPP_FILTER */
 
 #include "pppd.h"
 #include "pathnames.h"
@@ -77,9 +90,6 @@ struct option_value {
 /*
  * Option variables and default values.
  */
-#ifdef PPP_FILTER
-int    dflag = 0;              /* Tell libpcap we want debugging */
-#endif
 int    debug = 0;              /* Debug flag */
 int    kdebugflag = 0;         /* Tell kernel to print debug messages */
 int    default_device = 1;     /* Using /dev/tty or equivalent */
@@ -108,6 +118,7 @@ char        *bundle_name = NULL;    /* bundle name for multilink */
 bool   dump_options;           /* print out option values */
 bool   dryrun;                 /* print out option values and exit */
 char   *domain;                /* domain name set by domain option */
+int    child_wait = 5;         /* # seconds to wait for children at exit */
 
 #ifdef MAXOCTETS
 unsigned int  maxoctets = 0;    /* default - no limit */
@@ -122,7 +133,6 @@ extern struct stat devstat;
 #ifdef PPP_FILTER
 struct bpf_program pass_filter;/* Filter program for packets to pass */
 struct bpf_program active_filter; /* Filter program for link-active pkts */
-pcap_t  pc;                    /* Fake struct pcap so we can compile expr */
 #endif
 
 char *current_option;          /* the name of the option being parsed */
@@ -194,7 +204,8 @@ option_t general_options[] = {
       OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach },
 
     { "holdoff", o_int, &holdoff,
-      "Set time in seconds before retrying connection", OPT_PRIO },
+      "Set time in seconds before retrying connection",
+      OPT_PRIO, &holdoff_specified },
 
     { "idle", o_int, &idle_time_limit,
       "Set time in seconds before disconnecting idle link", OPT_PRIO },
@@ -266,6 +277,10 @@ option_t general_options[] = {
     { "dryrun", o_bool, &dryrun,
       "Stop after parsing, printing, and checking options", 1 },
 
+    { "child-timeout", o_int, &child_wait,
+      "Number of seconds to wait for child processes at exit",
+      OPT_PRIO },
+
 #ifdef HAVE_MULTILINK
     { "multilink", o_bool, &multilink,
       "Enable multilink operation", OPT_PRIO | 1 },
@@ -286,13 +301,10 @@ option_t general_options[] = {
 #endif
 
 #ifdef PPP_FILTER
-    { "pdebug", o_int, &dflag,
-      "libpcap debugging", OPT_PRIO },
-
-    { "pass-filter", 1, setpassfilter,
+    { "pass-filter", o_special, setpassfilter,
       "set filter for packets to pass", OPT_PRIO },
 
-    { "active-filter", 1, setactivefilter,
+    { "active-filter", o_special, setactivefilter,
       "set filter for active pkts", OPT_PRIO },
 #endif
 
@@ -391,12 +403,14 @@ options_from_file(filename, must_exist, check_prot, priv)
     char args[MAXARGS][MAXWORDLEN];
     char cmd[MAXWORDLEN];
 
-    if (check_prot)
-       seteuid(getuid());
+    if (check_prot && seteuid(getuid()) == -1) {
+       option_error("unable to drop privileges to open %s: %m", filename);
+       return 0;
+    }
     f = fopen(filename, "r");
     err = errno;
-    if (check_prot)
-       seteuid(0);
+    if (check_prot && seteuid(0) == -1)
+       fatal("unable to regain privileges");
     if (f == NULL) {
        errno = err;
        if (!must_exist) {
@@ -487,8 +501,8 @@ options_for_tty()
     size_t pl;
 
     dev = devnam;
-    if (strncmp(dev, "/dev/", 5) == 0)
-       dev += 5;
+    if ((p = strstr(dev, "/dev/")) != NULL)
+       dev = p + 5;
     if (dev[0] == 0 || strcmp(dev, "tty") == 0)
        return 1;               /* don't look for /etc/ppp/options.tty */
     pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1;
@@ -1439,13 +1453,18 @@ static int
 setpassfilter(argv)
     char **argv;
 {
-    pc.linktype = DLT_PPP;
-    pc.snapshot = PPP_HDRLEN;
-    if (pcap_compile(&pc, &pass_filter, *argv, 1, netmask) == 0)
-       return 1;
-    option_error("error in pass-filter expression: %s\n", pcap_geterr(&pc));
-    return 0;
+    pcap_t *pc;
+    int ret = 1;
+
+    pc = pcap_open_dead(DLT_PPP_PPPD, 65535);
+    if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) {
+       option_error("error in pass-filter expression: %s\n",
+                    pcap_geterr(pc));
+       ret = 0;
+    }
+    pcap_close(pc);
+
+    return ret;
 }
 
 /*
@@ -1455,13 +1474,18 @@ static int
 setactivefilter(argv)
     char **argv;
 {
-    pc.linktype = DLT_PPP;
-    pc.snapshot = PPP_HDRLEN;
-    if (pcap_compile(&pc, &active_filter, *argv, 1, netmask) == 0)
-       return 1;
-    option_error("error in active-filter expression: %s\n", pcap_geterr(&pc));
-    return 0;
+    pcap_t *pc;
+    int ret = 1;
+
+    pc = pcap_open_dead(DLT_PPP_PPPD, 65535);
+    if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) {
+       option_error("error in active-filter expression: %s\n",
+                    pcap_geterr(pc));
+       ret = 0;
+    }
+    pcap_close(pc);
+
+    return ret;
 }
 #endif
 
@@ -1483,21 +1507,22 @@ setdomain(argv)
     return (1);
 }
 
-
 static int
 setlogfile(argv)
     char **argv;
 {
     int fd, err;
 
-    if (!privileged_option)
-       seteuid(getuid());
+    if (!privileged_option && seteuid(getuid()) == -1) {
+       option_error("unable to drop permissions to open %s: %m", *argv);
+       return 0;
+    }
     fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644);
     if (fd < 0 && errno == EEXIST)
        fd = open(*argv, O_WRONLY | O_APPEND);
     err = errno;
-    if (!privileged_option)
-       seteuid(0);
+    if (!privileged_option && seteuid(0) == -1)
+       fatal("unable to regain privileges: %m");
     if (fd < 0) {
        errno = err;
        option_error("Can't open log file %s: %m", *argv);
@@ -1511,6 +1536,7 @@ setlogfile(argv)
     log_default = 0;
     return 1;
 }
+
 #ifdef MAXOCTETS
 static int
 setmodir(argv)