194 lines
6.0 KiB
C
194 lines
6.0 KiB
C
|
/*
|
||
|
* 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.
|
||
|
*/
|