xref: /freebsd/usr.sbin/ppp/systems.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
165309e5cSBrian Somers /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
465309e5cSBrian Somers  * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
565309e5cSBrian Somers  *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
665309e5cSBrian Somers  *                           Internet Initiative Japan, Inc (IIJ)
765309e5cSBrian Somers  * All rights reserved.
8af57ed9fSAtsushi Murai  *
965309e5cSBrian Somers  * Redistribution and use in source and binary forms, with or without
1065309e5cSBrian Somers  * modification, are permitted provided that the following conditions
1165309e5cSBrian Somers  * are met:
1265309e5cSBrian Somers  * 1. Redistributions of source code must retain the above copyright
1365309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer.
1465309e5cSBrian Somers  * 2. Redistributions in binary form must reproduce the above copyright
1565309e5cSBrian Somers  *    notice, this list of conditions and the following disclaimer in the
1665309e5cSBrian Somers  *    documentation and/or other materials provided with the distribution.
17af57ed9fSAtsushi Murai  *
1865309e5cSBrian Somers  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1965309e5cSBrian Somers  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2065309e5cSBrian Somers  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2165309e5cSBrian Somers  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2265309e5cSBrian Somers  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2365309e5cSBrian Somers  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2465309e5cSBrian Somers  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2565309e5cSBrian Somers  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2665309e5cSBrian Somers  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2765309e5cSBrian Somers  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2865309e5cSBrian Somers  * SUCH DAMAGE.
29af57ed9fSAtsushi Murai  */
3065309e5cSBrian Somers 
3175240ed1SBrian Somers #include <sys/param.h>
3275240ed1SBrian Somers 
33da2a8b4dSBrian Somers #include <ctype.h>
34da2a8b4dSBrian Somers #include <pwd.h>
3575240ed1SBrian Somers #include <stdio.h>
3675240ed1SBrian Somers #include <stdlib.h>
3775240ed1SBrian Somers #include <string.h>
385d9e6103SBrian Somers #include <termios.h>
3975240ed1SBrian Somers 
40c9e11a11SBrian Somers #include "defs.h"
41b6e82f33SBrian Somers #include "command.h"
4275240ed1SBrian Somers #include "log.h"
435106c671SBrian Somers #include "id.h"
4475240ed1SBrian Somers #include "systems.h"
45af57ed9fSAtsushi Murai 
46da2a8b4dSBrian Somers #define issep(ch) ((ch) == ' ' || (ch) == '\t')
47da2a8b4dSBrian Somers 
48af57ed9fSAtsushi Murai FILE *
OpenSecret(const char * file)49b6e82f33SBrian Somers OpenSecret(const char *file)
50af57ed9fSAtsushi Murai {
51af57ed9fSAtsushi Murai   FILE *fp;
52af57ed9fSAtsushi Murai   char line[100];
53af57ed9fSAtsushi Murai 
547a66a36dSBrian Somers   snprintf(line, sizeof line, "%s/%s", PPP_CONFDIR, file);
555106c671SBrian Somers   fp = ID0fopen(line, "r");
565106c671SBrian Somers   if (fp == NULL)
57dd7e2610SBrian Somers     log_Printf(LogWARN, "OpenSecret: Can't open %s.\n", line);
58af57ed9fSAtsushi Murai   return (fp);
59af57ed9fSAtsushi Murai }
60af57ed9fSAtsushi Murai 
61af57ed9fSAtsushi Murai void
CloseSecret(FILE * fp)62944f7098SBrian Somers CloseSecret(FILE *fp)
63af57ed9fSAtsushi Murai {
64af57ed9fSAtsushi Murai   fclose(fp);
65af57ed9fSAtsushi Murai }
66af57ed9fSAtsushi Murai 
67da2a8b4dSBrian Somers /* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */
682a30e2acSBrian Somers const char *
InterpretArg(const char * from,char * to)699409953dSBrian Somers InterpretArg(const char *from, char *to)
70da2a8b4dSBrian Somers {
71da2a8b4dSBrian Somers   char *ptr, *startto, *endto;
722a30e2acSBrian Somers   struct passwd *pwd;
73057f1760SBrian Somers   int instring;
74057f1760SBrian Somers   size_t len;
752a30e2acSBrian Somers   const char *env;
76da2a8b4dSBrian Somers 
772a30e2acSBrian Somers   instring = 0;
78da2a8b4dSBrian Somers   startto = to;
79da2a8b4dSBrian Somers   endto = to + LINE_LEN - 1;
80da2a8b4dSBrian Somers 
81da2a8b4dSBrian Somers   while(issep(*from))
82da2a8b4dSBrian Somers     from++;
839409953dSBrian Somers 
842a30e2acSBrian Somers   while (*from != '\0') {
852a30e2acSBrian Somers     switch (*from) {
862a30e2acSBrian Somers       case '"':
872a30e2acSBrian Somers         instring = !instring;
882a30e2acSBrian Somers         *to++ = *from++;
892a30e2acSBrian Somers         break;
902a30e2acSBrian Somers       case '\\':
912a30e2acSBrian Somers         switch (*++from) {
922a30e2acSBrian Somers           case '$':
932a30e2acSBrian Somers           case '~':
942a30e2acSBrian Somers             break;		/* Swallow the escapes */
95687d9f57SBrian Somers 
962a30e2acSBrian Somers           default:
972a30e2acSBrian Somers             *to++ = '\\';	/* Pass the escapes on, maybe skipping \# */
982a30e2acSBrian Somers             break;
99da2a8b4dSBrian Somers         }
1002a30e2acSBrian Somers         *to++ = *from++;
1012a30e2acSBrian Somers         break;
1022a30e2acSBrian Somers       case '$':
103da2a8b4dSBrian Somers         if (from[1] == '$') {
104da2a8b4dSBrian Somers           *to = '\0';	/* For an empty var name below */
105da2a8b4dSBrian Somers           from += 2;
106da2a8b4dSBrian Somers         } else if (from[1] == '{') {
107da2a8b4dSBrian Somers           ptr = strchr(from+2, '}');
108da2a8b4dSBrian Somers           if (ptr) {
109da2a8b4dSBrian Somers             len = ptr - from - 2;
110057f1760SBrian Somers             if (endto - to < (int)len )
111da2a8b4dSBrian Somers               len = endto - to;
112da2a8b4dSBrian Somers             if (len) {
113da2a8b4dSBrian Somers               strncpy(to, from+2, len);
114da2a8b4dSBrian Somers               to[len] = '\0';
115da2a8b4dSBrian Somers               from = ptr+1;
116da2a8b4dSBrian Somers             } else {
117da2a8b4dSBrian Somers               *to++ = *from++;
118da2a8b4dSBrian Somers               continue;
119da2a8b4dSBrian Somers             }
120da2a8b4dSBrian Somers           } else {
121da2a8b4dSBrian Somers             *to++ = *from++;
122da2a8b4dSBrian Somers             continue;
123da2a8b4dSBrian Somers           }
124da2a8b4dSBrian Somers         } else {
125da2a8b4dSBrian Somers           ptr = to;
126da2a8b4dSBrian Somers           for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++)
127da2a8b4dSBrian Somers             *ptr++ = *from;
128da2a8b4dSBrian Somers           *ptr = '\0';
129da2a8b4dSBrian Somers         }
130da2a8b4dSBrian Somers         if (*to == '\0')
131da2a8b4dSBrian Somers           *to++ = '$';
132da2a8b4dSBrian Somers         else if ((env = getenv(to)) != NULL) {
133da2a8b4dSBrian Somers           strncpy(to, env, endto - to);
134da2a8b4dSBrian Somers           *endto = '\0';
135da2a8b4dSBrian Somers           to += strlen(to);
136da2a8b4dSBrian Somers         }
1372a30e2acSBrian Somers         break;
1382a30e2acSBrian Somers 
1392a30e2acSBrian Somers       case '~':
1402a30e2acSBrian Somers         ptr = strchr(++from, '/');
141057f1760SBrian Somers         len = ptr ? (size_t)(ptr - from) : strlen(from);
1422a30e2acSBrian Somers         if (len == 0)
1432a30e2acSBrian Somers           pwd = getpwuid(ID0realuid());
1442a30e2acSBrian Somers         else {
1452a30e2acSBrian Somers           strncpy(to, from, len);
1462a30e2acSBrian Somers           to[len] = '\0';
1472a30e2acSBrian Somers           pwd = getpwnam(to);
1482a30e2acSBrian Somers         }
1492a30e2acSBrian Somers         if (pwd == NULL)
1502a30e2acSBrian Somers           *to++ = '~';
1512a30e2acSBrian Somers         else {
1522a30e2acSBrian Somers           strncpy(to, pwd->pw_dir, endto - to);
1532a30e2acSBrian Somers           *endto = '\0';
1542a30e2acSBrian Somers           to += strlen(to);
1552a30e2acSBrian Somers           from += len;
1562a30e2acSBrian Somers         }
1572a30e2acSBrian Somers         endpwent();
1582a30e2acSBrian Somers         break;
1592a30e2acSBrian Somers 
1602a30e2acSBrian Somers       default:
1612a30e2acSBrian Somers         *to++ = *from++;
1622a30e2acSBrian Somers         break;
163da2a8b4dSBrian Somers     }
1649409953dSBrian Somers   }
1659409953dSBrian Somers 
166da2a8b4dSBrian Somers   while (to > startto) {
167da2a8b4dSBrian Somers     to--;
168da2a8b4dSBrian Somers     if (!issep(*to)) {
169da2a8b4dSBrian Somers       to++;
170da2a8b4dSBrian Somers       break;
171da2a8b4dSBrian Somers     }
172da2a8b4dSBrian Somers   }
173da2a8b4dSBrian Somers   *to = '\0';
1749409953dSBrian Somers 
1759409953dSBrian Somers   return from;
176da2a8b4dSBrian Somers }
177da2a8b4dSBrian Somers 
178da2a8b4dSBrian Somers #define CTRL_UNKNOWN (0)
179da2a8b4dSBrian Somers #define CTRL_INCLUDE (1)
180da2a8b4dSBrian Somers 
181da2a8b4dSBrian Somers static int
DecodeCtrlCommand(char * line,char * arg)182da2a8b4dSBrian Somers DecodeCtrlCommand(char *line, char *arg)
183da2a8b4dSBrian Somers {
1849409953dSBrian Somers   const char *end;
1859409953dSBrian Somers 
186da2a8b4dSBrian Somers   if (!strncasecmp(line, "include", 7) && issep(line[7])) {
1879409953dSBrian Somers     end = InterpretArg(line+8, arg);
1889409953dSBrian Somers     if (*end && *end != '#')
189d3974088SDag-Erling Smørgrav       log_Printf(LogWARN, "usage: !include filename\n");
1909409953dSBrian Somers     else
191da2a8b4dSBrian Somers       return CTRL_INCLUDE;
192da2a8b4dSBrian Somers   }
193da2a8b4dSBrian Somers   return CTRL_UNKNOWN;
194da2a8b4dSBrian Somers }
195da2a8b4dSBrian Somers 
1967cf368ebSBrian Somers /*
1977cf368ebSBrian Somers  * Initialised in system_IsValid(), set in ReadSystem(),
1987cf368ebSBrian Somers  * used by system_IsValid()
1997cf368ebSBrian Somers  */
200565e35e5SBrian Somers static int modeok;
20112ef29a8SBrian Somers static int userok;
202565e35e5SBrian Somers static int modereq;
20312ef29a8SBrian Somers 
204af57ed9fSAtsushi Murai int
AllowUsers(struct cmdargs const * arg)205b6e82f33SBrian Somers AllowUsers(struct cmdargs const *arg)
20612ef29a8SBrian Somers {
207dd7e2610SBrian Somers   /* arg->bundle may be NULL (see system_IsValid()) ! */
20812ef29a8SBrian Somers   int f;
2098b50b30fSBrian Somers   struct passwd *pwd;
21012ef29a8SBrian Somers 
211dd49e719SBrian Somers   if (userok == -1)
21212ef29a8SBrian Somers     userok = 0;
213dd49e719SBrian Somers 
214a19a5c02SBrian Somers   pwd = getpwuid(ID0realuid());
2158b50b30fSBrian Somers   if (pwd != NULL)
21625092092SBrian Somers     for (f = arg->argn; f < arg->argc; f++)
2178b50b30fSBrian Somers       if (!strcmp("*", arg->argv[f]) || !strcmp(pwd->pw_name, arg->argv[f])) {
21812ef29a8SBrian Somers         userok = 1;
21912ef29a8SBrian Somers         break;
22012ef29a8SBrian Somers       }
2218b50b30fSBrian Somers   endpwent();
22212ef29a8SBrian Somers 
22312ef29a8SBrian Somers   return 0;
22412ef29a8SBrian Somers }
22512ef29a8SBrian Somers 
22612ef29a8SBrian Somers int
AllowModes(struct cmdargs const * arg)227b6e82f33SBrian Somers AllowModes(struct cmdargs const *arg)
22812ef29a8SBrian Somers {
229dd7e2610SBrian Somers   /* arg->bundle may be NULL (see system_IsValid()) ! */
230dd0645c5SBrian Somers   int f, mode, allowed;
23112ef29a8SBrian Somers 
23212ef29a8SBrian Somers   allowed = 0;
23325092092SBrian Somers   for (f = arg->argn; f < arg->argc; f++) {
234dd0645c5SBrian Somers     mode = Nam2mode(arg->argv[f]);
235dd0645c5SBrian Somers     if (mode == PHYS_NONE || mode == PHYS_ALL)
236dd7e2610SBrian Somers       log_Printf(LogWARN, "allow modes: %s: Invalid mode\n", arg->argv[f]);
237dd0645c5SBrian Somers     else
238dd0645c5SBrian Somers       allowed |= mode;
23912ef29a8SBrian Somers   }
24012ef29a8SBrian Somers 
241565e35e5SBrian Somers   modeok = modereq & allowed ? 1 : 0;
24212ef29a8SBrian Somers   return 0;
24312ef29a8SBrian Somers }
24412ef29a8SBrian Somers 
2451f64f3adSBrian Somers static char *
strip(char * line)2461f64f3adSBrian Somers strip(char *line)
2471f64f3adSBrian Somers {
2481f64f3adSBrian Somers   int len;
2491f64f3adSBrian Somers 
2501f64f3adSBrian Somers   len = strlen(line);
2511f64f3adSBrian Somers   while (len && (line[len-1] == '\n' || line[len-1] == '\r' ||
2521f64f3adSBrian Somers                  issep(line[len-1])))
2531f64f3adSBrian Somers     line[--len] = '\0';
2541f64f3adSBrian Somers 
2551f64f3adSBrian Somers   while (issep(*line))
2561f64f3adSBrian Somers     line++;
2571f64f3adSBrian Somers 
2581f64f3adSBrian Somers   if (*line == '#')
2591f64f3adSBrian Somers     *line = '\0';
2601f64f3adSBrian Somers 
2611f64f3adSBrian Somers   return line;
2621f64f3adSBrian Somers }
2631f64f3adSBrian Somers 
26412ef29a8SBrian Somers static int
xgets(char * buf,int buflen,FILE * fp)2651f64f3adSBrian Somers xgets(char *buf, int buflen, FILE *fp)
2661f64f3adSBrian Somers {
2671f64f3adSBrian Somers   int len, n;
2681f64f3adSBrian Somers 
2691f64f3adSBrian Somers   n = 0;
2701f64f3adSBrian Somers   while (fgets(buf, buflen-1, fp)) {
2711f64f3adSBrian Somers     n++;
2721f64f3adSBrian Somers     buf[buflen-1] = '\0';
2731f64f3adSBrian Somers     len = strlen(buf);
2741f64f3adSBrian Somers     while (len && (buf[len-1] == '\n' || buf[len-1] == '\r'))
2751f64f3adSBrian Somers       buf[--len] = '\0';
2761f64f3adSBrian Somers     if (len && buf[len-1] == '\\') {
2771f64f3adSBrian Somers       buf += len - 1;
2781f64f3adSBrian Somers       buflen -= len - 1;
2791f64f3adSBrian Somers       if (!buflen)        /* No buffer space */
2801f64f3adSBrian Somers         break;
2811f64f3adSBrian Somers     } else
2821f64f3adSBrian Somers       break;
2831f64f3adSBrian Somers   }
2841f64f3adSBrian Somers   return n;
2851f64f3adSBrian Somers }
2861f64f3adSBrian Somers 
287ed0e9269SBrian Somers /* Values for ``how'' in ReadSystem */
288ed0e9269SBrian Somers #define SYSTEM_EXISTS	1
289ed0e9269SBrian Somers #define SYSTEM_VALIDATE	2
290ed0e9269SBrian Somers #define SYSTEM_EXEC	3
291ed0e9269SBrian Somers 
29290e7fb01SBrian Somers static char *
GetLabel(char * line,const char * filename,int linenum)29390e7fb01SBrian Somers GetLabel(char *line, const char *filename, int linenum)
29490e7fb01SBrian Somers {
2955b78bdf8SBrian Somers   char *argv[MAXARGS];
2965b78bdf8SBrian Somers   int argc, len;
29790e7fb01SBrian Somers 
2985b78bdf8SBrian Somers   argc = MakeArgs(line, argv, MAXARGS, PARSE_REDUCE);
2995b78bdf8SBrian Somers 
3005b78bdf8SBrian Somers   if (argc == 2 && !strcmp(argv[1], ":"))
3015b78bdf8SBrian Somers     return argv[0];
3025b78bdf8SBrian Somers 
3035b78bdf8SBrian Somers   if (argc != 1 || (len = strlen(argv[0])) < 2 || argv[0][len-1] != ':') {
3045b78bdf8SBrian Somers       log_Printf(LogWARN, "Bad label in %s (line %d) - missing colon\n",
30590e7fb01SBrian Somers                  filename, linenum);
30690e7fb01SBrian Somers       return NULL;
30790e7fb01SBrian Somers   }
3085b78bdf8SBrian Somers   argv[0][len-1] = '\0';	/* Lose the ':' */
30990e7fb01SBrian Somers 
3105b78bdf8SBrian Somers   return argv[0];
31190e7fb01SBrian Somers }
31290e7fb01SBrian Somers 
3131322e9adSBrian Somers /* Returns -2 for ``file not found'' and -1 for ``label not found'' */
3141322e9adSBrian Somers 
3151ae349f5Scvs2svn static int
ReadSystem(struct bundle * bundle,const char * name,const char * file,struct prompt * prompt,struct datalink * cx,int how)3167a6f8720SBrian Somers ReadSystem(struct bundle *bundle, const char *name, const char *file,
317ed0e9269SBrian Somers            struct prompt *prompt, struct datalink *cx, int how)
318af57ed9fSAtsushi Murai {
319af57ed9fSAtsushi Murai   FILE *fp;
32090e7fb01SBrian Somers   char *cp;
321a1e8f937SBrian Somers   int n, len;
32286e02934SBrian Somers   char line[LINE_LEN];
32352847614SBrian Somers   char filename[PATH_MAX];
324274e766cSBrian Somers   int linenum;
32512ef29a8SBrian Somers   int argc;
326c9e11a11SBrian Somers   char *argv[MAXARGS];
32712ef29a8SBrian Somers   int allowcmd;
3281f64f3adSBrian Somers   int indent;
3291f64f3adSBrian Somers   char arg[LINE_LEN];
330b4f63b0bSBrian Somers   struct prompt *op;
331af57ed9fSAtsushi Murai 
332da2a8b4dSBrian Somers   if (*file == '/')
333da2a8b4dSBrian Somers     snprintf(filename, sizeof filename, "%s", file);
334da2a8b4dSBrian Somers   else
3357a66a36dSBrian Somers     snprintf(filename, sizeof filename, "%s/%s", PPP_CONFDIR, file);
3365106c671SBrian Somers   fp = ID0fopen(filename, "r");
337af57ed9fSAtsushi Murai   if (fp == NULL) {
338dd7e2610SBrian Somers     log_Printf(LogDEBUG, "ReadSystem: Can't open %s.\n", filename);
3391322e9adSBrian Somers     return -2;
340af57ed9fSAtsushi Murai   }
341dd7e2610SBrian Somers   log_Printf(LogDEBUG, "ReadSystem: Checking %s (%s).\n", name, filename);
342274e766cSBrian Somers 
343274e766cSBrian Somers   linenum = 0;
3441f64f3adSBrian Somers   while ((n = xgets(line, sizeof line, fp))) {
3451f64f3adSBrian Somers     linenum += n;
3461f64f3adSBrian Somers     if (issep(*line))
3471f64f3adSBrian Somers       continue;
3481f64f3adSBrian Somers 
3491f64f3adSBrian Somers     cp = strip(line);
3501f64f3adSBrian Somers 
351af57ed9fSAtsushi Murai     switch (*cp) {
3521f64f3adSBrian Somers     case '\0':			/* empty/comment */
353af57ed9fSAtsushi Murai       break;
3541f64f3adSBrian Somers 
3551f64f3adSBrian Somers     case '!':
356da2a8b4dSBrian Somers       switch (DecodeCtrlCommand(cp+1, arg)) {
357da2a8b4dSBrian Somers       case CTRL_INCLUDE:
358dd7e2610SBrian Somers         log_Printf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg);
359ed0e9269SBrian Somers         n = ReadSystem(bundle, name, arg, prompt, cx, how);
360dd7e2610SBrian Somers         log_Printf(LogCOMMAND, "%s: Done include of \"%s\"\n", filename, arg);
3612a8e2fe6SBrian Somers         if (!n) {
3622a8e2fe6SBrian Somers           fclose(fp);
363da2a8b4dSBrian Somers           return 0;	/* got it */
3642a8e2fe6SBrian Somers         }
365da2a8b4dSBrian Somers         break;
366da2a8b4dSBrian Somers       default:
367dd7e2610SBrian Somers         log_Printf(LogWARN, "%s: %s: Invalid command\n", filename, cp);
368da2a8b4dSBrian Somers         break;
369da2a8b4dSBrian Somers       }
3701f64f3adSBrian Somers       break;
3711f64f3adSBrian Somers 
3721f64f3adSBrian Somers     default:
37390e7fb01SBrian Somers       if ((cp = GetLabel(cp, filename, linenum)) == NULL)
3741b365e70SBrian Somers         continue;
3751f64f3adSBrian Somers 
3761f64f3adSBrian Somers       if (strcmp(cp, name) == 0) {
3771f64f3adSBrian Somers         /* We're in business */
3782a8e2fe6SBrian Somers         if (how == SYSTEM_EXISTS) {
3792a8e2fe6SBrian Somers           fclose(fp);
380ed0e9269SBrian Somers 	  return 0;
3812a8e2fe6SBrian Somers 	}
3821f64f3adSBrian Somers 	while ((n = xgets(line, sizeof line, fp))) {
3831f64f3adSBrian Somers           linenum += n;
3841f64f3adSBrian Somers           indent = issep(*line);
3851f64f3adSBrian Somers           cp = strip(line);
3861f64f3adSBrian Somers 
3871f64f3adSBrian Somers           if (*cp == '\0')			/* empty / comment */
3881f64f3adSBrian Somers             continue;
3891f64f3adSBrian Somers 
3908c8d43deSBrian Somers           if (!indent) {			/* start of next section */
39190e7fb01SBrian Somers             if (*cp != '!' && how == SYSTEM_EXEC)
3925b78bdf8SBrian Somers               cp = GetLabel(cp, filename, linenum);
3931f64f3adSBrian Somers             break;
3948c8d43deSBrian Somers           }
3951f64f3adSBrian Somers 
396a1e8f937SBrian Somers           len = strlen(cp);
3972a30e2acSBrian Somers           if ((argc = command_Expand_Interpret(cp, len, argv, cp - line)) < 0)
398c39aa54eSBrian Somers             log_Printf(LogWARN, "%s: %d: Syntax error\n", filename, linenum);
399c39aa54eSBrian Somers           else {
400c9e11a11SBrian Somers             allowcmd = argc > 0 && !strcasecmp(argv[0], "allow");
401dbde41c0SBrian Somers             if ((how != SYSTEM_EXEC && allowcmd) ||
402dbde41c0SBrian Somers                 (how == SYSTEM_EXEC && !allowcmd)) {
403b4f63b0bSBrian Somers               /*
404b4f63b0bSBrian Somers                * Disable any context so that warnings are given to everyone,
405b4f63b0bSBrian Somers                * including syslog.
406b4f63b0bSBrian Somers                */
407b4f63b0bSBrian Somers               op = log_PromptContext;
408b4f63b0bSBrian Somers               log_PromptContext = NULL;
40930291ffbSBrian Somers 	      command_Run(bundle, argc, (char const *const *)argv, prompt,
41030291ffbSBrian Somers                           name, cx);
411b4f63b0bSBrian Somers               log_PromptContext = op;
412b4f63b0bSBrian Somers             }
41312ef29a8SBrian Somers           }
414c39aa54eSBrian Somers         }
4151f64f3adSBrian Somers 
4161f64f3adSBrian Somers 	fclose(fp);  /* everything read - get out */
4171f64f3adSBrian Somers 	return 0;
418af57ed9fSAtsushi Murai       }
419af57ed9fSAtsushi Murai       break;
420af57ed9fSAtsushi Murai     }
421af57ed9fSAtsushi Murai   }
422af57ed9fSAtsushi Murai   fclose(fp);
423927145beSBrian Somers   return -1;
424af57ed9fSAtsushi Murai }
425af57ed9fSAtsushi Murai 
4267cf368ebSBrian Somers const char *
system_IsValid(const char * name,struct prompt * prompt,int mode)427dd7e2610SBrian Somers system_IsValid(const char *name, struct prompt *prompt, int mode)
42812ef29a8SBrian Somers {
4297a6f8720SBrian Somers   /*
4307a6f8720SBrian Somers    * Note:  The ReadSystem() calls only result in calls to the Allow*
4317a6f8720SBrian Somers    * functions.  arg->bundle will be set to NULL for these commands !
4327a6f8720SBrian Somers    */
4331322e9adSBrian Somers   int def, how, rs;
434dd49e719SBrian Somers   int defuserok;
4357cf368ebSBrian Somers 
4367cf368ebSBrian Somers   def = !strcmp(name, "default");
437ed0e9269SBrian Somers   how = ID0realuid() == 0 ? SYSTEM_EXISTS : SYSTEM_VALIDATE;
438dd49e719SBrian Somers   userok = -1;
43912ef29a8SBrian Somers   modeok = 1;
440565e35e5SBrian Somers   modereq = mode;
4417cf368ebSBrian Somers 
4421322e9adSBrian Somers   rs = ReadSystem(NULL, "default", CONFFILE, prompt, NULL, how);
4431322e9adSBrian Somers 
444dd49e719SBrian Somers   defuserok = userok;
445dd49e719SBrian Somers   userok = -1;
446dd49e719SBrian Somers 
4471322e9adSBrian Somers   if (!def) {
4481322e9adSBrian Somers     if (rs == -1)
4491322e9adSBrian Somers       rs = 0;		/* we don't care that ``default'' doesn't exist */
4501322e9adSBrian Somers 
4511322e9adSBrian Somers     if (rs == 0)
4521322e9adSBrian Somers       rs = ReadSystem(NULL, name, CONFFILE, prompt, NULL, how);
4531322e9adSBrian Somers 
4541322e9adSBrian Somers     if (rs == -1)
455ed0e9269SBrian Somers       return "Configuration label not found";
4567cf368ebSBrian Somers 
4571322e9adSBrian Somers     if (rs == -2)
4587a66a36dSBrian Somers       return PPP_CONFDIR "/" CONFFILE " : File not found";
4591322e9adSBrian Somers   }
460ed0e9269SBrian Somers 
461dd49e719SBrian Somers   if (userok == -1)
462dd49e719SBrian Somers     userok = defuserok;
463dd49e719SBrian Somers 
464ed0e9269SBrian Somers   if (how == SYSTEM_EXISTS)
465ed0e9269SBrian Somers     userok = modeok = 1;
4667cf368ebSBrian Somers 
4677cf368ebSBrian Somers   if (!userok)
468ed0e9269SBrian Somers     return "User access denied";
4697cf368ebSBrian Somers 
4707cf368ebSBrian Somers   if (!modeok)
471ed0e9269SBrian Somers     return "Mode denied for this label";
4727cf368ebSBrian Somers 
4737cf368ebSBrian Somers   return NULL;
47412ef29a8SBrian Somers }
47512ef29a8SBrian Somers 
47612ef29a8SBrian Somers int
system_Select(struct bundle * bundle,const char * name,const char * file,struct prompt * prompt,struct datalink * cx)477dd7e2610SBrian Somers system_Select(struct bundle *bundle, const char *name, const char *file,
47830291ffbSBrian Somers              struct prompt *prompt, struct datalink *cx)
47912ef29a8SBrian Somers {
48012ef29a8SBrian Somers   userok = modeok = 1;
481565e35e5SBrian Somers   modereq = PHYS_ALL;
482ed0e9269SBrian Somers   return ReadSystem(bundle, name, file, prompt, cx, SYSTEM_EXEC);
483af57ed9fSAtsushi Murai }
484