systems.c revision 32663
1/* 2 * System configuration routines 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 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. 19 * 20 * $Id: systems.c,v 1.34 1997/12/24 09:29:17 brian Exp $ 21 * 22 * TODO: 23 */ 24#include <sys/param.h> 25#include <netinet/in.h> 26 27#include <ctype.h> 28#include <pwd.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32#include <unistd.h> 33 34#include "command.h" 35#include "mbuf.h" 36#include "log.h" 37#include "id.h" 38#include "defs.h" 39#include "timer.h" 40#include "fsm.h" 41#include "loadalias.h" 42#include "pathnames.h" 43#include "vars.h" 44#include "server.h" 45#include "systems.h" 46 47#define issep(ch) ((ch) == ' ' || (ch) == '\t') 48 49FILE * 50OpenSecret(const char *file) 51{ 52 FILE *fp; 53 char line[100]; 54 55 snprintf(line, sizeof line, "%s/%s", _PATH_PPP, file); 56 fp = ID0fopen(line, "r"); 57 if (fp == NULL) 58 LogPrintf(LogWARN, "OpenSecret: Can't open %s.\n", line); 59 return (fp); 60} 61 62void 63CloseSecret(FILE * fp) 64{ 65 fclose(fp); 66} 67 68/* Move string from ``from'' to ``to'', interpreting ``~'' and $.... */ 69static void 70InterpretArg(char *from, char *to) 71{ 72 const char *env; 73 char *ptr, *startto, *endto; 74 int len; 75 76 startto = to; 77 endto = to + LINE_LEN - 1; 78 79 while(issep(*from)) 80 from++; 81 if (*from == '~') { 82 ptr = strchr(++from, '/'); 83 len = ptr ? ptr - from : strlen(from); 84 if (len == 0) { 85 if ((env = getenv("HOME")) == NULL) 86 env = _PATH_PPP; 87 strncpy(to, env, endto - to); 88 } else { 89 struct passwd *pwd; 90 91 strncpy(to, from, len); 92 to[len] = '\0'; 93 pwd = getpwnam(to); 94 if (pwd) 95 strncpy(to, pwd->pw_dir, endto-to); 96 else 97 strncpy(to, _PATH_PPP, endto - to); 98 endpwent(); 99 } 100 *endto = '\0'; 101 to += strlen(to); 102 from += len; 103 } 104 105 while (to < endto && *from != '\0') { 106 if (*from == '$') { 107 if (from[1] == '$') { 108 *to = '\0'; /* For an empty var name below */ 109 from += 2; 110 } else if (from[1] == '{') { 111 ptr = strchr(from+2, '}'); 112 if (ptr) { 113 len = ptr - from - 2; 114 if (endto - to < len ) 115 len = endto - to; 116 if (len) { 117 strncpy(to, from+2, len); 118 to[len] = '\0'; 119 from = ptr+1; 120 } else { 121 *to++ = *from++; 122 continue; 123 } 124 } else { 125 *to++ = *from++; 126 continue; 127 } 128 } else { 129 ptr = to; 130 for (from++; (isalnum(*from) || *from == '_') && ptr < endto; from++) 131 *ptr++ = *from; 132 *ptr = '\0'; 133 } 134 if (*to == '\0') 135 *to++ = '$'; 136 else if ((env = getenv(to)) != NULL) { 137 strncpy(to, env, endto - to); 138 *endto = '\0'; 139 to += strlen(to); 140 } 141 } else 142 *to++ = *from++; 143 } 144 while (to > startto) { 145 to--; 146 if (!issep(*to)) { 147 to++; 148 break; 149 } 150 } 151 *to = '\0'; 152} 153 154#define CTRL_UNKNOWN (0) 155#define CTRL_INCLUDE (1) 156 157static int 158DecodeCtrlCommand(char *line, char *arg) 159{ 160 if (!strncasecmp(line, "include", 7) && issep(line[7])) { 161 InterpretArg(line+8, arg); 162 return CTRL_INCLUDE; 163 } 164 return CTRL_UNKNOWN; 165} 166 167static int userok; 168 169int 170AllowUsers(struct cmdargs const *arg) 171{ 172 int f; 173 char *user; 174 175 userok = 0; 176 user = getlogin(); 177 if (user && *user) 178 for (f = 0; f < arg->argc; f++) 179 if (!strcmp("*", arg->argv[f]) || !strcmp(user, arg->argv[f])) { 180 userok = 1; 181 break; 182 } 183 184 return 0; 185} 186 187static struct { 188 int mode; 189 const char *name; 190} modes[] = { 191 { MODE_INTER, "interactive" }, 192 { MODE_AUTO, "auto" }, 193 { MODE_DIRECT, "direct" }, 194 { MODE_DEDICATED, "dedicated" }, 195 { MODE_DDIAL, "ddial" }, 196 { MODE_BACKGROUND, "background" }, 197 { ~0, "*" }, 198 { 0, 0 } 199}; 200 201static int modeok; 202 203int 204AllowModes(struct cmdargs const *arg) 205{ 206 int f; 207 int m; 208 int allowed; 209 210 allowed = 0; 211 for (f = 0; f < arg->argc; f++) { 212 for (m = 0; modes[m].mode; m++) 213 if (!strcasecmp(modes[m].name, arg->argv[f])) { 214 allowed |= modes[m].mode; 215 break; 216 } 217 if (modes[m].mode == 0) 218 LogPrintf(LogWARN, "allow modes: %s: Invalid mode\n", arg->argv[f]); 219 } 220 221 modeok = (mode | allowed) == allowed ? 1 : 0; 222 return 0; 223} 224 225static int 226ReadSystem(const char *name, const char *file, int doexec) 227{ 228 FILE *fp; 229 char *cp, *wp; 230 int n, len; 231 u_char olauth; 232 char line[LINE_LEN]; 233 char filename[MAXPATHLEN]; 234 int linenum; 235 int argc; 236 char **argv; 237 int allowcmd; 238 239 if (*file == '/') 240 snprintf(filename, sizeof filename, "%s", file); 241 else 242 snprintf(filename, sizeof filename, "%s/%s", _PATH_PPP, file); 243 fp = ID0fopen(filename, "r"); 244 if (fp == NULL) { 245 LogPrintf(LogDEBUG, "ReadSystem: Can't open %s.\n", filename); 246 return (-1); 247 } 248 LogPrintf(LogDEBUG, "ReadSystem: Checking %s (%s).\n", name, filename); 249 250 linenum = 0; 251 while (fgets(line, sizeof line, fp)) { 252 linenum++; 253 cp = line; 254 switch (*cp) { 255 case '#': /* comment */ 256 break; 257 case ' ': 258 case '\t': 259 break; 260 default: 261 wp = strpbrk(cp, ":\n"); 262 if (wp == NULL) { 263 LogPrintf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n", 264 filename, linenum); 265 ServerClose(); 266 exit(1); 267 } 268 *wp = '\0'; 269 if (*cp == '!') { 270 char arg[LINE_LEN]; 271 switch (DecodeCtrlCommand(cp+1, arg)) { 272 case CTRL_INCLUDE: 273 LogPrintf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg); 274 n = ReadSystem(name, arg, doexec); 275 LogPrintf(LogCOMMAND, "%s: Done include of \"%s\"\n", filename, arg); 276 if (!n) 277 return 0; /* got it */ 278 break; 279 default: 280 LogPrintf(LogWARN, "%s: %s: Invalid command\n", filename, cp); 281 break; 282 } 283 } else if (strcmp(cp, name) == 0) { 284 while (fgets(line, sizeof line, fp)) { 285 cp = line; 286 if (issep(*cp)) { 287 n = strspn(cp, " \t"); 288 cp += n; 289 len = strlen(cp); 290 if (!len || *cp == '#') 291 continue; 292 if (cp[len-1] == '\n') 293 cp[--len] = '\0'; 294 if (!len) 295 continue; 296 InterpretCommand(cp, len, &argc, &argv); 297 allowcmd = argc > 0 && !strcasecmp(*argv, "allow"); 298 if ((!doexec && allowcmd) || (doexec && !allowcmd)) { 299 olauth = VarLocalAuth; 300 if (VarLocalAuth == LOCAL_NO_AUTH) 301 VarLocalAuth = LOCAL_AUTH; 302 RunCommand(argc, (char const *const *)argv, name); 303 VarLocalAuth = olauth; 304 } 305 } else if (*cp == '#' || *cp == '\n' || *cp == '\0') { 306 continue; 307 } else 308 break; 309 } 310 fclose(fp); 311 return (0); 312 } 313 break; 314 } 315 } 316 fclose(fp); 317 return -1; 318} 319 320int 321ValidSystem(const char *name) 322{ 323 if (ID0realuid() == 0) 324 return userok = modeok = 1; 325 userok = 0; 326 modeok = 1; 327 ReadSystem("default", CONFFILE, 0); 328 if (name != NULL) 329 ReadSystem(name, CONFFILE, 0); 330 return userok && modeok; 331} 332 333int 334SelectSystem(const char *name, const char *file) 335{ 336 userok = modeok = 1; 337 return ReadSystem(name, file, 1); 338} 339 340int 341LoadCommand(struct cmdargs const *arg) 342{ 343 const char *name; 344 345 if (arg->argc > 0) 346 name = *arg->argv; 347 else 348 name = "default"; 349 350 if (!ValidSystem(name)) { 351 LogPrintf(LogERROR, "%s: Label not allowed\n", name); 352 return 1; 353 } else if (SelectSystem(name, CONFFILE) < 0) { 354 LogPrintf(LogWARN, "%s: label not found.\n", name); 355 return -1; 356 } else 357 SetLabel(arg->argc ? name : NULL); 358 return 0; 359} 360 361int 362SaveCommand(struct cmdargs const *arg) 363{ 364 LogPrintf(LogWARN, "save command is not implemented (yet).\n"); 365 return 1; 366} 367