X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fmain.c;h=6ec72b44a7a550dc6994fb8edeae60c5d655c26d;hp=c580f7c6e23d618e0ff7544b2083a25d5c3683d4;hb=728fd83b1728a00b690379006da00a966da1c4fe;hpb=a3396b002507d72b3e1f1169bd02ae018539654b diff --git a/pppd/main.c b/pppd/main.c index c580f7c..6ec72b4 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -18,10 +18,11 @@ */ #ifndef lint -static char rcsid[] = "$Id: main.c,v 1.19 1994/09/21 06:47:37 paulus Exp $"; +static char rcsid[] = "$Id: main.c,v 1.24 1995/06/12 11:22:49 paulus Exp $"; #endif #include +#include #include #include #include @@ -64,14 +65,13 @@ int ifunit; /* Interface unit number */ char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ -static char pidfilename[MAXPATHLEN]; - +static char pidfilename[MAXPATHLEN]; /* name of pid file */ +static char default_devnam[MAXPATHLEN]; /* name of default device */ static pid_t pid; /* Our pid */ static pid_t pgrpid; /* Process Group ID */ static uid_t uid; /* Our real user-id */ int fd = -1; /* Device file descriptor */ -int s; /* Socket file descriptor */ int phase; /* where the link is at */ int kill_link; @@ -112,6 +112,11 @@ void pr_log __P((void *, char *, ...)); extern char *ttyname __P((int)); extern char *getlogin __P((void)); +#ifdef ultrix +#undef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + /* * PPP Data Link Layer "protocol" table. * One entry per supported protocol. @@ -155,6 +160,7 @@ main(argc, argv) p = ttyname(0); if (p) strcpy(devnam, p); + strcpy(default_devnam, devnam); if (gethostname(hostname, MAXNAMELEN) < 0 ) { perror("couldn't get hostname"); @@ -187,6 +193,13 @@ main(argc, argv) check_auth_options(); setipdefault(); + /* + * If the user has specified the default device name explicitly, + * pretend they hadn't. + */ + if (!default_device && strcmp(devnam, default_devnam) == 0) + default_device = 1; + /* * Initialize system-dependent stuff and magic number package. */ @@ -212,12 +225,6 @@ main(argc, argv) } syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d", VERSION, PATCHLEVEL, p, uid); - - /* Get an internet socket for doing socket ioctl's on. */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "Couldn't create IP socket: %m"); - die(1); - } /* * Compute mask of all interesting signals and install signal handlers @@ -299,10 +306,10 @@ main(argc, argv) die(1); } - syslog(LOG_INFO, "Connected..."); + syslog(LOG_INFO, "Serial connection established."); sleep(1); /* give it time to set up its terminal */ } - + /* set line speed, flow control, etc.; clear CLOCAL if modem option */ set_up_tty(fd, 0); @@ -356,15 +363,20 @@ main(argc, argv) } /* - * Run disconnector script, if requested + * Run disconnector script, if requested. + * First we need to reset non-blocking mode. + * XXX we may not be able to do this if the line has hung up! */ + if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) >= 0) + initfdflags = -1; + disestablish_ppp(); if (disconnector) { + set_up_tty(fd, 1); if (device_script(disconnector, fd, fd) < 0) { syslog(LOG_WARNING, "disconnect script failed"); - die(1); + } else { + syslog(LOG_INFO, "Serial link disconnected."); } - - syslog(LOG_INFO, "Disconnected..."); } close_fd(); @@ -374,10 +386,7 @@ main(argc, argv) } while (persist); - if (lockflag && !default_device) - unlock(); - - exit(0); + die(0); } @@ -391,62 +400,59 @@ get_input() u_char *p; u_short protocol; - for (;;) { /* Read all available packets */ - p = inpacket_buf; /* point to beginning of packet buffer */ + p = inpacket_buf; /* point to beginning of packet buffer */ - len = read_packet(inpacket_buf); - if (len < 0) - return; + len = read_packet(inpacket_buf); + if (len < 0) + return; - if (len == 0) { - MAINDEBUG((LOG_DEBUG, "End of file on fd!")); - hungup = 1; - lcp_lowerdown(0); /* serial link is no longer available */ - phase = PHASE_DEAD; - return; - } + if (len == 0) { + syslog(LOG_NOTICE, "Modem hangup"); + hungup = 1; + lcp_lowerdown(0); /* serial link is no longer available */ + phase = PHASE_DEAD; + return; + } - if (debug /*&& (debugflags & DBG_INPACKET)*/) - log_packet(p, len, "rcvd "); + if (debug /*&& (debugflags & DBG_INPACKET)*/) + log_packet(p, len, "rcvd "); - if (len < PPP_HDRLEN) { - MAINDEBUG((LOG_INFO, "io(): Received short packet.")); - return; - } + if (len < PPP_HDRLEN) { + MAINDEBUG((LOG_INFO, "io(): Received short packet.")); + return; + } - p += 2; /* Skip address and control */ - GETSHORT(protocol, p); - len -= PPP_HDRLEN; + p += 2; /* Skip address and control */ + GETSHORT(protocol, p); + len -= PPP_HDRLEN; - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { - MAINDEBUG((LOG_INFO, - "io(): Received non-LCP packet when LCP not open.")); + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) { + MAINDEBUG((LOG_INFO, + "io(): Received non-LCP packet when LCP not open.")); + return; + } + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) { + if (prottbl[i].protocol == protocol) { + (*prottbl[i].input)(0, p, len); return; } - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++) - if (prottbl[i].protocol == protocol) { - (*prottbl[i].input)(0, p, len); - break; - } else if (protocol == (prottbl[i].protocol & ~0x8000) - && prottbl[i].datainput != NULL) { - (*prottbl[i].datainput)(0, p, len); - break; - } - - if (i == sizeof (prottbl) / sizeof (struct protent)) { - if (debug) - syslog(LOG_WARNING, "Unknown protocol (0x%x) received", - protocol); - lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); + if (protocol == (prottbl[i].protocol & ~0x8000) + && prottbl[i].datainput != NULL) { + (*prottbl[i].datainput)(0, p, len); + return; } } + + if (debug) + syslog(LOG_WARNING, "Unknown protocol (0x%x) received", protocol); + lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } @@ -522,6 +528,8 @@ cleanup(status, arg) void close_fd() { + disestablish_ppp(); + /* drop dtr to hang up */ if (modem) setdtr(fd, FALSE); @@ -530,8 +538,6 @@ close_fd() syslog(LOG_WARNING, "Couldn't restore device fd flags: %m"); initfdflags = -1; - disestablish_ppp(); - restore_tty(); close(fd); @@ -563,8 +569,8 @@ timeout(func, arg, time) { struct callout *newp, *p, **pp; - MAINDEBUG((LOG_DEBUG, "Timeout %x:%x in %d seconds.", - (int) func, (int) arg, time)); + MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.", + (long) func, (long) arg, time)); /* * Allocate timeout. @@ -583,9 +589,9 @@ timeout(func, arg, time) * Find correct place and link it in. */ for (pp = &callout; (p = *pp); pp = &p->c_next) - if (p->c_time.tv_sec < newp->c_time.tv_sec - || (p->c_time.tv_sec == newp->c_time.tv_sec - && p->c_time.tv_usec <= newp->c_time.tv_sec)) + if (newp->c_time.tv_sec < p->c_time.tv_sec + || (newp->c_time.tv_sec == p->c_time.tv_sec + && newp->c_time.tv_usec < p->c_time.tv_sec)) break; newp->c_next = p; *pp = newp; @@ -604,7 +610,7 @@ untimeout(func, arg) struct callout **copp, *freep; int reschedule = 0; - MAINDEBUG((LOG_DEBUG, "Untimeout %x:%x.", (int) func, (int) arg)); + MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg)); /* * Find first matching timeout and remove it from the list. @@ -754,12 +760,7 @@ device_script(program, in, out) { int pid; int status; - sigset_t mask; - - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGHUP); - sigprocmask(SIG_BLOCK, &mask, &mask); + int errfd; pid = fork(); @@ -769,11 +770,13 @@ device_script(program, in, out) } if (pid == 0) { - setreuid(getuid(), getuid()); - setregid(getgid(), getgid()); - sigprocmask(SIG_SETMASK, &mask, NULL); dup2(in, 0); dup2(out, 1); + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (errfd >= 0) + dup2(errfd, 2); + setuid(getuid()); + setgid(getgid()); execl("/bin/sh", "sh", "-c", program, (char *)0); syslog(LOG_ERR, "could not exec /bin/sh: %m"); _exit(99); @@ -786,7 +789,6 @@ device_script(program, in, out) syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); die(1); } - sigprocmask(SIG_SETMASK, &mask, NULL); return (status == 0 ? 0 : -1); } @@ -805,6 +807,7 @@ run_program(prog, args, must_exist) int must_exist; { int pid; + char *nullenv[1]; pid = fork(); if (pid == -1) { @@ -812,20 +815,22 @@ run_program(prog, args, must_exist) return -1; } if (pid == 0) { - int new_fd; + int new_fd; /* Leave the current location */ (void) setsid(); /* No controlling tty. */ - (void) umask (0); /* no umask. Must change in script. */ + (void) umask (S_IRWXG|S_IRWXO); (void) chdir ("/"); /* no current directory. */ + setuid(geteuid()); + setgid(getegid()); /* Ensure that nothing of our device environment is inherited. */ close (0); close (1); close (2); - close (s); /* Socket interface to the ppp device */ close (fd); /* tty interface to the ppp device */ - + /* XXX should call sysdep cleanup procedure here */ + /* Don't pass handles to the PPP device, even by accident. */ new_fd = open (_PATH_DEVNULL, O_RDWR); if (new_fd >= 0) { @@ -837,14 +842,17 @@ run_program(prog, args, must_exist) dup2 (0, 2); /* stderr -> /dev/null */ } +#ifdef BSD /* Force the priority back to zero if pppd is running higher. */ if (setpriority (PRIO_PROCESS, 0, 0) < 0) syslog (LOG_WARNING, "can't reset priority to 0: %m"); +#endif /* SysV recommends a second fork at this point. */ - /* run the program */ - execv(prog, args); + /* run the program; give it a null environment */ + nullenv[0] = NULL; + execve(prog, args, nullenv); if (must_exist || errno != ENOENT) syslog(LOG_WARNING, "Can't execute %s: %m", prog); _exit(-1);