2 * System configuration routines
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the Internet Initiative Japan, Inc. The name of the
14 * IIJ may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 #include <sys/param.h>
40 #define issep(ch) ((ch) == ' ' || (ch) == '\t')
43 OpenSecret(const char *file)
48 snprintf(line, sizeof line, "%s/%s", _PATH_PPP, file);
49 fp = ID0fopen(line, "r");
51 log_Printf(LogWARN, "OpenSecret: Can't open %s.\n", line);
61 /* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */
63 InterpretArg(char *from, char *to)
66 char *ptr, *startto, *endto;
70 endto = to + LINE_LEN - 1;
75 ptr = strchr(++from, '/');
76 len = ptr ? ptr - from : strlen(from);
78 if ((env = getenv("HOME")) == NULL)
80 strncpy(to, env, endto - to);
84 strncpy(to, from, len);
88 strncpy(to, pwd->pw_dir, endto-to);
90 strncpy(to, _PATH_PPP, endto - to);
98 while (to < endto && *from != '\0') {
100 if (from[1] == '$') {
101 *to = '\0'; /* For an empty var name below */
103 } else if (from[1] == '{') {
104 ptr = strchr(from+2, '}');
106 len = ptr - from - 2;
107 if (endto - to < len )
110 strncpy(to, from+2, len);
123 for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++)
129 else if ((env = getenv(to)) != NULL) {
130 strncpy(to, env, endto - to);
137 while (to > startto) {
147 #define CTRL_UNKNOWN (0)
148 #define CTRL_INCLUDE (1)
151 DecodeCtrlCommand(char *line, char *arg)
153 if (!strncasecmp(line, "include", 7) && issep(line[7])) {
154 InterpretArg(line+8, arg);
161 * Initialised in system_IsValid(), set in ReadSystem(),
162 * used by system_IsValid()
169 AllowUsers(struct cmdargs const *arg)
171 /* arg->bundle may be NULL (see system_IsValid()) ! */
178 for (f = arg->argn; f < arg->argc; f++)
179 if (!strcmp("*", arg->argv[f]) || !strcmp(user, arg->argv[f])) {
188 AllowModes(struct cmdargs const *arg)
190 /* arg->bundle may be NULL (see system_IsValid()) ! */
191 int f, mode, allowed;
194 for (f = arg->argn; f < arg->argc; f++) {
195 mode = Nam2mode(arg->argv[f]);
196 if (mode == PHYS_NONE || mode == PHYS_ALL)
197 log_Printf(LogWARN, "allow modes: %s: Invalid mode\n", arg->argv[f]);
202 modeok = modereq & allowed ? 1 : 0;
212 while (len && (line[len-1] == '\n' || line[len-1] == '\r' ||
226 xgets(char *buf, int buflen, FILE *fp)
231 while (fgets(buf, buflen-1, fp)) {
233 buf[buflen-1] = '\0';
235 while (len && (buf[len-1] == '\n' || buf[len-1] == '\r'))
237 if (len && buf[len-1] == '\\') {
240 if (!buflen) /* No buffer space */
248 /* Values for ``how'' in ReadSystem */
249 #define SYSTEM_EXISTS 1
250 #define SYSTEM_VALIDATE 2
251 #define SYSTEM_EXEC 3
253 /* Returns -2 for ``file not found'' and -1 for ``label not found'' */
256 ReadSystem(struct bundle *bundle, const char *name, const char *file,
257 struct prompt *prompt, struct datalink *cx, int how)
263 char filename[MAXPATHLEN];
273 snprintf(filename, sizeof filename, "%s", file);
275 snprintf(filename, sizeof filename, "%s/%s", _PATH_PPP, file);
276 fp = ID0fopen(filename, "r");
278 log_Printf(LogDEBUG, "ReadSystem: Can't open %s.\n", filename);
281 log_Printf(LogDEBUG, "ReadSystem: Checking %s (%s).\n", name, filename);
284 while ((n = xgets(line, sizeof line, fp))) {
292 case '\0': /* empty/comment */
296 switch (DecodeCtrlCommand(cp+1, arg)) {
298 log_Printf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg);
299 n = ReadSystem(bundle, name, arg, prompt, cx, how);
300 log_Printf(LogCOMMAND, "%s: Done include of \"%s\"\n", filename, arg);
302 return 0; /* got it */
305 log_Printf(LogWARN, "%s: %s: Invalid command\n", filename, cp);
311 wp = strchr(cp, ':');
312 if (wp == NULL || wp[1] != '\0') {
313 log_Printf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n",
318 cp = strip(cp); /* lose any spaces between the label and the ':' */
320 if (strcmp(cp, name) == 0) {
321 /* We're in business */
322 if (how == SYSTEM_EXISTS)
324 while ((n = xgets(line, sizeof line, fp))) {
326 indent = issep(*line);
329 if (*cp == '\0') /* empty / comment */
332 if (!indent) { /* start of next section */
334 wp = strchr(cp, ':');
335 if ((how == SYSTEM_EXEC) && (wp == NULL || wp[1] != '\0'))
336 log_Printf(LogWARN, "Unindented command (%s line %d) -"
337 " ignored\n", filename, linenum);
343 argc = command_Interpret(cp, len, argv);
344 allowcmd = argc > 0 && !strcasecmp(argv[0], "allow");
345 if ((!(how == SYSTEM_EXEC) && allowcmd) ||
346 ((how == SYSTEM_EXEC) && !allowcmd)) {
348 * Disable any context so that warnings are given to everyone,
351 op = log_PromptContext;
352 log_PromptContext = NULL;
353 command_Run(bundle, argc, (char const *const *)argv, prompt,
355 log_PromptContext = op;
359 fclose(fp); /* everything read - get out */
370 system_IsValid(const char *name, struct prompt *prompt, int mode)
373 * Note: The ReadSystem() calls only result in calls to the Allow*
374 * functions. arg->bundle will be set to NULL for these commands !
378 def = !strcmp(name, "default");
379 how = ID0realuid() == 0 ? SYSTEM_EXISTS : SYSTEM_VALIDATE;
384 rs = ReadSystem(NULL, "default", CONFFILE, prompt, NULL, how);
388 rs = 0; /* we don't care that ``default'' doesn't exist */
391 rs = ReadSystem(NULL, name, CONFFILE, prompt, NULL, how);
394 return "Configuration label not found";
397 return _PATH_PPP "/" CONFFILE ": File not found";
400 if (how == SYSTEM_EXISTS)
404 return "User access denied";
407 return "Mode denied for this label";
413 system_Select(struct bundle *bundle, const char *name, const char *file,
414 struct prompt *prompt, struct datalink *cx)
418 return ReadSystem(bundle, name, file, prompt, cx, SYSTEM_EXEC);