summaryrefslogtreecommitdiff
path: root/modules/pam_radius
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2000-06-20 22:10:38 +0000
committerAndrew G. Morgan <morgan@kernel.org>2000-06-20 22:10:38 +0000
commitea488580c42e8918445a945484de3c8a5addc761 (patch)
treec992f3ba699caafedfadc16af38e6359c3c24698 /modules/pam_radius
Initial revision
Diffstat (limited to 'modules/pam_radius')
-rw-r--r--modules/pam_radius/.cvsignore1
-rw-r--r--modules/pam_radius/Makefile99
-rw-r--r--modules/pam_radius/README58
-rw-r--r--modules/pam_radius/pam_radius.c193
-rw-r--r--modules/pam_radius/pam_radius.h38
5 files changed, 389 insertions, 0 deletions
diff --git a/modules/pam_radius/.cvsignore b/modules/pam_radius/.cvsignore
new file mode 100644
index 00000000..380a834a
--- /dev/null
+++ b/modules/pam_radius/.cvsignore
@@ -0,0 +1 @@
+dynamic
diff --git a/modules/pam_radius/Makefile b/modules/pam_radius/Makefile
new file mode 100644
index 00000000..a74b911f
--- /dev/null
+++ b/modules/pam_radius/Makefile
@@ -0,0 +1,99 @@
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10
+#
+# STATIC modules are not supported
+#
+
+TITLE=pam_radius
+CONFD=$(CONFIGED)/security
+export CONFD
+CONFILE=$(CONFD)/radius.conf
+export CONFILE
+
+ifeq ($(HAVE_PWDBLIB),yes)
+
+#
+
+LIBSRC = $(TITLE).c
+LIBOBJ = $(TITLE).o
+
+LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
+#LIBOBJS = $(addprefix static/,$(LIBOBJ))
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+#static/%.o : %.c
+# $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+
+ifdef DYNAMIC
+LIBSHARED = $(TITLE).so
+endif
+
+#ifdef STATIC
+#LIBSTATIC = lib$(TITLE).o
+#endif
+
+####################### don't edit below #######################
+
+dummy:
+
+ @echo "**** This is not a top-level Makefile "
+ exit
+
+all: dirs $(LIBSHARED) $(LIBSTATIC) register
+
+dirs:
+ifdef DYNAMIC
+ $(MKDIR) ./dynamic
+endif
+#ifdef STATIC
+# $(MKDIR) ./static
+#endif
+
+register:
+#ifdef STATIC
+# ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+#endif
+
+ifdef DYNAMIC
+$(LIBOBJD): $(LIBSRC)
+
+$(LIBSHARED): $(LIBOBJD)
+ $(LD_D) -o $@ $(LIBOBJD) -lpwdb
+endif
+
+#ifdef STATIC
+#$(LIBOBJS): $(LIBSRC)
+#
+#$(LIBSTATIC): $(LIBOBJS)
+# $(LD) -r -o $@ $(LIBOBJS) -lpwdb
+#endif
+
+install: all
+ifdef DYNAMIC
+ $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
+endif
+
+remove:
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+
+clean:
+ rm -f $(LIBOBJD) $(LIBOBJS) core *~
+
+extraclean: clean
+ rm -f *.a *.o *.so *.bak dynamic/* static/*
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+else
+
+include ../dont_makefile
+
+endif
diff --git a/modules/pam_radius/README b/modules/pam_radius/README
new file mode 100644
index 00000000..253308fd
--- /dev/null
+++ b/modules/pam_radius/README
@@ -0,0 +1,58 @@
+
+pam_radius module:
+ RADIUS session module.
+
+WHAT IT DOES:
+ This module is intended to provide the session service for users
+autheticated with a RADIUS server. At the present stage, the only option
+supported is the use of the RADIUS server as an accounting server. There are
+few things which needs to be cleared out first in the PAM project until one
+will be able to use this module and expect it to magically start pppd in
+response to a RADIUS server command to use PPP for this user, or to initiate
+a telnet connection to another host, or to hang and call back the user using
+parameters provided in the RADIUS server response. Most of these things are
+better suited for the radius login application. I hope to make available
+Real Soon (tm) patches for the login apps to make it work this way.
+
+
+ARGUMENTS RECOGNIZED:
+ debug verbose logging
+
+MODULE SERVICES PROVIDED:
+ session _open_session and _close_session
+
+ When opening a session, this module sends an Accounting-Start
+message to the RADIUS server, which will log/update/whatever a database for
+this user. On close, an Accounting-Stop message is sent to the RADIUS
+server.
+
+This module have no other pre-requisites for making it work. One can install
+a RADIUS server just for fun and use it as a centralized accounting server and
+forget about wtmp/last/sac&comp :-)
+
+USAGE:
+ For the services you need this module (login for example) put
+ the following line in /etc/pam.conf as the last line for that
+ service (usually after the pam_unix session line):
+
+ login session required /lib/security/pam_radius.so
+
+ Replace "login" for each service you are using this module.
+
+ This module make extensive use of the API provided in libpwdb
+ 0.54preB or later. By default, it will read the radius server
+ configuration (hostname and secret) from /etc/raddb/server. This is
+ a default compiled into libpwdb, and curently there is no way to
+ modify this default without recompiling libpwdb. I am working on
+ extending the radius support from libpwdb to provide a possibility
+ to make this runtime-configurable.
+
+ Also please note that libpwdb will require also the RADIUS
+ dictionary to be present (/etc/raddb/dictionary).
+
+TODO:
+ The work is far from complete. Deal with "real" session things.
+
+AUTHOR:
+ Cristian Gafton <gafton@redhat.com>
+
diff --git a/modules/pam_radius/pam_radius.c b/modules/pam_radius/pam_radius.c
new file mode 100644
index 00000000..b412edf9
--- /dev/null
+++ b/modules/pam_radius/pam_radius.c
@@ -0,0 +1,193 @@
+/*
+ * pam_radius
+ * Process an user session according to a RADIUS server response
+ *
+ * 1.0 - initial release - Linux ONLY
+ * 1.1 - revised and reorganized for libpwdb 0.54preB or higher
+ * - removed the conf= parameter, since we use libpwdb exclusively now
+ *
+ * See end for Copyright information
+ */
+
+#if !(defined(linux))
+#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+/* Module defines */
+#define BUFFER_SIZE 1024
+#define LONG_VAL_PTR(ptr) ((*(ptr)<<24)+(*((ptr)+1)<<16)+(*((ptr)+2)<<8)+(*((ptr)+3)))
+
+#define PAM_SM_SESSION
+
+#include "pam_radius.h"
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+static time_t session_time;
+
+/* we need to save these from open_session to close_session, since
+ * when close_session will be called we won't be root anymore and
+ * won't be able to access again the radius server configuration file
+ * -- cristiang */
+
+static RADIUS_SERVER rad_server;
+static char hostname[BUFFER_SIZE];
+static char secret[BUFFER_SIZE];
+
+/* logging */
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("pam_radius", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+
+static int _pam_parse(int argc, const char **argv)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else {
+ _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
+ }
+ }
+
+ return ctrl;
+}
+
+/* now the session stuff */
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval;
+ char *user_name;
+ int ctrl;
+
+ ctrl = _pam_parse(argc, argv);
+ retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ _pam_log(LOG_CRIT, "open_session - error recovering username");
+ return PAM_SESSION_ERR;
+ }
+
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG, "starting RADIUS user session for '%s'",
+ user_name);
+
+ retval = get_server_entries(hostname, secret);
+ if ((retval != PWDB_RADIUS_SUCCESS) ||
+ !strlen(hostname) || !strlen(secret)) {
+ _pam_log(LOG_CRIT, "Could not determine the radius server to talk to");
+ return PAM_IGNORE;
+ }
+ session_time = time(NULL);
+ rad_server.hostname = hostname;
+ rad_server.secret = secret;
+ retval = radius_acct_start(rad_server, user_name);
+ if (retval != PWDB_RADIUS_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server");
+ return PAM_IGNORE;
+ }
+
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int ctrl;
+ char *user_name;
+ int retval;
+
+ ctrl = _pam_parse(argc, argv);
+ retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ _pam_log(LOG_CRIT, "open_session - error recovering username");
+ return PAM_SESSION_ERR;
+ }
+
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG, "closing RADIUS user session for '%s'",
+ user_name);
+
+ if (!strlen(hostname) || !strlen(secret)) {
+ _pam_log(LOG_CRIT, "Could not determine the radius server to talk to");
+ return PAM_IGNORE;
+ }
+ retval = radius_acct_stop(rad_server, user_name,
+ time(NULL) - session_time);
+ if (retval != PWDB_RADIUS_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG, "ERROR communicating with the RADIUS server");
+ return PAM_IGNORE;
+ }
+
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_radius_modstruct = {
+ "pam_radius",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL
+};
+#endif
+
+/*
+ * Copyright (c) Cristian Gafton, 1996, <gafton@redhat.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_radius/pam_radius.h b/modules/pam_radius/pam_radius.h
new file mode 100644
index 00000000..1f860eb5
--- /dev/null
+++ b/modules/pam_radius/pam_radius.h
@@ -0,0 +1,38 @@
+
+#ifndef PAM_RADIUS_H
+#define PAM_RADIUS_H
+
+#define _GNU_SOURCE
+#include <features.h>
+
+#include <stdio.h>
+
+#ifndef __USE_POSIX2
+#define __USE_POSIX2
+#endif /* __USE_POSIX2 */
+
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <utmp.h>
+#include <time.h>
+#include <netdb.h>
+
+#include <netinet/in.h>
+#include <rpcsvc/ypclnt.h>
+#include <rpc/rpc.h>
+
+#include <pwdb/radius.h>
+#include <pwdb/pwdb_radius.h>
+
+/******************************************************************/
+
+#endif /* PAM_RADIUS_H */