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 { NULL } 33 }; 34 35 extern void (*radius_pre_auth_hook)(char const *user, 36 SERVER **authserver, 37 SERVER **acctserver); 38 39 static void 40 lookup_realm(char const *user, 41 SERVER **authserver, 42 SERVER **acctserver) 43 { 44 char *realm; 45 FILE *fd; 46 SERVER *accts, *auths, *s; 47 char buffer[512], *p; 48 int line = 0; 49 50 auths = (SERVER *) malloc(sizeof(SERVER)); 51 auths->max = 0; 52 accts = (SERVER *) malloc(sizeof(SERVER)); 53 accts->max = 0; 54 55 realm = strrchr(user, '@'); 56 57 if (realm) { 58 info("Looking up servers for realm '%s'", realm); 59 } else { 60 info("Looking up servers for DEFAULT realm"); 61 } 62 if (realm) { 63 if (*(++realm) == '\0') { 64 realm = NULL; 65 } 66 } 67 68 if ((fd = fopen(radrealms_config, "r")) == NULL) { 69 option_error("cannot open %s", radrealms_config); 70 return; 71 } 72 info("Reading %s", radrealms_config); 73 74 while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { 75 line++; 76 77 if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0')) 78 continue; 79 80 buffer[strlen(buffer)-1] = '\0'; 81 82 p = strtok(buffer, "\t "); 83 84 if (p == NULL || (strcmp(p, "authserver") !=0 85 && strcmp(p, "acctserver"))) { 86 fclose(fd); 87 option_error("%s: invalid line %d: %s", radrealms_config, 88 line, buffer); 89 return; 90 } 91 info("Parsing '%s' entry:", p); 92 s = auths; 93 if (p[1] == 'c') { 94 s = accts; 95 } 96 if (s->max >= SERVER_MAX) 97 continue; 98 99 if ((p = strtok(NULL, "\t ")) == NULL) { 100 fclose(fd); 101 option_error("%s: realm name missing on line %d: %s", 102 radrealms_config, line, buffer); 103 return; 104 } 105 106 if ((realm != NULL && strcmp(p, realm) == 0) || 107 (realm == NULL && strcmp(p, "DEFAULT") == 0) ) { 108 info(" - Matched realm %s", p); 109 if ((p = strtok(NULL, ":")) == NULL) { 110 fclose(fd); 111 option_error("%s: server address missing on line %d: %s", 112 radrealms_config, line, buffer); 113 return; 114 } 115 s->name[s->max] = strdup(p); 116 info(" - Address is '%s'",p); 117 if ((p = strtok(NULL, "\t ")) == NULL) { 118 fclose(fd); 119 option_error("%s: server port missing on line %d: %s", 120 radrealms_config, line, buffer); 121 return; 122 } 123 s->port[s->max] = atoi(p); 124 info(" - Port is '%d'", s->port[s->max]); 125 s->max++; 126 } else 127 info(" - Skipping realm '%s'", p); 128 } 129 fclose(fd); 130 131 if (accts->max) 132 *acctserver = accts; 133 134 if (auths->max) 135 *authserver = auths; 136 137 return; 138 } 139 140 void 141 plugin_init(void) 142 { 143 radius_pre_auth_hook = lookup_realm; 144 145 add_options(Options); 146 info("RADIUS Realms plugin initialized."); 147 } 148