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