From 1bfa6e76484cb41af476183166d4498f9638b752 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 17 Sep 2015 15:43:08 +0200 Subject: [PATCH] Reinstated the PAM accounting method It can be used to check for a valid PAM account, even when certificates or another authentication method is in use. --- doc/sample.config | 3 ++ src/Makefile.am | 2 +- src/acct/pam.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ src/acct/pam.h | 28 ++++++++++++++ src/config.c | 5 ++- src/ocserv-args.def | 3 ++ 6 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/acct/pam.c create mode 100644 src/acct/pam.h diff --git a/doc/sample.config b/doc/sample.config index acf9f67c..c7dd5ace 100644 --- a/doc/sample.config +++ b/doc/sample.config @@ -51,6 +51,9 @@ auth = "plain[passwd=./sample.passwd]" # radius: can be combined with any authentication method, it provides # radius accounting to available users (see also stats-report-time). # +# pam: can be combined with any authentication method, it provides +# a validation of the connecting user's name using PAM. +# # Only one accounting method can be specified. #acct = "radius[config=/etc/radiusclient/radiusclient.conf]" diff --git a/src/Makefile.am b/src/Makefile.am index bc29a91d..c4793722 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -67,7 +67,7 @@ AUTH_SOURCES=auth/pam.c auth/pam.h auth/plain.c auth/plain.h auth/radius.c auth/ auth/common.c auth/common.h auth/gssapi.h auth/gssapi.c auth-unix.c \ auth-unix.h -ACCT_SOURCES=acct/radius.c acct/radius.h +ACCT_SOURCES=acct/radius.c acct/radius.h acct/pam.c acct/pam.h ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ cookies.c main-misc.c ip-lease.c ip-lease.h \ diff --git a/src/acct/pam.c b/src/acct/pam.c new file mode 100644 index 00000000..fa46e19c --- /dev/null +++ b/src/acct/pam.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2013 Nikos Mavrogiannopoulos + * + * This file is part of ocserv. + * + * ocserv is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * ocserv is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "pam.h" +#include + +#ifdef HAVE_PAM + +#include +#include +#include +#include +#include +#include +#include "auth/pam.h" + +static int ocserv_conv(int msg_size, const struct pam_message **msg, + struct pam_response **resp, void *uptr) +{ + *resp = NULL; + return PAM_SUCCESS; +} + +static int pam_acct_open_session(unsigned auth_method, void *ctx, const struct common_auth_info_st *ai, const void *sid, unsigned sid_size) +{ +int pret; +pam_handle_t *ph; +struct pam_conv dc; + + if (ai->username[0] == 0) { + syslog(LOG_AUTH, + "PAM-acct: no username present"); + return ERR_AUTH_FAIL; + } + + dc.conv = ocserv_conv; + dc.appdata_ptr = NULL; + pret = pam_start(PACKAGE, ai->username, &dc, &ph); + if (pret != PAM_SUCCESS) { + syslog(LOG_AUTH, "PAM-acct init: %s", pam_strerror(ph, pret)); + goto fail1; + } + + pret = pam_acct_mgmt(ph, PAM_DISALLOW_NULL_AUTHTOK); + if (pret != PAM_SUCCESS) { + syslog(LOG_INFO, "PAM-acct account error: %s", pam_strerror(ph, pret)); + goto fail2; + } + + pam_end(ph, pret); + return 0; + +fail2: + pam_end(ph, pret); +fail1: + return -1; + +} + +static void pam_acct_close_session(unsigned auth_method, void *ctx, const struct common_auth_info_st *ai, stats_st *stats, unsigned status) +{ + return; +} + +const struct acct_mod_st pam_acct_funcs = { + .type = ACCT_TYPE_PAM, + .auth_types = ALL_AUTH_TYPES, + .open_session = pam_acct_open_session, + .close_session = pam_acct_close_session, +}; + +#endif diff --git a/src/acct/pam.h b/src/acct/pam.h new file mode 100644 index 00000000..1ab10a7f --- /dev/null +++ b/src/acct/pam.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of ocserv. + * + * The GnuTLS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + */ +#ifndef ACCT_PAM_H +#define ACCT_PAM_H + +#include + +extern const struct acct_mod_st pam_acct_funcs; + +#endif diff --git a/src/config.c b/src/config.c index 2032d157..ba14a357 100644 --- a/src/config.c +++ b/src/config.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -466,7 +467,9 @@ static acct_types_st avail_acct_types[] = #ifdef HAVE_RADIUS {NAME("radius"), &radius_acct_funcs, radius_get_brackets_string}, #endif - {NAME("pam"), NULL, NULL} +#ifdef HAVE_PAM + {NAME("pam"), &pam_acct_funcs, NULL}, +#endif }; static void figure_acct_funcs(struct perm_cfg_st *config, const char *acct) diff --git a/src/ocserv-args.def b/src/ocserv-args.def index b680d6ff..9769df5c 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -133,6 +133,9 @@ An example configuration file follows. # radius: can be combined with any authentication method, it provides # radius accounting to available users (see also stats-report-time). # +# pam: can be combined with any authentication method, it provides +# a validation of the connecting user's name using PAM. +# # Only one accounting method can be specified. #acct = "radius[config=/etc/radiusclient/radiusclient.conf]"