X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Foptions.c;h=e92fb20c5b0d966ab6a3c13c64bd03eddfc6c1cd;hb=13e277c831dfdd5cecab41e534e78fcbf5393d6e;hp=b7e517a1272a93829d55bd115acf277f43e489c8;hpb=b71ef4d88a7cc850d171d2f6ed172ef9044ac1b9;p=ppp.git diff --git a/pppd/options.c b/pppd/options.c index b7e517a..e92fb20 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.6 1994/05/01 11:45:53 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.8 1994/05/24 11:24:32 paulus Exp $"; #endif #include @@ -29,8 +29,10 @@ static char rcsid[] = "$Id: options.c,v 1.6 1994/05/01 11:45:53 paulus Exp $"; #include #include #include +#include #include #include +#include #include "ppp.h" #include "pppd.h" @@ -49,6 +51,10 @@ static char rcsid[] = "$Id: options.c,v 1.6 1994/05/01 11:45:53 paulus Exp $"; char *strdup __ARGS((char *)); #endif +#ifndef GIDSET_TYPE +#define GIDSET_TYPE int +#endif + /* * Prototypes */ @@ -79,6 +85,7 @@ static int setdisconnector __ARGS((char **)); static int setdomain __ARGS((char **)); static int setnetmask __ARGS((char **)); static int setcrtscts __ARGS((void)); +static int setxonxoff __ARGS((void)); static int setnodetach __ARGS((void)); static int setmodem __ARGS((void)); static int setlocal __ARGS((void)); @@ -109,9 +116,12 @@ static int setchapchal __ARGS((char **)); static int setchapintv __ARGS((char **)); static int setipcpaccl __ARGS((void)); static int setipcpaccr __ARGS((void)); +static int setlcpechointerval __ARGS((char **)); +static int setlcpechofails __ARGS((char **)); +static int setslots __ARGS((char **)); static int number_option __ARGS((char *, long *, int)); - +static int readable __ARGS((int fd)); /* * Option variables @@ -136,6 +146,9 @@ extern int auth_required; extern int proxyarp; extern int persist; extern int uselogin; +extern int nslots; +extern u_long lcp_echo_interval; +extern u_long lcp_echo_fails; extern char our_name[]; extern char remote_name[]; int usehostname; @@ -171,6 +184,8 @@ static struct cmd { "connect", 1, setconnector, /* A program to set up a connection */ "disconnect", 1, setdisconnector, /* program to disconnect serial dev. */ "crtscts", 0, setcrtscts, /* set h/w flow control */ + "xonxoff", 0, setxonxoff, /* set s/w flow control */ + "-crtscts", 0, setxonxoff, /* another name for xonxoff */ "debug", 0, setdebug, /* Increase debugging level */ "kdebug", 1, setkdebug, /* Enable kernel-level debugging */ "domain", 1, setdomain, /* Add given domain name to hostname*/ @@ -193,6 +208,8 @@ static struct cmd { "persist", 0, setpersist, /* Keep on reopening connection after close */ "login", 0, setdologin, /* Use system password database for UPAP */ "noipdefault", 0, setnoipdflt, /* Don't use name for default IP adrs */ + "lcp-echo-failure", 1, setlcpechofails, /* consecutive echo failures */ + "lcp-echo-interval", 1, setlcpechointerval, /* time for lcp echo events */ "lcp-restart", 1, setlcptimeout, /* Set timeout for LCP */ "lcp-max-terminate", 1, setlcpterm, /* Set max #xmits for term-reqs */ "lcp-max-configure", 1, setlcpconf, /* Set max #xmits for conf-reqs */ @@ -201,6 +218,7 @@ static struct cmd { "ipcp-max-terminate", 1, setipcpterm, /* Set max #xmits for term-reqs */ "ipcp-max-configure", 1, setipcpconf, /* Set max #xmits for conf-reqs */ "ipcp-max-failure", 1, setipcpfails, /* Set max #conf-naks for IPCP */ + "ipcp-max-slots", 1, setslots, /* Set maximum vj header slots */ "pap-restart", 1, setpaptimeout, /* Set timeout for UPAP */ "pap-max-authreq", 1, setpapreqs, /* Set max #xmits for auth-reqs */ "chap-restart", 1, setchaptimeout, /* Set timeout for CHAP */ @@ -212,8 +230,12 @@ static struct cmd { }; +#ifndef IMPLEMENTATION +#define IMPLEMENTATION "" +#endif + static char *usage_string = "\ -pppd version %s patch level %d\n\ +pppd version %s patch level %d%s\n\ Usage: %s [ arguments ], where arguments are:\n\ Communicate over the named device\n\ Set the baud rate to \n\ @@ -243,6 +265,7 @@ parse_args(argc, argv) { char *arg, *val; struct cmd *cmdp; + int ret; while (argc > 0) { arg = *argv++; @@ -269,11 +292,15 @@ parse_args(argc, argv) /* * Maybe a tty name, speed or IP address? */ - if (!setdevname(arg) && !setspeed(arg) && !setipaddr(arg)) { + if ((ret = setdevname(arg)) == 0 + && (ret = setspeed(arg)) == 0 + && (ret = setipaddr(arg)) == 0) { fprintf(stderr, "%s: unrecognized command\n", arg); usage(); return 0; } + if (ret < 0) /* error */ + return 0; } } return 1; @@ -284,7 +311,8 @@ parse_args(argc, argv) */ usage() { - fprintf(stderr, usage_string, VERSION, PATCHLEVEL, progname); + fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, + progname); } /* @@ -292,12 +320,13 @@ usage() * and interpret them. */ int -options_from_file(filename, must_exist) +options_from_file(filename, must_exist, check_prot) char *filename; int must_exist; + int check_prot; { FILE *f; - int i, newline; + int i, newline, ret; struct cmd *cmdp; char *argv[MAXARGS]; char args[MAXARGS][MAXWORDLEN]; @@ -309,6 +338,12 @@ options_from_file(filename, must_exist) perror(filename); return 0; } + if (check_prot && !readable(fileno(f))) { + fprintf(stderr, "%s: access denied\n", filename); + fclose(f); + return 0; + } + while (getword(f, cmd, &newline, filename)) { /* * First see if it's a command. @@ -337,12 +372,16 @@ options_from_file(filename, must_exist) /* * Maybe a tty name, speed or IP address? */ - if (!setdevname(cmd) && !setspeed(cmd) && !setipaddr(cmd)) { + if ((ret = setdevname(cmd)) == 0 + && (ret = setspeed(cmd)) == 0 + && (ret = setipaddr(cmd)) == 0) { fprintf(stderr, "In file %s: unrecognized command %s\n", filename, cmd); fclose(f); return 0; } + if (ret < 0) /* error */ + return 0; } } return 1; @@ -357,20 +396,78 @@ options_from_user() { char *user, *path, *file; int ret; + struct passwd *pw; - if ((user = getenv("HOME")) == NULL) - return; - file = "/.ppprc"; - path = malloc(strlen(user) + strlen(file) + 1); + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) + return 1; + file = _PATH_USEROPT; + path = malloc(strlen(user) + strlen(file) + 2); if (path == NULL) novm("init file name"); strcpy(path, user); + strcat(path, "/"); strcat(path, file); - ret = options_from_file(path, 0); + ret = options_from_file(path, 0, 1); free(path); return ret; } +/* + * options_for_tty - See if an options file exists for the serial + * device, and if so, interpret options from it. + */ +int +options_for_tty() +{ + char *dev, *path; + int ret; + + dev = strrchr(devname, '/'); + if (dev == NULL) + dev = devname; + else + ++dev; + if (strcmp(dev, "tty") == 0) + return 1; /* don't look for /etc/ppp/options.tty */ + path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1); + if (path == NULL) + novm("tty init file name"); + strcpy(path, _PATH_TTYOPT); + strcat(path, dev); + ret = options_from_file(path, 0, 0); + free(path); + return ret; +} + +/* + * readable - check if a file is readable by the real user. + */ +static int +readable(fd) + int fd; +{ + uid_t uid; + int ngroups, i; + struct stat sbuf; + GIDSET_TYPE groups[NGROUPS_MAX]; + + uid = getuid(); + if (uid == 0) + return 1; + if (fstat(fd, &sbuf) != 0) + return 0; + if (sbuf.st_uid == uid) + return sbuf.st_mode & S_IRUSR; + if (sbuf.st_gid == getgid()) + return sbuf.st_mode & S_IRGRP; + ngroups = getgroups(NGROUPS_MAX, groups); + for (i = 0; i < ngroups; ++i) + if (sbuf.st_gid == groups[i]) + return sbuf.st_mode & S_IRGRP; + return sbuf.st_mode & S_IROTH; +} + /* * Read a word from a file. * Words are delimited by white-space or by quotes ("). @@ -527,7 +624,7 @@ static int readfile(argv) char **argv; { - return options_from_file(*argv, 1); + return options_from_file(*argv, 1, 1); } /* @@ -923,16 +1020,16 @@ setdevname(cp) */ if (stat(cp, &statbuf) < 0) { if (errno == ENOENT) - return (0); + return 0; syslog(LOG_ERR, cp); - return 0; + return -1; } (void) strncpy(devname, cp, MAXPATHLEN); devname[MAXPATHLEN-1] = 0; default_device = FALSE; - return (1); + return 1; } @@ -952,7 +1049,7 @@ setipaddr(arg) * IP address pair separated by ":". */ if ((colon = index(arg, ':')) == NULL) - return (0); + return 0; /* * If colon first character, then no local addr. @@ -961,8 +1058,8 @@ setipaddr(arg) *colon = '\0'; if ((local = inet_addr(arg)) == -1) { if ((hp = gethostbyname(arg)) == NULL) { - fprintf(stderr, "unknown host: %s", arg); - local = 0; + fprintf(stderr, "unknown host: %s\n", arg); + return -1; } else { local = *(long *)hp->h_addr; if (our_name[0] == 0) { @@ -971,6 +1068,10 @@ setipaddr(arg) } } } + if (bad_ip_adrs(local)) { + fprintf(stderr, "bad local IP address %s\n", ip_ntoa(local)); + return -1; + } if (local != 0) wo->ouraddr = local; *colon = ':'; @@ -982,8 +1083,8 @@ setipaddr(arg) if (*++colon != '\0') { if ((remote = inet_addr(colon)) == -1) { if ((hp = gethostbyname(colon)) == NULL) { - fprintf(stderr, "unknown host: %s", colon); - remote = 0; + fprintf(stderr, "unknown host: %s\n", colon); + return -1; } else { remote = *(long *)hp->h_addr; if (remote_name[0] == 0) { @@ -992,11 +1093,15 @@ setipaddr(arg) } } } + if (bad_ip_adrs(remote)) { + fprintf(stderr, "bad remote IP address %s\n", ip_ntoa(remote)); + return -1; + } if (remote != 0) wo->hisaddr = remote; } - return (1); + return 1; } @@ -1058,7 +1163,7 @@ setipdefault() if ((hp = gethostbyname(hostname)) == NULL) return; local = *(long *)hp->h_addr; - if (local != 0) + if (local != 0 && !bad_ip_adrs(local)) wo->ouraddr = local; } @@ -1071,8 +1176,8 @@ setnetmask(argv) char **argv; { u_long mask; - - if ((mask = inet_addr(*argv)) == -1) { + + if ((mask = inet_addr(*argv)) == -1 || (netmask & ~mask) != 0) { fprintf(stderr, "Invalid netmask %s\n", *argv); return 0; } @@ -1101,6 +1206,13 @@ setcrtscts() return (1); } +static int +setxonxoff() +{ + crtscts = 2; + return (1); +} + static int setnodetach() { @@ -1200,6 +1312,22 @@ setdologin() return 1; } +/* + * Functions to set the echo interval for modem-less monitors + */ + +static int setlcpechointerval(argv) + char **argv; +{ + return int_option(*argv, &lcp_echo_interval, 0); +} + +static int setlcpechofails(argv) + char **argv; +{ + return int_option(*argv, &lcp_echo_fails, 0); +} + /* * Functions to set timeouts, max transmits, etc. */ @@ -1281,3 +1409,16 @@ static int setchapintv(argv) { return int_option(*argv, &chap[0].chal_interval, 0); } + +static int setslots(argv) + char **argv; +{ + int value; + int answer = int_option(*argv, &value, 0); + + if (answer == 1 && value > 1 && value < 17) { + ipcp_wantoptions [0].maxslotindex = + ipcp_allowoptions[0].maxslotindex = value - 1; + } + return answer; +}