]> git.ozlabs.org Git - ppp.git/blob - pppd/plugins/radius/radrealms.c
Merge pull request #101 from vyos/if-renaming-clean
[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 #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
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         free(auths);
72         free(accts);
73         return;
74     }
75     info("Reading %s", radrealms_config);
76
77     while ((fgets(buffer, sizeof(buffer), fd) != NULL)) {
78         line++;
79
80         if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0'))
81             continue;
82
83         buffer[strlen(buffer)-1] = '\0';
84
85         p = strtok(buffer, "\t ");
86
87         if (p == NULL || (strcmp(p, "authserver") !=0
88             && strcmp(p, "acctserver"))) {
89             fclose(fd);
90             option_error("%s: invalid line %d: %s", radrealms_config,
91                          line, buffer);
92             free(auths);
93             free(accts);
94             return;
95         }
96         info("Parsing '%s' entry:", p);
97         s = auths;
98         if (p[1] == 'c') {
99             s = accts;
100         }
101         if (s->max >= SERVER_MAX)
102             continue;
103
104         if ((p = strtok(NULL, "\t ")) == NULL) {
105             fclose(fd);
106             option_error("%s: realm name missing on line %d: %s",
107                          radrealms_config, line, buffer);
108             free(auths);
109             free(accts);
110             return;
111         }
112
113         if ((realm != NULL && strcmp(p, realm) == 0) ||
114             (realm == NULL && strcmp(p, "DEFAULT") == 0) ) {
115             info(" - Matched realm %s", p);
116             if ((p = strtok(NULL, ":")) == NULL) {
117                 fclose(fd);
118                 option_error("%s: server address missing on line %d: %s",
119                              radrealms_config, line, buffer);
120                 free(auths);
121                 free(accts);
122                 return;
123             }
124             s->name[s->max] = strdup(p);
125             info(" - Address is '%s'",p);
126             if ((p = strtok(NULL, "\t ")) == NULL) {
127                 fclose(fd);
128                 option_error("%s: server port missing on line %d:  %s",
129                              radrealms_config, line, buffer);
130                 free(auths);
131                 free(accts);
132                 return;
133             }
134             s->port[s->max] = atoi(p);
135             info(" - Port is '%d'", s->port[s->max]);
136             s->max++;
137         } else 
138             info(" - Skipping realm '%s'", p);
139     }
140     fclose(fd);
141
142     if (accts->max)
143         *acctserver = accts;
144
145     if (auths->max)
146         *authserver = auths;
147
148     return;
149 }
150
151 void
152 plugin_init(void)
153 {
154     radius_pre_auth_hook = lookup_realm;
155
156     add_options(Options);
157     info("RADIUS Realms plugin initialized.");
158 }