X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Foptions.c;h=1844e3efa7ce9ea2ede568ec0e23ff47e46a80bc;hp=9e8158aaf0836aabb22cde749f79631b3210a6a2;hb=52a17b6d41d64d0502a73e5b4224546360581b49;hpb=9b7089a0401b5d0973cace08f1f632d526a06377 diff --git a/pppd/options.c b/pppd/options.c index 9e8158a..1844e3e 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -17,7 +17,7 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#define RCSID "$Id: options.c,v 1.74 2000/04/15 01:27:13 masputra Exp $" +#define RCSID "$Id: options.c,v 1.75 2000/06/30 04:54:21 paulus Exp $" #include #include @@ -70,18 +70,9 @@ int debug = 0; /* Debug flag */ int kdebugflag = 0; /* Tell kernel to print debug messages */ int default_device = 1; /* Using /dev/tty or equivalent */ char devnam[MAXPATHLEN]; /* Device name */ -int crtscts = 0; /* Use hardware flow control */ -bool modem = 1; /* Use modem control lines */ -int inspeed = 0; /* Input/Output speed requested */ u_int32_t netmask = 0; /* IP netmask to set on interface */ -bool lockflag = 0; /* Create lock file to lock the serial dev */ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ -char *initializer = NULL; /* Script to initialize physical link */ -char *connect_script = NULL; /* Script to establish physical link */ -char *disconnect_script = NULL; /* Script to disestablish physical link */ -char *welcomer = NULL; /* Script to run after phys link estab. */ -char *ptycommand = NULL; /* Command to run on other side of pty */ int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ @@ -92,24 +83,17 @@ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ int holdoff = 30; /* # seconds to pause before reconnecting */ bool holdoff_specified; /* true if a holdoff value has been given */ -bool notty = 0; /* Stdin/out is not a tty */ -char *pty_socket = NULL; /* Socket to connect to pty */ -char *record_file = NULL; /* File to record chars sent/received */ -int using_pty = 0; -bool sync_serial = 0; /* Device is synchronous serial device */ int log_to_fd = 1; /* send log messages to this fd too */ int maxfail = 10; /* max # of unsuccessful connection attempts */ char linkname[MAXPATHLEN]; /* logical name for link */ bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ -int max_data_rate; /* max bytes/sec through charshunt */ int req_unit = -1; /* requested interface unit */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ extern option_t auth_options[]; extern struct stat devstat; -extern int prepass; /* Doing pre-pass to find device name */ struct option_info initializer_info; struct option_info connect_script_info; @@ -129,6 +113,7 @@ int privileged_option; /* set iff the current option came from root */ char *option_source; /* string saying where the option came from */ bool log_to_file; /* log_to_fd is a file opened by us */ bool log_to_specific_fd; /* log_to_fd was specified by user option */ +bool no_override; /* don't override previously-set options */ /* * Prototypes @@ -139,7 +124,6 @@ static int setspeed __P((char *)); static int noopt __P((char **)); static int setdomain __P((char **)); static int setnetmask __P((char **)); -static int setxonxoff __P((char **)); static int readfile __P((char **)); static int callfile __P((char **)); static int showversion __P((char **)); @@ -190,55 +174,16 @@ option_t general_options[] = { "Set time in seconds before retrying connection" }, { "idle", o_int, &idle_time_limit, "Set time in seconds before disconnecting idle link" }, - { "lock", o_bool, &lockflag, - "Lock serial device with UUCP-style lock file", 1 }, { "-all", o_special_noarg, (void *)noopt, "Don't request/allow any LCP or IPCP options (useless)" }, - { "init", o_string, &initializer, - "A program to initialize the device", - OPT_A2INFO | OPT_PRIVFIX, &initializer_info }, - { "connect", o_string, &connect_script, - "A program to set up a connection", - OPT_A2INFO | OPT_PRIVFIX, &connect_script_info }, - { "disconnect", o_string, &disconnect_script, - "Program to disconnect serial device", - OPT_A2INFO | OPT_PRIVFIX, &disconnect_script_info }, - { "welcome", o_string, &welcomer, - "Script to welcome client", - OPT_A2INFO | OPT_PRIVFIX, &welcomer_info }, - { "pty", o_string, &ptycommand, - "Script to run on pseudo-tty master side", - OPT_A2INFO | OPT_PRIVFIX | OPT_DEVNAM, &ptycommand_info }, - { "notty", o_bool, ¬ty, - "Input/output is not a tty", OPT_DEVNAM | 1 }, - { "socket", o_string, &pty_socket, - "Send and receive over socket, arg is host:port", OPT_DEVNAM }, - { "record", o_string, &record_file, - "Record characters sent/received to file" }, { "maxconnect", o_int, &maxconnect, "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF }, - { "crtscts", o_int, &crtscts, - "Set hardware (RTS/CTS) flow control", OPT_NOARG|OPT_VAL(1) }, - { "nocrtscts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) }, - { "-crtscts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) }, - { "cdtrcts", o_int, &crtscts, - "Set alternate hardware (DTR/CTS) flow control", OPT_NOARG|OPT_VAL(2) }, - { "nocdtrcts", o_int, &crtscts, - "Disable hardware flow control", OPT_NOARG|OPT_VAL(-1) }, - { "xonxoff", o_special_noarg, (void *)setxonxoff, - "Set software (XON/XOFF) flow control" }, { "domain", o_special, (void *)setdomain, "Add given domain name to hostname" }, { "mtu", o_int, &lcp_allowoptions[0].mru, "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, { "netmask", o_special, (void *)setnetmask, "set netmask" }, - { "modem", o_bool, &modem, - "Use modem control lines", 1 }, - { "local", o_bool, &modem, - "Don't use modem control lines" }, { "file", o_special, (void *)readfile, "Take options from a file", OPT_PREPASS }, { "call", o_special, (void *)callfile, @@ -255,8 +200,6 @@ option_t general_options[] = { "Show brief listing of options" }, { "-h", o_special_noarg, (void *)showhelp, "Show brief listing of options" }, - { "sync", o_bool, &sync_serial, - "Use synchronous HDLC serial encoding", 1 }, { "logfd", o_int, &log_to_fd, "Send log messages to this file descriptor", 0, &log_to_specific_fd }, @@ -279,8 +222,6 @@ option_t general_options[] = { "Don't alter kernel settings", 0 }, { "connect-delay", o_int, &connect_delay, "Maximum time (in ms) to wait after connect script finishes" }, - { "datarate", o_int, &max_data_rate, - "Maximum data rate in bytes/sec (with pty, notty or record option)" }, { "unit", o_int, &req_unit, "PPP interface unit number to use if possible", OPT_LLIMIT, 0, 0 }, #ifdef HAVE_MULTILINK @@ -336,8 +277,6 @@ See pppd(8) for more options.\n\ /* * parse_args - parse a string of arguments from the command line. - * If prepass is true, we are scanning for the device name and only - * processing a few options, so error messages are suppressed. */ int parse_args(argc, argv) @@ -377,8 +316,7 @@ parse_args(argc, argv) */ if ((ret = setdevname(arg)) == 0 && (ret = setspeed(arg)) == 0 - && (ret = setipaddr(arg)) == 0 - && !prepass) { + && (ret = setipaddr(arg)) == 0) { option_error("unrecognized option '%s'", arg); usage(); return 0; @@ -452,9 +390,12 @@ options_from_file(filename, must_exist, check_prot, priv) if (check_prot) seteuid(0); if (f == NULL) { - if (!must_exist && err == ENOENT) - return 1; errno = err; + if (!must_exist) { + if (err != ENOENT && err != ENOTDIR) + warn("Warning: can't open options file %s: %m", filename); + return 1; + } option_error("Can't open options file %s: %m", filename); return 0; } @@ -483,7 +424,7 @@ options_from_file(filename, must_exist, check_prot, priv) argv[i] = args[i]; } current_option = cmd; - if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) { + if ((opt->flags & OPT_DEVEQUIV) && no_override) { option_error("the %s option may not be used in the %s file", cmd, filename); goto err; @@ -544,6 +485,9 @@ options_from_user() /* * options_for_tty - See if an options file exists for the serial * device, and if so, interpret options from it. + * We only allow the per-tty options file to override anything from + * the command line if it is something that the user can't override + * once it has been set by root. */ int options_for_tty() @@ -566,7 +510,9 @@ options_for_tty() for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p) if (*p == '/') *p = '.'; + no_override = 1; ret = options_from_file(path, 0, 0, 1); + no_override = 0; free(path); return ret; } @@ -673,8 +619,14 @@ process_option(opt, argv) char *sv; int (*parser) __P((char **)); - if ((opt->flags & OPT_PREPASS) == 0 && prepass) - return 1; + if (no_override && (opt->flags & OPT_SEENIT)) { + struct option_info *ip = (struct option_info *) opt->addr2; + if (!(privileged && (opt->flags & OPT_PRIVFIX))) + return 1; + if (!ip || ip->priv) + return 1; + warn("%s option from per-tty file overrides command line", opt->name); + } if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) { option_error("it's too late to use the %s option", opt->name); return 0; @@ -694,6 +646,7 @@ process_option(opt, argv) return 0; } } + opt->flags |= OPT_SEENIT; switch (opt->type) { case o_bool: @@ -877,10 +830,6 @@ option_error __V((char *fmt, ...)) va_start(args); fmt = va_arg(args, char *); #endif - if (prepass) { - va_end(args); - return; - } vslprintf(buf, sizeof(buf), fmt, args); va_end(args); if (phase == PHASE_INITIALIZE) @@ -1350,12 +1299,13 @@ setspeed(arg) char *ptr; int spd; - if (prepass) + if (no_override && inspeed != 0) return 1; spd = strtol(arg, &ptr, 0); if (ptr == arg || *ptr != 0 || spd == 0) return 0; - inspeed = spd; + if (!no_override || inspeed == 0) + inspeed = spd; return 1; } @@ -1396,7 +1346,8 @@ setdevname(cp) if (phase != PHASE_INITIALIZE) { option_error("device name cannot be changed after initialization"); return -1; - } else if (devnam_fixed) { + } + if (no_override) { option_error("per-tty options file may not specify device name"); return -1; } @@ -1427,19 +1378,18 @@ setipaddr(arg) char *colon; u_int32_t local, remote; ipcp_options *wo = &ipcp_wantoptions[0]; - + static int seen_local = 0, seen_remote = 0; + /* * IP address pair separated by ":". */ if ((colon = strchr(arg, ':')) == NULL) return 0; - if (prepass) - return 1; /* * If colon first character, then no local addr. */ - if (colon != arg) { + if (colon != arg && !(no_override && seen_local)) { *colon = '\0'; if ((local = inet_addr(arg)) == (u_int32_t) -1) { if ((hp = gethostbyname(arg)) == NULL) { @@ -1456,12 +1406,13 @@ setipaddr(arg) if (local != 0) wo->ouraddr = local; *colon = ':'; + seen_local = 1; } /* * If colon last character, then no remote addr. */ - if (*++colon != '\0') { + if (*++colon != '\0' && !(no_override && seen_remote)) { if ((remote = inet_addr(colon)) == (u_int32_t) -1) { if ((hp = gethostbyname(colon)) == NULL) { option_error("unknown host: %s", colon); @@ -1478,6 +1429,7 @@ setipaddr(arg) } if (remote != 0) wo->hisaddr = remote; + seen_remote = 1; } return 1; @@ -1546,17 +1498,6 @@ parse_dotted_ip(p, vp) return p - p0; } -static int -setxonxoff(argv) - char **argv; -{ - lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ - lcp_wantoptions[0].neg_asyncmap = 1; - - crtscts = -2; - return (1); -} - static int setlogfile(argv) char **argv;