18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* radrealms.c 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A pppd plugin which is stacked on top of radius.so. This plugin 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* allows selection of alternate set of servers based on the user's realm. 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Author: Ben McKeegan ben@netservers.co.uk 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Copyright (C) 2002 Netservers 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* This plugin may be distributed according to the terms of the GNU 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* General Public License, version 2 or (at your option) any later version. 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char const RCSID[] = 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $"; 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "radiusclient.h" 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h> 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar pppd_version[] = VERSION; 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms"; 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t Options[] = { 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { "realms-config-file", o_string, &radrealms_config }, 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { NULL } 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern void (*radius_pre_auth_hook)(char const *user, 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **authserver, 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **acctserver); 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlookup_realm(char const *user, 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **authserver, 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **acctserver) 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *realm; 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FILE *fd; 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER *accts, *auths, *s; 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[512], *p; 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int line = 0; 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auths = (SERVER *) malloc(sizeof(SERVER)); 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auths->max = 0; 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project accts = (SERVER *) malloc(sizeof(SERVER)); 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project accts->max = 0; 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project realm = strrchr(user, '@'); 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (realm) { 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Looking up servers for realm '%s'", realm); 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Looking up servers for DEFAULT realm"); 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (realm) { 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (*(++realm) == '\0') { 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project realm = NULL; 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((fd = fopen(radrealms_config, "r")) == NULL) { 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("cannot open %s", radrealms_config); 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Reading %s", radrealms_config); 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project line++; 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0')) 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buffer[strlen(buffer)-1] = '\0'; 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = strtok(buffer, "\t "); 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (p == NULL || (strcmp(p, "authserver") !=0 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && strcmp(p, "acctserver"))) { 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: invalid line %d: %s", radrealms_config, 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project line, buffer); 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Parsing '%s' entry:", p); 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s = auths; 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (p[1] == 'c') { 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s = accts; 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (s->max >= SERVER_MAX) 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, "\t ")) == NULL) { 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: realm name missing on line %d: %s", 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((realm != NULL && strcmp(p, realm) == 0) || 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (realm == NULL && strcmp(p, "DEFAULT") == 0) ) { 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Matched realm %s", p); 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, ":")) == NULL) { 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: server address missing on line %d: %s", 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->name[s->max] = strdup(p); 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Address is '%s'",p); 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, "\t ")) == NULL) { 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: server port missing on line %d: %s", 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->port[s->max] = atoi(p); 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Port is '%d'", s->port[s->max]); 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->max++; 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Skipping realm '%s'", p); 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (accts->max) 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *acctserver = accts; 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (auths->max) 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *authserver = auths; 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectplugin_init(void) 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radius_pre_auth_hook = lookup_realm; 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project add_options(Options); 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("RADIUS Realms plugin initialized."); 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 148