1 /* 2 * 3 * radrealms.c 4 * 5 * A pppd plugin which is stacked on top of radius.so. This plugin 6 * allows selection of alternate set of servers based on the user's realm. 7 * 8 * Author: Ben McKeegan ben (at) netservers.co.uk 9 * 10 * Copyright (C) 2002 Netservers 11 * 12 * This plugin may be distributed according to the terms of the GNU 13 * General Public License, version 2 or (at your option) any later version. 14 * 15 */ 16 17 static char const RCSID[] = 18 "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $"; 19 20 #include "pppd.h" 21 #include "radiusclient.h" 22 #include <stdio.h> 23 #include <string.h> 24 #include <stdlib.h> 25 26 char pppd_version[] = VERSION; 27 28 char radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms"; 29 30 static option_t Options[] = { 31 { "realms-config-file", o_string, &radrealms_config, 32 "Configuration file for RADIUS realms", OPT_STATIC, NULL, MAXPATHLEN }, 33 { NULL } 34 }; 35 36 extern void (*radius_pre_auth_hook)(char const *user, 37 SERVER **authserver, 38 SERVER **acctserver); 39 40 static void 41 lookup_realm(char const *user, 42 SERVER **authserver, 43 SERVER **acctserver) 44 { 45 char *realm; 46 FILE *fd; 47 SERVER *accts, *auths, *s; 48 char buffer[512], *p; 49 int line = 0; 50 51 auths = (SERVER *) malloc(sizeof(SERVER)); 52 auths->max = 0; 53 accts = (SERVER *) malloc(sizeof(SERVER)); 54 accts->max = 0; 55 56 realm = strrchr(user, '@'); 57 58 if (realm) { 59 info("Looking up servers for realm '%s'", realm); 60 } else { 61 info("Looking up servers for DEFAULT realm"); 62 } 63 if (realm) { 64 if (*(++realm) == '\0') { 65 realm = NULL; 66 } 67 } 68 69 if ((fd = fopen(radrealms_config, "r")) == NULL) { 70 option_error("cannot open %s", radrealms_config); 71 return; 72 } 73 info("Reading %s", radrealms_config); 74 75 while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { 76 line++; 77 78 if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0')) 79 continue; 80 81 buffer[strlen(buffer)-1] = '\0'; 82 83 p = strtok(buffer, "\t "); 84 85 if (p == NULL || (strcmp(p, "authserver") !=0 86 && strcmp(p, "acctserver"))) { 87 fclose(fd); 88 option_error("%s: invalid line %d: %s", radrealms_config, 89 line, buffer); 90 return; 91 } 92 info("Parsing '%s' entry:", p); 93 s = auths; 94 if (p[1] == 'c') { 95 s = accts; 96 } 97 if (s->max >= SERVER_MAX) 98 continue; 99 100 if ((p = strtok(NULL, "\t ")) == NULL) { 101 fclose(fd); 102 option_error("%s: realm name missing on line %d: %s", 103 radrealms_config, line, buffer); 104 return; 105 } 106 107 if ((realm != NULL && strcmp(p, realm) == 0) || 108 (realm == NULL && strcmp(p, "DEFAULT") == 0) ) { 109 info(" - Matched realm %s", p); 110 if ((p = strtok(NULL, ":")) == NULL) { 111 fclose(fd); 112 option_error("%s: server address missing on line %d: %s", 113 radrealms_config, line, buffer); 114 return; 115 } 116 s->name[s->max] = strdup(p); 117 info(" - Address is '%s'",p); 118 if ((p = strtok(NULL, "\t ")) == NULL) { 119 fclose(fd); 120 option_error("%s: server port missing on line %d: %s", 121 radrealms_config, line, buffer); 122 return; 123 } 124 s->port[s->max] = atoi(p); 125 info(" - Port is '%d'", s->port[s->max]); 126 s->max++; 127 } else 128 info(" - Skipping realm '%s'", p); 129 } 130 fclose(fd); 131 132 if (accts->max) 133 *acctserver = accts; 134 135 if (auths->max) 136 *authserver = auths; 137 138 return; 139 } 140 141 void 142 plugin_init(void) 143 { 144 radius_pre_auth_hook = lookup_realm; 145 146 add_options(Options); 147 info("RADIUS Realms plugin initialized."); 148 } 149