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