From: Paul Mackerras Date: Mon, 3 Mar 2003 05:11:46 +0000 (+0000) Subject: A bunch of fixes mostly aimed at fixing the problems we have been X-Git-Tag: ppp-2.4.7~322 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=cb67581446e926290c6147634f7f467f48c806b5 A bunch of fixes mostly aimed at fixing the problems we have been having with leaking fds and with fatal errors occurring when the link goes down. Updated patchlevel.h to 2.4.2b2. Moved open of /dev/ppp to generic_establish_ppp; we now close the ppp_dev_fd in generic_disestablish_ppp rather than trying to use PPPIOCDETACH. *_send_config and *_recv_config now return 0 for success or -1 for error, rather than calling fatal() when an error occurs. Added a notifier for when we fork so plugins can close their fds in the child. Added a safe_fork() which does a fork and then closes stuff in the child; the parent waits until the child has done that. On detach, the parent rewrites the pid files rather than the child, and the child waits for the parent to die. Fixed some potential FILE * leaks. Also moved auth_number() check into auth_check_options. --- diff --git a/pppd/auth.c b/pppd/auth.c index a4f7775..d554bfd 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -73,7 +73,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: auth.c,v 1.92 2003/02/16 22:29:50 paulus Exp $" +#define RCSID "$Id: auth.c,v 1.93 2003/03/03 05:11:45 paulus Exp $" #include #include @@ -428,7 +428,8 @@ setupapfile(argv) /* get username */ if (fgets(u, MAXNAMELEN - 1, ufile) == NULL - || fgets(p, MAXSECRETLEN - 1, ufile) == NULL){ + || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { + fclose(ufile); option_error("unable to read user login data file %s", fname); return 0; } @@ -1149,6 +1150,14 @@ auth_check_options() exit(1); } + + /* + * Early check for remote number authorization. + */ + if (!auth_number()) { + warn("calling number %q is not authorized", remote_number); + exit(EXIT_CNID_AUTH_FAILED); + } } /* diff --git a/pppd/demand.c b/pppd/demand.c index db5dd90..395a598 100644 --- a/pppd/demand.c +++ b/pppd/demand.c @@ -33,7 +33,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: demand.c,v 1.16 2002/12/04 23:03:32 paulus Exp $" +#define RCSID "$Id: demand.c,v 1.17 2003/03/03 05:11:45 paulus Exp $" #include #include @@ -102,8 +102,9 @@ demand_conf() fcs = PPP_INITFCS; netif_set_mtu(0, MIN(lcp_allowoptions[0].mru, PPP_MRU)); - ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); - ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); + if (ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0 + || ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0) < 0) + fatal("Couldn't set up demand-dialled PPP interface: %m"); #ifdef PPP_FILTER set_filters(&pass_filter, &active_filter); diff --git a/pppd/lcp.c b/pppd/lcp.c index 442ae22..e44a781 100644 --- a/pppd/lcp.c +++ b/pppd/lcp.c @@ -40,7 +40,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: lcp.c,v 1.64 2002/12/04 23:03:32 paulus Exp $" +#define RCSID "$Id: lcp.c,v 1.65 2003/03/03 05:11:46 paulus Exp $" /* * TODO: @@ -433,9 +433,10 @@ lcp_lowerup(unit) * but accept A/C and protocol compressed packets * if we are going to ask for A/C and protocol compression. */ - ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), - wo->neg_pcompression, wo->neg_accompression); + if (ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0) < 0 + || ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff), + wo->neg_pcompression, wo->neg_accompression) < 0) + return; peer_mru[unit] = PPP_MRU; if (listen_time != 0) { diff --git a/pppd/main.c b/pppd/main.c index 5f30dd1..a01b852 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -40,7 +40,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: main.c,v 1.122 2003/02/24 12:46:37 fcusack Exp $" +#define RCSID "$Id: main.c,v 1.123 2003/03/03 05:11:46 paulus Exp $" #include #include @@ -113,6 +113,7 @@ struct notifier *pidchange = NULL; struct notifier *phasechange = NULL; struct notifier *exitnotify = NULL; struct notifier *sigreceived = NULL; +struct notifier *fork_notifier = NULL; int hungup; /* terminal has been hung up */ int privileged; /* we're running as real uid root */ @@ -139,6 +140,7 @@ static int conn_running; /* we have a [dis]connector running */ static int devfd; /* fd of underlying device */ static int fd_ppp = -1; /* fd for talking PPP */ static int fd_loop; /* fd for getting demand-dial packets */ +static int fd_devnull; /* fd for /dev/null */ int phase; /* where the link is at */ int kill_link; @@ -190,8 +192,8 @@ static struct subprocess *children; /* Prototypes for procedures local to this file. */ static void setup_signals __P((void)); -static void create_pidfile __P((void)); -static void create_linkpidfile __P((void)); +static void create_pidfile __P((int pid)); +static void create_linkpidfile __P((int pid)); static void cleanup __P((void)); static void get_input __P((void)); static void calltimeout __P((void)); @@ -278,18 +280,6 @@ main(argc, argv) link_stats_valid = 0; new_phase(PHASE_INITIALIZE); - /* - * Ensure that fds 0, 1, 2 are open, to /dev/null if nowhere else. - * This way we can close 0, 1, 2 in detach() without clobbering - * a fd that we are using. - */ - if ((i = open("/dev/null", O_RDWR)) >= 0) { - while (0 <= i && i <= 2) - i = dup(i); - if (i >= 0) - close(i); - } - script_env = NULL; /* Initialize syslog facilities */ @@ -387,14 +377,6 @@ main(argc, argv) end_pr_log(); } - /* - * Early check for remote number authorization. - */ - if (!auth_number()) { - warn("calling number %q is not authorized", remote_number); - exit(EXIT_CNID_AUTH_FAILED); - } - if (dryrun) die(0); @@ -403,6 +385,17 @@ main(argc, argv) */ sys_init(); + /* Make sure fds 0, 1, 2 are open to somewhere. */ + fd_devnull = open(_PATH_DEVNULL, O_RDWR); + if (fd_devnull < 0) + fatal("Couldn't open %s: %m", _PATH_DEVNULL); + while (fd_devnull <= 2) { + i = dup(fd_devnull); + if (i < 0) + fatal("Critical shortage of file descriptors: dup failed: %m"); + fd_devnull = i; + } + #ifdef USE_TDB pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644); if (pppdb != NULL) { @@ -443,7 +436,7 @@ main(argc, argv) waiting = 0; - create_linkpidfile(); + create_linkpidfile(getpid()); /* * If we're doing dial-on-demand, set up the interface now. @@ -783,8 +776,8 @@ set_ifunit(iskey) slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); script_setenv("IFNAME", ifname, iskey); if (iskey) { - create_pidfile(); /* write pid to file */ - create_linkpidfile(); + create_pidfile(getpid()); /* write pid to file */ + create_linkpidfile(getpid()); } } @@ -796,9 +789,12 @@ detach() { int pid; char numbuf[16]; + int pipefd[2]; if (detached) return; + if (pipe(pipefd) == -1) + pipefd[0] = pipefd[1] = -1; if ((pid = fork()) < 0) { error("Couldn't detach (fork failed: %m)"); die(1); /* or just return? */ @@ -806,23 +802,28 @@ detach() if (pid != 0) { /* parent */ notify(pidchange, pid); + /* update pid files if they have been written already */ + if (pidfilename[0]) + create_pidfile(pid); + if (linkpidfile[0]) + create_linkpidfile(pid); exit(0); /* parent dies */ } setsid(); chdir("/"); - close(0); - close(1); - close(2); + dup2(fd_devnull, 0); + dup2(fd_devnull, 1); + dup2(fd_devnull, 2); detached = 1; if (log_default) log_to_fd = -1; - /* update pid files if they have been written already */ - if (pidfilename[0]) - create_pidfile(); - if (linkpidfile[0]) - create_linkpidfile(); slprintf(numbuf, sizeof(numbuf), "%d", getpid()); script_setenv("PPPD_PID", numbuf, 1); + + /* wait for parent to finish updating pid & lock files and die */ + close(pipefd[1]); + read(pipefd[0], numbuf, 1); + close(pipefd[0]); } /* @@ -843,7 +844,8 @@ reopen_log() * Create a file containing our process ID. */ static void -create_pidfile() +create_pidfile(pid) + int pid; { FILE *pidfile; @@ -859,7 +861,8 @@ create_pidfile() } static void -create_linkpidfile() +create_linkpidfile(pid) + int pid; { FILE *pidfile; @@ -1405,6 +1408,40 @@ bad_signal(sig) die(127); } +/* + * safe_fork - Create a child process. The child closes all the + * file descriptors that we don't want to leak to a script. + * The parent waits for the child to do this before returning. + */ +pid_t +safe_fork() +{ + pid_t pid; + int pipefd[2]; + char buf[1]; + + if (pipe(pipefd) == -1) + pipefd[0] = pipefd[1] = -1; + pid = fork(); + if (pid < 0) + return -1; + if (pid > 0) { + close(pipefd[1]); + /* this read() blocks until the close(pipefd[1]) below */ + read(pipefd[0], buf, 1); + close(pipefd[0]); + return pid; + } + sys_close(); +#ifdef USE_TDB + tdb_close(pppdb); +#endif + notify(fork_notifier, 0); + close(pipefd[0]); + /* this close unblocks the read() call above in the parent */ + close(pipefd[1]); + return 0; +} /* * device_script - run a program to talk to the specified fds @@ -1417,12 +1454,12 @@ device_script(program, in, out, dont_wait) int in, out; int dont_wait; { - int pid, fd; + int pid; int status = -1; int errfd; ++conn_running; - pid = fork(); + pid = safe_fork(); if (pid < 0) { --conn_running; @@ -1446,13 +1483,6 @@ device_script(program, in, out, dont_wait) } /* here we are executing in the child */ - /* make sure fds 0, 1, 2 are occupied */ - while ((fd = dup(in)) >= 0) { - if (fd > 2) { - close(fd); - break; - } - } /* dup in and out to fds > 2 */ { @@ -1474,10 +1504,10 @@ device_script(program, in, out, dont_wait) close(0); close(1); close(2); - sys_close(); if (the_channel->close) (*the_channel->close)(); closelog(); + close(fd_devnull); /* dup the in, out, err fds to 0, 1, 2 */ dup2(in, 0); @@ -1537,66 +1567,54 @@ run_program(prog, args, must_exist, done, arg) return 0; } - pid = fork(); + pid = safe_fork(); if (pid == -1) { error("Failed to create child process for %s: %m", prog); return -1; } - if (pid == 0) { - int new_fd; + if (pid != 0) { + if (debug) + dbglog("Script %s started (pid %d)", prog, pid); + record_child(pid, prog, done, arg); + return pid; + } - /* Leave the current location */ - (void) setsid(); /* No controlling tty. */ - (void) umask (S_IRWXG|S_IRWXO); - (void) chdir ("/"); /* no current directory. */ - setuid(0); /* set real UID = root */ - setgid(getegid()); + /* Leave the current location */ + (void) setsid(); /* No controlling tty. */ + (void) umask (S_IRWXG|S_IRWXO); + (void) chdir ("/"); /* no current directory. */ + setuid(0); /* set real UID = root */ + setgid(getegid()); - /* Ensure that nothing of our device environment is inherited. */ - sys_close(); - closelog(); - close (0); - close (1); - close (2); - if (the_channel->close) - (*the_channel->close)(); - - /* Don't pass handles to the PPP device, even by accident. */ - new_fd = open (_PATH_DEVNULL, O_RDWR); - if (new_fd >= 0) { - if (new_fd != 0) { - dup2 (new_fd, 0); /* stdin <- /dev/null */ - close (new_fd); - } - dup2 (0, 1); /* stdout -> /dev/null */ - dup2 (0, 2); /* stderr -> /dev/null */ - } + /* Ensure that nothing of our device environment is inherited. */ + closelog(); + if (the_channel->close) + (*the_channel->close)(); + + /* Don't pass handles to the PPP device, even by accident. */ + dup2(fd_devnull, 0); + dup2(fd_devnull, 1); + dup2(fd_devnull, 2); + close(fd_devnull); #ifdef BSD - /* Force the priority back to zero if pppd is running higher. */ - if (setpriority (PRIO_PROCESS, 0, 0) < 0) - warn("can't reset priority to 0: %m"); + /* Force the priority back to zero if pppd is running higher. */ + if (setpriority (PRIO_PROCESS, 0, 0) < 0) + warn("can't reset priority to 0: %m"); #endif - /* SysV recommends a second fork at this point. */ + /* SysV recommends a second fork at this point. */ - /* run the program */ - execve(prog, args, script_env); - if (must_exist || errno != ENOENT) { - /* have to reopen the log, there's nowhere else - for the message to go. */ - reopen_log(); - syslog(LOG_ERR, "Can't execute %s: %m", prog); - closelog(); - } - _exit(-1); + /* run the program */ + execve(prog, args, script_env); + if (must_exist || errno != ENOENT) { + /* have to reopen the log, there's nowhere else + for the message to go. */ + reopen_log(); + syslog(LOG_ERR, "Can't execute %s: %m", prog); + closelog(); } - - if (debug) - dbglog("Script %s started (pid %d)", prog, pid); - record_child(pid, prog, done, arg); - - return pid; + _exit(-1); } diff --git a/pppd/options.c b/pppd/options.c index 7f4f5eb..b8a2103 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -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.91 2003/03/03 05:11:46 paulus Exp $" #include #include @@ -1483,7 +1483,6 @@ setdomain(argv) return (1); } - static int setlogfile(argv) char **argv; @@ -1511,6 +1510,7 @@ setlogfile(argv) log_default = 0; return 1; } + #ifdef MAXOCTETS static int setmodir(argv) diff --git a/pppd/patchlevel.h b/pppd/patchlevel.h index d22c191..9b143e3 100644 --- a/pppd/patchlevel.h +++ b/pppd/patchlevel.h @@ -1,4 +1,4 @@ -/* $Id: patchlevel.h,v 1.55 2003/02/16 22:31:41 paulus Exp $ */ +/* $Id: patchlevel.h,v 1.56 2003/03/03 05:11:46 paulus Exp $ */ -#define VERSION "2.4.2b1" -#define DATE "17 February 2003" +#define VERSION "2.4.2b2" +#define DATE "3 March 2003" diff --git a/pppd/pppd.h b/pppd/pppd.h index f6ad318..60ca8b5 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -39,7 +39,7 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: pppd.h,v 1.79 2003/02/16 22:26:27 paulus Exp $ + * $Id: pppd.h,v 1.80 2003/03/03 05:11:46 paulus Exp $ */ /* @@ -252,6 +252,7 @@ extern struct notifier *ip_up_notifier; /* IPCP has come up */ extern struct notifier *ip_down_notifier; /* IPCP has gone down */ extern struct notifier *auth_up_notifier; /* peer has authenticated */ extern struct notifier *link_down_notifier; /* link has gone down */ +extern struct notifier *fork_notifier; /* we are a new child process */ /* Values for do_callback and doing_callback */ #define CALLBACK_DIALIN 1 /* we are expecting the call back */ @@ -438,9 +439,9 @@ struct channel { /* take the channel out of PPP `mode', restore loopback if demand */ void (*disestablish_ppp) __P((int)); /* set the transmit-side PPP parameters of the channel */ - void (*send_config) __P((int, u_int32_t, int, int)); + int (*send_config) __P((int, u_int32_t, int, int)); /* set the receive-side PPP parameters of the channel */ - void (*recv_config) __P((int, u_int32_t, int, int)); + int (*recv_config) __P((int, u_int32_t, int, int)); /* cleanup on error or normal exit */ void (*cleanup) __P((void)); /* close the device, called in children after fork */ @@ -450,16 +451,12 @@ struct channel { extern struct channel *the_channel; #define ppp_send_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->send_config)((mtu), (accm), (pc), (acc)); \ -} while (0) + (the_channel->send_config? \ + (*the_channel->send_config)((mtu), (accm), (pc), (acc)): 0) #define ppp_recv_config(unit, mtu, accm, pc, acc) \ -do { \ - if (the_channel->send_config) \ - (*the_channel->recv_config)((mtu), (accm), (pc), (acc)); \ -} while (0) + (the_channel->recv_config? \ + (*the_channel->recv_config)((mtu), (accm), (pc), (acc)): 0) /* * Prototypes. @@ -476,6 +473,7 @@ void timeout __P((void (*func)(void *), void *arg, int s, int us)); void untimeout __P((void (*func)(void *), void *arg)); /* Cancel call to func(arg) */ void record_child __P((int, char *, void (*) (void *), void *)); +pid_t safe_fork __P((void)); /* Fork & close stuff in child */ int device_script __P((char *cmd, int in, int out, int dont_wait)); /* Run `cmd' with given stdin and stdout */ pid_t run_program __P((char *prog, char **args, int must_exist, @@ -588,11 +586,11 @@ void add_fd __P((int)); /* Add fd to set to wait for */ void remove_fd __P((int)); /* Remove fd from set to wait for */ int read_packet __P((u_char *)); /* Read PPP packet */ int get_loop_output __P((void)); /* Read pkts from loopback */ -void tty_send_config __P((int, u_int32_t, int, int)); +int tty_send_config __P((int, u_int32_t, int, int)); /* Configure i/f transmit parameters */ void tty_set_xaccm __P((ext_accm)); /* Set extended transmit ACCM */ -void tty_recv_config __P((int, u_int32_t, int, int)); +int tty_recv_config __P((int, u_int32_t, int, int)); /* Configure i/f receive parameters */ int ccp_test __P((int, u_char *, int, int)); /* Test support for compression scheme */ diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 099db53..0b6db1c 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -183,7 +183,7 @@ static int master_fd = -1; #ifdef INET6 static int sock6_fd = -1; #endif /* INET6 */ -int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ +int ppp_dev_fd = -1; /* fd for /dev/ppp (new style driver) */ static int chindex; /* channel index (new style driver) */ static fd_set in_fds; /* set of fds that wait_input waits for */ @@ -225,7 +225,7 @@ static int kernel_version; /* Prototypes for procedures local to this file. */ static int get_flags (int fd); -static void set_flags (int fd, int flags); +static int set_flags (int fd, int flags); static int translate_speed (int bps); static int baud_rate_of (int speed); static void close_route_table (void); @@ -300,14 +300,16 @@ static int get_flags (int fd) /********************************************************************/ -static void set_flags (int fd, int flags) +static int set_flags (int fd, int flags) { SYSDEBUG ((LOG_DEBUG, "set flags = %x\n", flags)); if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) { if (! ok_error (errno) ) - fatal("ioctl(PPPIOCSFLAGS, %x): %m (line %d)", flags, errno, __LINE__); + error("Failed to set PPP kernel option flags: %m", flags); + return -1; } + return 0; } /******************************************************************** @@ -317,18 +319,6 @@ static void set_flags (int fd, int flags) void sys_init(void) { - int flags; - - if (new_style_driver) { - ppp_dev_fd = open("/dev/ppp", O_RDWR); - if (ppp_dev_fd < 0) - fatal("Couldn't open /dev/ppp: %m"); - flags = fcntl(ppp_dev_fd, F_GETFL); - if (flags == -1 - || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) - warn("Couldn't set /dev/ppp to nonblock: %m"); - } - /* Get an internet socket for doing socket ioctls. */ sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) @@ -381,11 +371,14 @@ sys_close(void) close(ppp_dev_fd); if (sock_fd >= 0) close(sock_fd); +#ifdef INET6 + if (sock6_fd >= 0) + close(sock6_fd); +#endif if (slave_fd >= 0) close(slave_fd); if (master_fd >= 0) close(master_fd); - closelog(); } /******************************************************************** @@ -472,9 +465,9 @@ int generic_establish_ppp (int fd) int x; if (new_style_driver) { - /* Open another instance of /dev/ppp and connect the channel to it */ int flags; + /* Open an instance of /dev/ppp and connect the channel to it */ if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { error("Couldn't get channel number: %m"); goto err; @@ -617,10 +610,11 @@ void generic_disestablish_ppp(int dev_fd) if (demand) { set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_LOOP_TRAFFIC); looped = 1; - } else if (ifunit >= 0 && ioctl(ppp_dev_fd, PPPIOCDETACH) < 0) - error("Couldn't release PPP unit: %m"); - if (!multilink) + } else if (ifunit >= 0) { + close(ppp_dev_fd); remove_fd(ppp_dev_fd); + ppp_dev_fd = -1; + } } else { /* old-style driver */ if (demand) @@ -634,7 +628,19 @@ void generic_disestablish_ppp(int dev_fd) */ static int make_ppp_unit() { - int x; + int x, flags; + + if (ppp_dev_fd >= 0) { + dbglog("in make_ppp_unit, already had /dev/ppp open?"); + close(ppp_dev_fd); + } + ppp_dev_fd = open("/dev/ppp", O_RDWR); + if (ppp_dev_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + flags = fcntl(ppp_dev_fd, F_GETFL); + if (flags == -1 + || fcntl(ppp_dev_fd, F_SETFL, flags | O_NONBLOCK) == -1) + warn("Couldn't set /dev/ppp to nonblock: %m"); ifunit = req_unit; x = ioctl(ppp_dev_fd, PPPIOCNEWUNIT, &ifunit); @@ -701,17 +707,25 @@ void make_new_bundle(int mrru, int mtru, int rssn, int tssn) */ int bundle_attach(int ifnum) { + int master_fd; + if (!new_style_driver) return -1; - if (ioctl(ppp_dev_fd, PPPIOCATTACH, &ifnum) < 0) { - if (errno == ENXIO) + master_fd = open("/dev/ppp", O_RDWR); + if (master_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { + if (errno == ENXIO) { + close(master_fd); return 0; /* doesn't still exist */ + } fatal("Couldn't attach to interface unit %d: %m\n", ifnum); } if (ioctl(ppp_fd, PPPIOCCONNECT, &ifnum) < 0) fatal("Couldn't connect to interface unit %d: %m", ifnum); - set_flags(ppp_dev_fd, get_flags(ppp_dev_fd) | SC_MULTILINK); + set_flags(master_fd, get_flags(master_fd) | SC_MULTILINK); + close(master_fd); ifunit = ifnum; return 1; @@ -1175,7 +1189,7 @@ netif_get_mtu(int unit) * the ppp interface. */ -void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp) +int tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp) { u_int x; @@ -1183,20 +1197,22 @@ void tty_send_config (int mtu,u_int32_t asyncmap,int pcomp,int accomp) * Set the asyncmap and other parameters for the ppp device */ if (!still_ppp()) - return; + return 0; link_mtu = mtu; SYSDEBUG ((LOG_DEBUG, "send_config: asyncmap = %lx\n", asyncmap)); if (ioctl(ppp_fd, PPPIOCSASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - fatal("ioctl(PPPIOCSASYNCMAP): %m (line %d)", __LINE__); - return; + if (errno != EIO && errno != ENOTTY) + error("Couldn't set transmit async character map: %m"); + else if (debug) + dbglog("PPPIOCSASYNCMAP: %m"); + return -1; } x = get_flags(ppp_fd); x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT; x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC; x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC; - set_flags(ppp_fd, x); + return set_flags(ppp_fd, x); } /******************************************************************** @@ -1223,31 +1239,42 @@ void tty_set_xaccm (ext_accm accm) * the ppp interface. */ -void tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp) +int tty_recv_config (int mru,u_int32_t asyncmap,int pcomp,int accomp) { + int ret = 0; + SYSDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru)); /* * If we were called because the link has gone down then there is nothing * which may be done. Just return without incident. */ if (!still_ppp()) - return; + return 0; /* * Set the receiver parameters */ if (ioctl(ppp_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { - if ( ! ok_error (errno)) - error("ioctl(PPPIOCSMRU): %m (line %d)", __LINE__); + if (errno != EIO && errno != ENOTTY) + error("Couldn't set channel receive MRU: %m"); + else if (debug) + dbglog("PPPIOCSMRU: %m"); + ret = -1; } if (new_style_driver && ifunit >= 0 - && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) + && ioctl(ppp_dev_fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { error("Couldn't set MRU in generic PPP layer: %m"); + ret = -1; + } SYSDEBUG ((LOG_DEBUG, "recv_config: asyncmap = %lx\n", asyncmap)); if (ioctl(ppp_fd, PPPIOCSRASYNCMAP, (caddr_t) &asyncmap) < 0) { - if (!ok_error(errno)) - error("ioctl(PPPIOCSRASYNCMAP): %m (line %d)", __LINE__); + if (errno != EIO && errno != ENOTTY) + error("Couldn't set channel receive asyncmap: %m"); + else if (debug) + dbglog("PPPIOCSRASYNCMAP: %m"); + ret = -1; } + return ret; } /******************************************************************** diff --git a/pppd/sys-solaris.c b/pppd/sys-solaris.c index 10803e2..d3675f6 100644 --- a/pppd/sys-solaris.c +++ b/pppd/sys-solaris.c @@ -90,7 +90,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: sys-solaris.c,v 1.9 2002/12/04 23:03:33 paulus Exp $" +#define RCSID "$Id: sys-solaris.c,v 1.10 2003/03/03 05:11:46 paulus Exp $" #include #include @@ -1539,24 +1539,27 @@ netif_set_mtu(unit, mtu) * tty_send_config - configure the transmit characteristics of * the ppp interface. */ -void +int tty_send_config(mtu, asyncmap, pcomp, accomp) int mtu; u_int32_t asyncmap; int pcomp, accomp; { int cf[2]; + int ret = 0; link_mtu = mtu; if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { if (hungup && errno == ENXIO) - return; + return -1; error("Couldn't set MTU: %m"); + ret = -1; } if (fdmuxid >= 0) { if (!sync_serial) { if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { error("Couldn't set transmit ACCM: %m"); + ret = -1; } } cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); @@ -1564,8 +1567,10 @@ tty_send_config(mtu, asyncmap, pcomp, accomp) if (any_compressions() && strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC compression: %m"); + ret = -1; } } + return ret; } /* @@ -1589,24 +1594,27 @@ tty_set_xaccm(accm) * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */ -void +int tty_recv_config(mru, asyncmap, pcomp, accomp) int mru; u_int32_t asyncmap; int pcomp, accomp; { int cf[2]; + int ret = 0; link_mru = mru; if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { if (hungup && errno == ENXIO) - return; + return -1; error("Couldn't set MRU: %m"); + ret = -1; } if (fdmuxid >= 0) { if (!sync_serial) { if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { error("Couldn't set receive ACCM: %m"); + ret = -1; } } cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); @@ -1614,8 +1622,10 @@ tty_recv_config(mru, asyncmap, pcomp, accomp) if (any_compressions() && strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC decompression: %m"); + ret = -1; } } + return ret; } /* diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index 26e2ba1..cb1b248 100644 --- a/pppd/sys-sunos4.c +++ b/pppd/sys-sunos4.c @@ -73,7 +73,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: sys-sunos4.c,v 1.30 2002/12/04 23:03:33 paulus Exp $" +#define RCSID "$Id: sys-sunos4.c,v 1.31 2003/03/03 05:11:46 paulus Exp $" #include #include @@ -803,28 +803,33 @@ netif_set_mtu(unit, mtu) * tty_send_config - configure the transmit characteristics of * the ppp interface. */ -void +int tty_send_config(mtu, asyncmap, pcomp, accomp) int mtu; u_int32_t asyncmap; int pcomp, accomp; { int cf[2]; + int ret = 0; link_mtu = mtu; if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) { if (hungup && errno == ENXIO) - return; + return -1; error("Couldn't set MTU: %m"); + ret = -1; } if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { error("Couldn't set transmit ACCM: %m"); + ret = -1; } cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0); cf[1] = COMP_PROT | COMP_AC; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC compression: %m"); + ret = -1; } + return ret; } /* @@ -845,28 +850,33 @@ tty_set_xaccm(unit, accm) * tty_recv_config - configure the receive-side characteristics of * the ppp interface. */ -void +int tty_recv_config(mru, asyncmap, pcomp, accomp) int mru; u_int32_t asyncmap; int pcomp, accomp; { int cf[2]; + int ret = 0; link_mru = mru; if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) { if (hungup && errno == ENXIO) - return; + return -1; error("Couldn't set MRU: %m"); + ret = -1; } if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0) { error("Couldn't set receive ACCM: %m"); + ret = -1; } cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0); cf[1] = DECOMP_PROT | DECOMP_AC; if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) { error("Couldn't set prot/AC decompression: %m"); + ret = -1; } + return ret; } /* diff --git a/pppd/tty.c b/pppd/tty.c index a7ebe6f..9fa0326 100644 --- a/pppd/tty.c +++ b/pppd/tty.c @@ -73,7 +73,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: tty.c,v 1.10 2003/02/24 11:29:53 fcusack Exp $" +#define RCSID "$Id: tty.c,v 1.11 2003/03/03 05:11:46 paulus Exp $" #include #include @@ -108,7 +108,7 @@ int connect_tty __P((void)); void disconnect_tty __P((void)); void tty_close_fds __P((void)); void cleanup_tty __P((void)); -void tty_do_send_config __P((int, u_int32_t, int, int)); +int tty_do_send_config __P((int, u_int32_t, int, int)); static int setdevname __P((char *, char **, int)); static int setspeed __P((char *, char **, int)); @@ -772,14 +772,14 @@ void cleanup_tty() * tty_do_send_config - set transmit-side PPP configuration. * We set the extended transmit ACCM here as well. */ -void +int tty_do_send_config(mtu, accm, pcomp, accomp) int mtu; u_int32_t accm; int pcomp, accomp; { tty_set_xaccm(xmit_accm); - tty_send_config(mtu, accm, pcomp, accomp); + return tty_send_config(mtu, accm, pcomp, accomp); } /* @@ -887,7 +887,7 @@ start_charshunt(ifd, ofd) { int cpid; - cpid = fork(); + cpid = safe_fork(); if (cpid == -1) { error("Can't fork process for character shunt: %m"); return 0; @@ -899,7 +899,6 @@ start_charshunt(ifd, ofd) if (getuid() != uid) fatal("setuid failed"); setgid(getgid()); - sys_close(); if (!nodetach) log_to_fd = -1; charshunt(ifd, ofd, record_file);