radrealms plugin from Ben McKeegan
authorFrank Cusack <fcusack@fcusack.com>
Sat, 5 Oct 2002 04:35:24 +0000 (04:35 +0000)
committerFrank Cusack <fcusack@fcusack.com>
Sat, 5 Oct 2002 04:35:24 +0000 (04:35 +0000)
pppd/plugins/radius/Makefile.linux
pppd/plugins/radius/radiusclient/etc/Makefile.am
pppd/plugins/radius/radiusclient/etc/Makefile.in
pppd/plugins/radius/radiusclient/etc/realms [new file with mode: 0644]
pppd/plugins/radius/radrealms.c [new file with mode: 0644]

index 30a3ac40de500653b20c1db1e9aeed3bec7151d8..f8de391b693349d4ed8a0fcdeae763c3c0065c0a 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 MANDIR=/usr/man
-PLUGIN=radius.so radattr.so
+PLUGIN=radius.so radattr.so radrealms.so
 CFLAGS=-I../.. -I../../../include -Iradiusclient/include -O2
 
 # Uncomment the next line to include support for Microsoft's
@@ -32,6 +32,7 @@ install: all
        $(INSTALL) -d -m 755 $(LIBDIR)
        $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
        $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
+       $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
        $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)/man8
        $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)/man8
 
@@ -41,12 +42,18 @@ radius.so: radiusclient/lib/.libs/libradiusclient.a radius.o
 radattr.so: radattr.o
        gcc -o radattr.so -shared radattr.o
 
+radrealms.so: radrealms.o
+       gcc -o radrealms.so -shared radrealms.o
+
 radius.o: radius.c
        gcc $(CFLAGS) -c -o radius.o -fPIC radius.c
 
 radattr.o: radattr.c
        gcc $(CFLAGS) -c -o radattr.o -fPIC radattr.c
 
+radrealms.o: radrealms.c
+       gcc $(CFLAGS) -c -o radrealms.o -fPIC radrealms.c
+
 radiusclient/lib/.libs/libradiusclient.a:
        test -r radiusclient/Makefile ||           \
                (cd radiusclient;                  \
index bea69bc5f786f02dfd14b31c4b6d104dad455013..8f50d38e5424e857010342e0c7b3ce59e737afe7 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.am,v 1.2 2002/04/02 13:17:13 dfs Exp $
+# $Id: Makefile.am,v 1.3 2002/10/05 04:35:24 fcusack Exp $
 #
 # Copyright (C) 1997,1998 Lars Fenneberg
 #
@@ -20,17 +20,20 @@ pkgsysconf_DATA = issue port-id-map radiusclient.conf \
 
 EXTRA_DIST = issue port-id-map dictionary dictionary.ascend \
        dictionary.compat dictionary.merit dictionary.microsoft \
-       servers radiusclient.conf.in
+       realms servers radiusclient.conf.in
 
 radiusclient.conf: radiusclient.conf.in
        sed -e 's|@sbin''dir@|$(sbindir)|g' \
            -e 's|@pkgsysconf''dir@|$(pkgsysconfdir)|g' \
            <$(srcdir)/radiusclient.conf.in >radiusclient.conf
 
-install-data-local: servers
+install-data-local: realms servers
        $(mkinstalldirs) $(pkgsysconfdir); \
+        echo " $(INSTALL) -m600 $(srcdir)/realms $(pkgsysconfdir)/realms"; \
+        $(INSTALL) -m600 $(srcdir)/realms $(pkgsysconfdir)/realms
         echo " $(INSTALL) -m600 $(srcdir)/servers $(pkgsysconfdir)/servers"; \
         $(INSTALL) -m600 $(srcdir)/servers $(pkgsysconfdir)/servers
 
 uninstall-local:
+       rm -f $(pkgsysconfdir)/realms
        rm -f $(pkgsysconfdir)/servers
index fc36f526fab439501e4562b7105d903bbf321c2f..e3e2aedcdf55e53100a177c839c5d12e41ad558d 100644 (file)
@@ -11,7 +11,7 @@
 # PARTICULAR PURPOSE.
 
 #
-# $Id: Makefile.in,v 1.3 2002/04/02 13:17:13 dfs Exp $
+# $Id: Makefile.in,v 1.4 2002/10/05 04:35:24 fcusack Exp $
 #
 # Copyright (C) 1997,1998 Lars Fenneberg
 #
@@ -99,7 +99,7 @@ pkgsysconf_DATA = issue port-id-map radiusclient.conf \
 
 EXTRA_DIST = issue port-id-map dictionary dictionary.ascend \
        dictionary.compat dictionary.merit dictionary.microsoft \
-       servers radiusclient.conf.in
+       realms servers radiusclient.conf.in
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
 CONFIG_CLEAN_FILES = 
@@ -215,12 +215,15 @@ radiusclient.conf: radiusclient.conf.in
            -e 's|@pkgsysconf''dir@|$(pkgsysconfdir)|g' \
            <$(srcdir)/radiusclient.conf.in >radiusclient.conf
 
-install-data-local: servers
+install-data-local: realms servers
        $(mkinstalldirs) $(DESTDIR)$(pkgsysconfdir); \
+        echo " $(INSTALL) -m600 $(srcdir)/realms $(DESTDIR)$(pkgsysconfdir)/realms"; \
+        $(INSTALL) -m600 $(srcdir)/realms $(DESTDIR)$(pkgsysconfdir)/realms
         echo " $(INSTALL) -m600 $(srcdir)/servers $(DESTDIR)$(pkgsysconfdir)/servers"; \
         $(INSTALL) -m600 $(srcdir)/servers $(DESTDIR)$(pkgsysconfdir)/servers
 
 uninstall-local:
+       rm -f $(DESTDIR)$(pkgsysconfdir)/realms
        rm -f $(DESTDIR)$(pkgsysconfdir)/servers
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/pppd/plugins/radius/radiusclient/etc/realms b/pppd/plugins/radius/radiusclient/etc/realms
new file mode 100644 (file)
index 0000000..3440364
--- /dev/null
@@ -0,0 +1,22 @@
+# /etc/radiusclient/realms
+#
+# Handle realm @netservers.co.uk on an internal RADIUS server
+# (note the server must be told to strip the realm)
+
+#authserver netservers.co.uk 192.168.1.1:1812
+#acctserver netservers.co.uk 192.168.1.1:1813
+
+# users in realm @example.com are handled by separate servers
+
+#authserver example.com 10.0.0.1:1812
+#acctserver example.com 10.0.0.2:1813
+
+# the DEFAULT realm matches users that do not supply a realm
+
+#authserver DEFAULT 192.168.1.1:1812
+#acctserver DEFAULT 192.168.1.1:1813
+
+# Any realms that do not match in the realms file automatically fall 
+# through to the standard radius plugin which uses the servers in the 
+# radiusclient.conf file.  Note that this is different than the
+# DEFAULT realm match, above.
diff --git a/pppd/plugins/radius/radrealms.c b/pppd/plugins/radius/radrealms.c
new file mode 100644 (file)
index 0000000..1690042
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+*
+* radrealms.c
+*
+* A pppd plugin which is stacked on top of radius.so.  This plugin
+* allows selection of alternate set of servers based on the user's realm.
+*
+* Author: Ben McKeegan  ben@netservers.co.uk
+*
+* Copyright (C) 2002 Netservers
+*
+* This plugin may be distributed according to the terms of the GNU
+* General Public License, version 2 or (at your option) any later version.
+*
+*/
+
+static char const RCSID[] =
+    "$Id: radrealms.c,v 1.1 2002/10/05 04:35:24 fcusack Exp $";
+
+#include "pppd.h"
+#include "radiusclient.h"
+#include <stdio.h>
+#include <string.h>
+
+char pppd_version[] = VERSION;
+
+char radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms";
+
+static option_t Options[] = {
+    { "realms-config-file", o_string, &radrealms_config },
+    { NULL }
+};
+
+extern void (*radius_pre_auth_hook)(char const *user,
+                                   SERVER **authserver,
+                                   SERVER **acctserver);
+
+static void
+lookup_realm(char const *user,
+            SERVER **authserver,
+            SERVER **acctserver)
+{
+    char *realm;
+    FILE *fd;
+    SERVER *accts, *auths, *s;
+    char buffer[512], *p;
+    int line, pos;
+    
+    auths = (SERVER *) malloc(sizeof(SERVER));
+    auths->max = 0;
+    accts = (SERVER *) malloc(sizeof(SERVER));
+    accts->max = 0;
+    
+    realm = strrchr(user, '@');
+    
+    if (realm) {
+       info("Looking up servers for realm '%s'", realm);
+    } else {
+       info("Looking up servers for DEFAULT realm");
+    }
+    if (realm) {
+       if (*(++realm) == '\0') {
+           realm = NULL;
+       }
+    }
+    
+    if ((fd = fopen(radrealms_config, "r")) == NULL) {
+       option_error("cannot open %s", radrealms_config);
+       return;
+    } 
+    info("Reading %s", radrealms_config);
+    
+    while ((fgets(buffer, sizeof(buffer), fd) != NULL)) {
+       line++;
+
+       if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0'))
+           continue;
+
+       buffer[strlen(buffer)-1] = '\0';
+
+       p = strtok(buffer, "\t ");
+
+       if (p == NULL || (strcmp(p, "authserver") !=0
+           && strcmp(p, "acctserver"))) {
+           fclose(fd);
+           option_error("%s: invalid line %d: %s", radrealms_config,
+                        line, buffer);
+           return;
+       }
+       info("Parsing '%s' entry:", p);
+       s = auths;
+       if (p[1] == 'c') {
+           s = accts;
+       }
+       if (s->max >= SERVER_MAX)
+           continue;
+
+       if ((p = strtok(NULL, "\t ")) == NULL) {
+           fclose(fd);
+           option_error("%s: realm name missing on line %d: %s",
+                        radrealms_config, line, buffer);
+           return;
+       }
+
+       if ((realm != NULL && strcmp(p, realm) == 0) ||
+           (realm == NULL && strcmp(p, "DEFAULT") == 0) ) {
+           info(" - Matched realm %s", p);
+           if ((p = strtok(NULL, ":")) == NULL) {
+               fclose(fd);
+               option_error("%s: server address missing on line %d: %s",
+                            radrealms_config, line, buffer);
+               return;
+           }
+           s->name[s->max] = strdup(p);
+           info(" - Address is '%s'",p);
+           if ((p = strtok(NULL, "\t ")) == NULL) {
+               fclose(fd);
+               option_error("%s: server port missing on line %d:  %s",
+                            radrealms_config, line, buffer);
+               return;
+           }
+           s->port[s->max] = atoi(p);
+           info(" - Port is '%d'", s->port[s->max]);
+           s->max++;
+       } else 
+           info(" - Skipping realm '%s'", p);
+    }
+    fclose(fd);
+
+    if (accts->max)
+       *acctserver = accts;
+
+    if (auths->max)
+       *authserver = auths;
+
+    return;
+}
+
+void
+plugin_init(void)
+{
+    radius_pre_auth_hook = lookup_realm;
+
+    add_options(Options);
+    info("RADIUS Realms plugin initialized.");
+}