aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Hrozek <jakub.hrozek@posteo.se>2015-10-20 15:47:48 +0200
committerAndreas Schneider <asn@samba.org>2015-12-10 13:31:19 +0100
commitcdceeaaf6e83001b260d733492c0014f2255982b (patch)
tree6e9b7b874dc17fd0d18172a9900abd434789f15c
parentbe9fbe4bbdcbf6699ed7e549b3a74e0da275fc79 (diff)
downloadpam_wrapper-cdceeaaf6e83001b260d733492c0014f2255982b.tar.gz
pam_wrapper-cdceeaaf6e83001b260d733492c0014f2255982b.tar.xz
pam_wrapper-cdceeaaf6e83001b260d733492c0014f2255982b.zip
pwrap: Add pam_get_items.so and pam_set_items.so
-rw-r--r--src/CMakeLists.txt26
-rw-r--r--src/modules/pam_get_items.c178
-rw-r--r--src/modules/pam_set_items.c145
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/services/pwrap_get_set.in2
-rw-r--r--tests/test_pam_wrapper.c53
6 files changed, 394 insertions, 12 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b09a78f..1455bb3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -45,25 +45,27 @@ install(
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
)
-add_library(pam_matrix MODULE modules/pam_matrix.c)
-set_property(TARGET pam_matrix PROPERTY PREFIX "")
-
+set(PAM_MODULES pam_matrix pam_get_items pam_set_items)
set(PAM_LIBRARIES
pam
pam_misc)
-target_link_libraries(pam_matrix
- ${PAM_LIBRARIES})
-
set(PWRAP_PRIVATE_LIBRARIES
${LIB_INSTALL_DIR}/pam_wrapper)
-install(
- TARGETS
- pam_matrix
- LIBRARY DESTINATION ${PWRAP_PRIVATE_LIBRARIES}
- ARCHIVE DESTINATION ${PWRAP_PRIVATE_LIBRARIES}
-)
+foreach(_PAM_MODULE ${PAM_MODULES})
+ add_library(${_PAM_MODULE} MODULE modules/${_PAM_MODULE}.c)
+ set_property(TARGET ${_PAM_MODULE} PROPERTY PREFIX "")
+
+ target_link_libraries(${_PAM_MODULE}
+ ${PAM_LIBRARIES})
+
+ install(
+ TARGETS
+ ${_PAM_MODULE}
+ LIBRARY DESTINATION ${PWRAP_PRIVATE_LIBRARIES}
+ ARCHIVE DESTINATION ${PWRAP_PRIVATE_LIBRARIES})
+endforeach()
# This needs to be at the end
if (POLICY CMP0026)
diff --git a/src/modules/pam_get_items.c b/src/modules/pam_get_items.c
new file mode 100644
index 0000000..ec9f70f
--- /dev/null
+++ b/src/modules/pam_get_items.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2015 Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_appl.h>
+
+static const char *str_opt(const int opt)
+{
+ switch (opt) {
+ case PAM_SERVICE:
+ return "PAM_SERVICE";
+ case PAM_USER:
+ return "PAM_USER";
+ case PAM_USER_PROMPT:
+ return "PAM_USER_PROMPT";
+ case PAM_TTY:
+ return "PAM_TTY";
+ case PAM_RUSER:
+ return "PAM_RUSER";
+ case PAM_RHOST:
+ return "PAM_RHOST";
+ case PAM_AUTHTOK:
+ return "PAM_AUTHTOK";
+ case PAM_OLDAUTHTOK:
+ return "PAM_OLDAUTHTOK";
+ case PAM_XDISPLAY:
+ return "PAM_XDISPLAY";
+ case PAM_AUTHTOK_TYPE:
+ return "PAM_AUTHTOK_TYPE";
+ }
+
+ return NULL; /* Unsupported */
+}
+
+static int putenv_item(pam_handle_t *pamh,
+ int item_type)
+{
+ const char *opt_name;
+ const char *value = NULL;
+ char *env_name;
+ size_t env_len;
+ int rv;
+
+ rv = pam_get_item(pamh, item_type, (const void **) &value);
+ if (rv != PAM_SUCCESS) {
+ return rv;
+ }
+
+ if (value == NULL) {
+ return PAM_SUCCESS;
+ }
+
+ opt_name = str_opt(item_type);
+ if (opt_name == NULL) {
+ /* Probably some non-printable value */
+ return PAM_BAD_ITEM;
+ }
+
+ env_len = strlen(value) + strlen(opt_name) + 2;
+ env_name = malloc(env_len);
+ if (env_name == NULL) {
+ return PAM_BUF_ERR;
+ }
+
+ rv = snprintf(env_name, env_len, "%s=%s", opt_name, value);
+ if (rv < 0) {
+ free(env_name);
+ return PAM_BUF_ERR;
+ }
+
+ rv = pam_putenv(pamh, env_name);
+ free(env_name);
+
+ return rv;
+}
+
+/* Get all pam_items and put them into environment */
+static int pam_putitem(pam_handle_t *pamh)
+{
+
+ putenv_item(pamh, PAM_SERVICE);
+ putenv_item(pamh, PAM_USER);
+ putenv_item(pamh, PAM_USER_PROMPT);
+ putenv_item(pamh, PAM_TTY);
+ putenv_item(pamh, PAM_RUSER);
+ putenv_item(pamh, PAM_RHOST);
+ putenv_item(pamh, PAM_AUTHTOK);
+ putenv_item(pamh, PAM_OLDAUTHTOK);
+ putenv_item(pamh, PAM_XDISPLAY);
+ putenv_item(pamh, PAM_AUTHTOK_TYPE);
+
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
+
+PAM_EXTERN int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
+
+PAM_EXTERN int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
+
+PAM_EXTERN int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
+
+PAM_EXTERN int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ return pam_putitem(pamh);
+}
diff --git a/src/modules/pam_set_items.c b/src/modules/pam_set_items.c
new file mode 100644
index 0000000..0fccf4c
--- /dev/null
+++ b/src/modules/pam_set_items.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 Andreas Schneider <asn@samba.org>
+ * Copyright (c) 2015 Jakub Hrozek <jakub.hrozek@posteo.se>
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_appl.h>
+
+#define ITEM_FILE_KEY "item_file="
+
+static const char *envs[] = {
+ "PAM_SERVICE",
+ "PAM_USER",
+ "PAM_USER_PROMPT",
+ "PAM_TTY",
+ "PAM_RUSER",
+ "PAM_RHOST",
+ "PAM_AUTHTOK",
+ "PAM_OLDAUTHTOK",
+ "PAM_XDISPLAY",
+ "PAM_AUTHTOK_TYPE",
+ NULL
+};
+
+static const int items[] = {
+ PAM_SERVICE,
+ PAM_USER,
+ PAM_USER_PROMPT,
+ PAM_TTY,
+ PAM_RUSER,
+ PAM_RHOST,
+ PAM_AUTHTOK,
+ PAM_OLDAUTHTOK,
+ PAM_XDISPLAY,
+ PAM_AUTHTOK_TYPE,
+};
+
+static void pam_setitem_env(pam_handle_t *pamh)
+{
+ int i;
+ int rv;
+ const char *v;
+
+ for (i = 0; envs[i] != NULL; i++) {
+ v = getenv(envs[i]);
+ if (v == NULL) {
+ continue;
+ }
+
+ rv = pam_set_item(pamh, items[i], v);
+ if (rv != PAM_SUCCESS) {
+ continue;
+ }
+ }
+}
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ (void) flags; /* unused */
+ (void) argc; /* unused */
+ (void) argv; /* unused */
+
+ pam_setitem_env(pamh);
+ return PAM_SUCCESS;
+}
+
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c53090c..59db52b 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -15,6 +15,8 @@ set(PASSDB_PATH
configure_file(passdb_ro ${PASSDB_PATH} @ONLY)
configure_file(services/pwrap_pam_opt.in ${CMAKE_CURRENT_BINARY_DIR}/services/pwrap_pam_opt @ONLY)
+configure_file(services/pwrap_get_set.in ${CMAKE_CURRENT_BINARY_DIR}/services/pwrap_get_set @ONLY)
+
if (OSX)
set(TEST_ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${PAM_WRAPPER_LOCATION};PAM_WRAPPER=1;PAM_WRAPPER_CONFDIR=${CMAKE_CURRENT_BINARY_DIR}/services})
add_definitions(-DOSX)
diff --git a/tests/services/pwrap_get_set.in b/tests/services/pwrap_get_set.in
new file mode 100644
index 0000000..48809b9
--- /dev/null
+++ b/tests/services/pwrap_get_set.in
@@ -0,0 +1,2 @@
+session required @CMAKE_CURRENT_BINARY_DIR@/../src/pam_set_items.so
+session required @CMAKE_CURRENT_BINARY_DIR@/../src/pam_get_items.so
diff --git a/tests/test_pam_wrapper.c b/tests/test_pam_wrapper.c
index d34b097..69d95b6 100644
--- a/tests/test_pam_wrapper.c
+++ b/tests/test_pam_wrapper.c
@@ -619,6 +619,58 @@ static void test_pam_vsyslog(void **state)
pam_syslog(test_ctx->ph, LOG_INFO, "This is pam_wrapper test\n");
}
+#define test_setenv(env) setenv(env, "test_"env, 1)
+
+#define test_getenv(envlist, key) do { \
+ const char *__v; \
+ __v = string_in_list(envlist, key); \
+ assert_non_null(__v); \
+ assert_string_equal(__v, "test_"key); \
+} while(0);
+
+static void test_get_set(void **state)
+{
+ const char *svc;
+ enum pamtest_err perr;
+ struct pamtest_case tests[] = {
+ { PAMTEST_OPEN_SESSION, PAM_SUCCESS, 0, 0 },
+ { PAMTEST_GETENVLIST, PAM_SUCCESS, 0, 0 },
+ { PAMTEST_SENTINEL, 0, 0, 0 },
+ };
+
+ (void) state; /* unused */
+
+ test_setenv("PAM_SERVICE");
+ test_setenv("PAM_USER");
+ test_setenv("PAM_USER_PROMPT");
+ test_setenv("PAM_TTY");
+ test_setenv("PAM_RUSER");
+ test_setenv("PAM_RHOST");
+ test_setenv("PAM_AUTHTOK");
+ test_setenv("PAM_OLDAUTHTOK");
+ test_setenv("PAM_XDISPLAY");
+ test_setenv("PAM_AUTHTOK_TYPE");
+
+ perr = pamtest("pwrap_get_set", "testuser", NULL, tests);
+ assert_int_equal(perr, PAMTEST_ERR_OK);
+
+ /* PAM_SERVICE is a special case, libpam lowercases it */
+ svc = string_in_list(tests[1].case_out.envlist, "PAM_SERVICE");
+ assert_non_null(svc);
+ assert_string_equal(svc, "test_pam_service");
+
+ //test_getenv(tests[1].case_out.envlist, "PAM_SERVICE");
+ test_getenv(tests[1].case_out.envlist, "PAM_USER");
+ test_getenv(tests[1].case_out.envlist, "PAM_USER_PROMPT");
+ test_getenv(tests[1].case_out.envlist, "PAM_TTY");
+ test_getenv(tests[1].case_out.envlist, "PAM_RUSER");
+ test_getenv(tests[1].case_out.envlist, "PAM_RHOST");
+ test_getenv(tests[1].case_out.envlist, "PAM_AUTHTOK");
+ test_getenv(tests[1].case_out.envlist, "PAM_OLDAUTHTOK");
+ test_getenv(tests[1].case_out.envlist, "PAM_XDISPLAY");
+ test_getenv(tests[1].case_out.envlist, "PAM_AUTHTOK_TYPE");
+}
+
int main(void) {
int rc;
@@ -669,6 +721,7 @@ int main(void) {
cmocka_unit_test_setup_teardown(test_pam_vsyslog,
setup_noconv,
teardown),
+ cmocka_unit_test(test_get_set),
};
rc = cmocka_run_group_tests(init_tests, NULL, NULL);