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]"