The branch, master has been updated via 4ef299e Bump version to 1.1.1 via fbb0f45 gitlab-ci: Work around a Python 3.8 bug via 3f0088a gitlab-ci: Add ubuntu target via 97fdcec pwrap: Add back pso_copy for openSUSE Tumbleweed via 9b43dad cmake: Check for pam_modutil_search_key via c7ab357 pwrap: Use PSO_COPY_READ_SIZE in pso_copy() via 1f22429 Revert "pwrap: Fix pso_copy to work with libpam.so.0.84.2" via 0452102 pwrap: Create two pwrap_init() functions via c559f8d pwrap: Log the return code of pam_start() via 345596e pwrap: Improve debug message in p_rmdirs_at() via 26be2b9 pwrap: Initialize pointers with NULL in p_rmdirs_at() via ffca010 tests: Define PAM_AUTH_ERROR in init function via 36fe0f3 tests: Workaround an off-by-one error in FreeBSD from d247d7a Bump version to 1.1.0
https://git.samba.org/?p=pam_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4ef299e83efc09006ca485162c3bb692c003e1dd Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 08:52:19 2020 +0100 Bump version to 1.1.1 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit fbb0f4515f456d851f77eeb6e8f96370d2dc5855 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 08:08:50 2020 +0100 gitlab-ci: Work around a Python 3.8 bug Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 3f0088a09ee3bab5d66ac703271a9381e1828017 Author: Andreas Schneider <a...@samba.org> Date: Mon Mar 23 18:49:27 2020 +0100 gitlab-ci: Add ubuntu target Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 97fdcec92ee34cf061222e3d12c2624ec7ab4ff7 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 07:32:06 2020 +0100 pwrap: Add back pso_copy for openSUSE Tumbleweed Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 9b43dad109b0e66247a7c909d5cc96bade3cea56 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 07:22:37 2020 +0100 cmake: Check for pam_modutil_search_key Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit c7ab357a0c24d48ddd521c282af4eeec016b2eb4 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 11:19:36 2020 +0100 pwrap: Use PSO_COPY_READ_SIZE in pso_copy() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 1f224299e46a44473c42eab06a8fcc369fb3c8f2 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 07:05:28 2020 +0100 Revert "pwrap: Fix pso_copy to work with libpam.so.0.84.2" This reverts commit 047e9fb616d21e202add9f16347cea2084444104. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 045210208d5dfc8b4e41735eeb73165d4a37990e Author: Andreas Schneider <a...@samba.org> Date: Mon Mar 23 17:44:22 2020 +0100 pwrap: Create two pwrap_init() functions One for pam_start() and one for pam_start_confdir() support. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit c559f8d98331ecfa7c32396556fac040c61b7e55 Author: Andreas Schneider <a...@samba.org> Date: Mon Mar 23 17:47:16 2020 +0100 pwrap: Log the return code of pam_start() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 345596e3fdf6d0c94a36f36568766c0534ab082b Author: Andreas Schneider <a...@samba.org> Date: Mon Mar 23 17:39:57 2020 +0100 pwrap: Improve debug message in p_rmdirs_at() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 26be2b9b8d99ca5aaa05b082765785179a9ba494 Author: Andreas Schneider <a...@samba.org> Date: Mon Mar 23 17:34:37 2020 +0100 pwrap: Initialize pointers with NULL in p_rmdirs_at() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit ffca0103fceb9d283eb36f175cb76597183de255 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 08:37:24 2020 +0100 tests: Define PAM_AUTH_ERROR in init function Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 36fe0f34041ba04f5cfe2f39ee28ebcb7cda3ca6 Author: Andreas Schneider <a...@samba.org> Date: Tue Mar 24 07:39:10 2020 +0100 tests: Workaround an off-by-one error in FreeBSD https://www.openpam.org/wiki/Errata/2019-02-22 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: .gitlab-ci.yml | 27 ++++- CHANGELOG | 4 + CMakeLists.txt | 4 +- ConfigureChecks.cmake | 3 + config.h.cmake | 1 + src/pam_wrapper.c | 294 ++++++++++++++++++++++++++++++++++++++++++----- tests/pypamtest_test.py | 14 ++- tests/test_pam_wrapper.c | 20 ++++ 8 files changed, 328 insertions(+), 39 deletions(-) Changeset truncated at 500 lines: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 440521d..839c834 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ variables: FEDORA_BUILD: buildenv-fedora CENTOS7_BUILD: buildenv-centos7 TUMBLEWEED_BUILD: buildenv-tumbleweed + UBUNTU_BUILD: buildenv-ubuntu centos7/x86_64: image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS7_BUILD @@ -169,13 +170,15 @@ tumbleweed/x86_64/gcc7: paths: - obj/ +# PICKY_DEVELOPER IS OFF +# => https://github.com/python/cpython/pull/19133 tumbleweed/x86_64/clang: image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: - mkdir -p obj && cd obj && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ - -DPICKY_DEVELOPER=ON + -DPICKY_DEVELOPER=OFF -DUNIT_TESTING=ON .. && make -j$(nproc) && ctest --output-on-failure tags: @@ -188,6 +191,8 @@ tumbleweed/x86_64/clang: paths: - obj/ +# PICKY_DEVELOPER IS OFF +# => https://github.com/python/cpython/pull/19133 tumbleweed/static-analysis: image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD script: @@ -196,7 +201,7 @@ tumbleweed/static-analysis: - mkdir -p obj && cd obj && scan-build cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ - -DPICKY_DEVELOPER=ON + -DPICKY_DEVELOPER=OFF -DUNIT_TESTING=ON .. && scan-build --status-bugs -o scan make -j$(nproc) tags: @@ -208,3 +213,21 @@ tumbleweed/static-analysis: when: on_failure paths: - obj/scan + +ubuntu/x86_64: + image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$UBUNTU_BUILD + script: + - mkdir -p obj && cd obj && cmake + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DPICKY_DEVELOPER=ON + -DUNIT_TESTING=ON .. && + make -j$(nproc) && ctest --output-on-failure + tags: + - shared + except: + - tags + artifacts: + expire_in: 1 week + when: on_failure + paths: + - obj/ diff --git a/CHANGELOG b/CHANGELOG index ac94d0f..86bdfb4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ ChangeLog ========== +version 1.1.1 (released 2020-03-24) + * Fixed pam_wrapper on Ubuntu + * Improved PAM detection for openSUSE Tumbleweed + version 1.1.0 (released 2020-03-20) * Added support for pam_start_confdir() * Added pam_chatty module diff --git a/CMakeLists.txt b/CMakeLists.txt index 216699f..c5ff40b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") include(DefineCMakeDefaults) include(DefineCompilerFlags) -project(pam_wrapper VERSION 1.1.0 LANGUAGES C) +project(pam_wrapper VERSION 1.1.1 LANGUAGES C) # global needed variables set(APPLICATION_NAME ${PROJECT_NAME}) @@ -25,7 +25,7 @@ set(APPLICATION_NAME ${PROJECT_NAME}) # Increment PATCH. set(LIBRARY_VERSION_MAJOR 0) set(LIBRARY_VERSION_MINOR 0) -set(LIBRARY_VERSION_PATCH 5) +set(LIBRARY_VERSION_PATCH 6) set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(LIBRARY_SOVERSION ${LIBRARY_VERSION_MAJOR}) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 1d5ca9a..8dcf978 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -77,6 +77,9 @@ set(CMAKE_REQUIRED_LIBRARIES ${PAM_LIBRARY}) check_function_exists(pam_syslog HAVE_PAM_SYSLOG) check_function_exists(pam_vsyslog HAVE_PAM_VSYSLOG) check_function_exists(pam_start_confdir HAVE_PAM_START_CONFDIR) +# This is available in current PAM master and will be used as a workaround +# till pam_start_confdir() is available. +check_function_exists(pam_modutil_search_key HAVE_PAM_MODUTIL_SEARCH_KEY) unset(CMAKE_REQUIRED_LIBRARIES) # OPTIONS diff --git a/config.h.cmake b/config.h.cmake index 4e74315..01a54f3 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -21,6 +21,7 @@ #cmakedefine HAVE_PAM_VSYSLOG 1 #cmakedefine HAVE_PAM_SYSLOG 1 #cmakedefine HAVE_PAM_START_CONFDIR 1 +#cmakedefine HAVE_PAM_MODUTIL_SEARCH_KEY 1 #cmakedefine HAVE_PAM_VPROMPT_CONST 1 #cmakedefine HAVE_PAM_PROMPT_CONST 1 diff --git a/src/pam_wrapper.c b/src/pam_wrapper.c index a02523b..dd69c43 100644 --- a/src/pam_wrapper.c +++ b/src/pam_wrapper.c @@ -804,7 +804,141 @@ static void pwrap_clean_stale_dirs(const char *dir) return; } -#ifndef HAVE_PAM_START_CONFDIR +#ifdef HAVE_PAM_START_CONFDIR +static void pwrap_init(void) +{ + char tmp_config_dir[] = "/tmp/pam.X"; + size_t len = strlen(tmp_config_dir); + const char *env; + struct stat sb; + int rc; + unsigned i; + ssize_t ret; + FILE *pidfile; + char pidfile_path[1024] = { 0 }; + char letter; + + if (!pam_wrapper_enabled()) { + return; + } + + if (pwrap.initialised) { + return; + } + + /* + * The name is selected to match/replace /etc/pam.d + * We start from a random alphanum trying letters until + * an available directory is found. + */ + letter = 48 + (getpid() % 70); + for (i = 0; i < 127; i++) { + if (isalpha(letter) || isdigit(letter)) { + tmp_config_dir[len - 1] = letter; + + rc = lstat(tmp_config_dir, &sb); + if (rc == 0) { + PWRAP_LOG(PWRAP_LOG_TRACE, + "Check if pam_wrapper dir %s is a " + "stale directory", + tmp_config_dir); + pwrap_clean_stale_dirs(tmp_config_dir); + } else if (rc < 0) { + if (errno != ENOENT) { + continue; + } + break; /* found */ + } + } + + letter++; + letter %= 127; + } + + if (i == 127) { + PWRAP_LOG(PWRAP_LOG_ERROR, + "Failed to find a possible path to create " + "pam_wrapper config dir: %s", + tmp_config_dir); + exit(1); + } + + PWRAP_LOG(PWRAP_LOG_DEBUG, "Initialize pam_wrapper"); + + pwrap.config_dir = strdup(tmp_config_dir); + if (pwrap.config_dir == NULL) { + PWRAP_LOG(PWRAP_LOG_ERROR, + "No memory"); + exit(1); + } + PWRAP_LOG(PWRAP_LOG_TRACE, + "pam_wrapper config dir: %s", + tmp_config_dir); + + rc = mkdir(pwrap.config_dir, 0755); + if (rc != 0) { + PWRAP_LOG(PWRAP_LOG_ERROR, + "Failed to create pam_wrapper config dir: %s - %s", + tmp_config_dir, strerror(errno)); + } + + /* Create file with the PID of the the process */ + ret = snprintf(pidfile_path, sizeof(pidfile_path), + "%s/pid", pwrap.config_dir); + if (ret < 0) { + p_rmdirs(pwrap.config_dir); + exit(1); + } + + pidfile = fopen(pidfile_path, "w"); + if (pidfile == NULL) { + p_rmdirs(pwrap.config_dir); + exit(1); + } + + rc = fprintf(pidfile, "%d", getpid()); + fclose(pidfile); + if (rc <= 0) { + p_rmdirs(pwrap.config_dir); + exit(1); + } + + pwrap.libpam_so = strdup(PAM_LIBRARY); + if (pwrap.libpam_so == NULL) { + PWRAP_LOG(PWRAP_LOG_ERROR, "No memory"); + p_rmdirs(pwrap.config_dir); + exit(1); + } + + PWRAP_LOG(PWRAP_LOG_TRACE, "Using libpam path: %s", pwrap.libpam_so); + + pwrap.initialised = true; + + env = getenv("PAM_WRAPPER_SERVICE_DIR"); + if (env == NULL) { + PWRAP_LOG(PWRAP_LOG_ERROR, "No config file"); + p_rmdirs(pwrap.config_dir); + exit(1); + } + + rc = copy_confdir(env); + if (rc != 0) { + PWRAP_LOG(PWRAP_LOG_ERROR, "Failed to copy config files"); + p_rmdirs(pwrap.config_dir); + exit(1); + } + + setenv("PAM_WRAPPER_RUNTIME_DIR", pwrap.config_dir, 1); + + PWRAP_LOG(PWRAP_LOG_DEBUG, "Successfully initialized pam_wrapper"); +} + +#else /* HAVE_PAM_START_CONFDIR */ + +#ifdef HAVE_PAM_MODUTIL_SEARCH_KEY +/* + * This is needed to workaround Tumbleweed which packages a libpam git version. + */ static int pso_copy(const char *src, const char *dst, const char *pdir, mode_t mode) { #define PSO_COPY_READ_SIZE 16 @@ -923,7 +1057,104 @@ out: return rc; #undef PSO_COPY_READ_SIZE } -#endif /* HAVE_PAM_START_CONFDIR */ +#else /* HAVE_PAM_MODUTIL_SEARCH_KEY */ + +static int pso_copy(const char *src, const char *dst, const char *pdir, mode_t mode) +{ +#define PSO_COPY_READ_SIZE 9 + int srcfd = -1; + int dstfd = -1; + int rc = -1; + ssize_t bread, bwritten; + struct stat sb; + char buf[PSO_COPY_READ_SIZE + 1]; + int cmp; + size_t to_read; + bool found_slash; + + cmp = strcmp(src, dst); + if (cmp == 0) { + return -1; + } + + srcfd = open(src, O_RDONLY, 0); + if (srcfd < 0) { + return -1; + } + + if (mode == 0) { + rc = fstat(srcfd, &sb); + if (rc != 0) { + rc = -1; + goto out; + } + mode = sb.st_mode; + } + + dstfd = open(dst, O_CREAT|O_WRONLY|O_TRUNC, mode); + if (dstfd < 0) { + rc = -1; + goto out; + } + + found_slash = false; + to_read = 1; + + for (;;) { + bread = read(srcfd, buf, to_read); + if (bread == 0) { + /* done */ + break; + } else if (bread < 0) { + errno = EIO; + rc = -1; + goto out; + } + + to_read = 1; + if (!found_slash && buf[0] == '/') { + found_slash = true; + to_read = PSO_COPY_READ_SIZE; + } + + if (found_slash && bread == PSO_COPY_READ_SIZE) { + cmp = memcmp(buf, "etc/pam.d", PSO_COPY_READ_SIZE); + if (cmp == 0) { + memcpy(buf, pdir + 1, PSO_COPY_READ_SIZE); + } + found_slash = false; + } + + bwritten = write(dstfd, buf, bread); + if (bwritten < 0) { + errno = EIO; + rc = -1; + goto out; + } + + if (bread != bwritten) { + errno = EFAULT; + rc = -1; + goto out; + } + } + + rc = 0; +out: + if (srcfd != -1) { + close(srcfd); + } + if (dstfd != -1) { + close(dstfd); + } + if (rc < 0) { + unlink(dst); + } + + return rc; +#undef PSO_COPY_READ_SIZE +} +#endif /* HAVE_PAM_MODUTIL_SEARCH_KEY */ static void pwrap_init(void) { @@ -933,10 +1164,8 @@ static void pwrap_init(void) struct stat sb; int rc; unsigned i; -#ifndef HAVE_PAM_START_CONFDIR char pam_library[128] = { 0 }; char libpam_path[1024] = { 0 }; -#endif ssize_t ret; FILE *pidfile; char pidfile_path[1024] = { 0 }; @@ -1027,14 +1256,6 @@ static void pwrap_init(void) exit(1); } -#ifdef HAVE_PAM_START_CONFDIR - pwrap.libpam_so = strdup(PAM_LIBRARY); - if (pwrap.libpam_so == NULL) { - PWRAP_LOG(PWRAP_LOG_ERROR, "No memory"); - p_rmdirs(pwrap.config_dir); - exit(1); - } -#else /* HAVE_PAM_START_CONFDIR */ /* create lib subdirectory */ snprintf(libpam_path, sizeof(libpam_path), @@ -1119,7 +1340,6 @@ static void pwrap_init(void) p_rmdirs(pwrap.config_dir); exit(1); } -#endif /* HAVE_PAM_START_CONFDIR */ PWRAP_LOG(PWRAP_LOG_TRACE, "Using libpam path: %s", pwrap.libpam_so); @@ -1143,6 +1363,7 @@ static void pwrap_init(void) PWRAP_LOG(PWRAP_LOG_DEBUG, "Successfully initialized pam_wrapper"); } +#endif /* HAVE_PAM_START_CONFDIR */ bool pam_wrapper_enabled(void) { @@ -1222,6 +1443,8 @@ static int pwrap_pam_start(const char *service_name, const struct pam_conv *pam_conversation, pam_handle_t **pamh) { + int rc; + pwrap_init(); PWRAP_LOG(PWRAP_LOG_TRACE, @@ -1230,22 +1453,25 @@ static int pwrap_pam_start(const char *service_name, user); #if defined(HAVE_OPENPAM) - return pwrap_openpam_start(service_name, - user, - pam_conversation, - pamh); + rc = pwrap_openpam_start(service_name, + user, + pam_conversation, + pamh); #elif defined (HAVE_PAM_START_CONFDIR) - return libpam_pam_start_confdir(service_name, - user, - pam_conversation, - pwrap.config_dir, - pamh); + rc = libpam_pam_start_confdir(service_name, + user, + pam_conversation, + pwrap.config_dir, + pamh); #else - return libpam_pam_start(service_name, - user, - pam_conversation, - pamh); + rc = libpam_pam_start(service_name, + user, + pam_conversation, + pamh); #endif + PWRAP_LOG(PWRAP_LOG_TRACE, "pam_start rc=%d", rc); + + return rc; } @@ -1821,15 +2047,25 @@ void pwrap_constructor(void) static int p_rmdirs_at(const char *path, int parent_fd) { - DIR *d; - struct dirent *dp; + DIR *d = NULL; + struct dirent *dp = NULL; struct stat sb; + char fd_str[64] = { 0 }; int path_fd; int rc; + switch(parent_fd) { + case AT_FDCWD: + snprintf(fd_str, sizeof(fd_str), "CWD"); + break; + default: + snprintf(fd_str, sizeof(fd_str), "fd=%d", parent_fd); + break; + } + /* If path is absolute, parent_fd is ignored. */ PWRAP_LOG(PWRAP_LOG_TRACE, - "p_rmdirs_at removing %s at %d\n", path, parent_fd); -- pam wrapper repository