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@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
lookup_realm(char const * user,SERVER ** authserver,SERVER ** acctserver)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
plugin_init(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