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