diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-02-19 21:23:23 +0100 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2018-02-22 16:03:53 +0100 |
commit | 6bea1e19edf520985776787c3ba3fcea3ca89faa (patch) | |
tree | cd624f2374f708bc4869bb8f559039adbdb5077a | |
parent | 5c36d4284918a3fcc1c58f29f01ca64c65a66fa7 (diff) | |
download | pam_wrapper-6bea1e19edf520985776787c3ba3fcea3ca89faa.tar.gz pam_wrapper-6bea1e19edf520985776787c3ba3fcea3ca89faa.tar.xz pam_wrapper-6bea1e19edf520985776787c3ba3fcea3ca89faa.zip |
pwrap: Use a more unique name for pamdir
Parallel builds fail quite predictable when using libpam_wrapper.
It seems that the temporary directory used are created sequentially
and that caused issues like:
PWRAP_ERROR(8157) - pwrap_load_lib_handle: Failed to dlopen library: /tmp/pam.0/lib/libpam.so.0: cannot open shared object file: No such file or directory
When a directory was cleaned up, incorrectly. I have not pin-pointed
the race condition, but this patch starts from a random letter (using
the PID of the process) in the temporary directory name, providing
better assurances of uniqueness.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
-rw-r--r-- | src/pam_wrapper.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/src/pam_wrapper.c b/src/pam_wrapper.c index 473df4e..69bd9ca 100644 --- a/src/pam_wrapper.c +++ b/src/pam_wrapper.c @@ -34,6 +34,7 @@ #include <libgen.h> #include <signal.h> #include <limits.h> +#include <ctype.h> #include <ftw.h> @@ -760,13 +761,15 @@ static void pwrap_init(void) char tmp_config_dir[] = "/tmp/pam.X"; size_t len = strlen(tmp_config_dir); const char *env; - uint32_t i; + struct stat sb; int rc; + unsigned i; char pam_library[128] = { 0 }; char libpam_path[1024] = { 0 }; ssize_t ret; FILE *pidfile; char pidfile_path[1024] = { 0 }; + char letter; if (!pam_wrapper_enabled()) { return; @@ -776,33 +779,36 @@ static void pwrap_init(void) return; } - PWRAP_LOG(PWRAP_LOG_DEBUG, "Initialize pam_wrapper"); - - for (i = 0; i < 36; i++) { - struct stat sb; - char c; - - if (i < 10) { - c = (char)(i + 48); - } else { - c = (char)(i + 87); + /* + * 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 */ + } } - tmp_config_dir[len - 1] = c; - 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); - continue; - } else if (errno == ENOENT) { - break; - } + letter++; + letter %= 127; } - if (i == 36) { + if (i == 127) { PWRAP_LOG(PWRAP_LOG_ERROR, "Failed to find a possible path to create " "pam_wrapper config dir: %s", @@ -810,6 +816,10 @@ static void pwrap_init(void) exit(1); } + PWRAP_LOG(PWRAP_LOG_DEBUG, "Initialize pam_wrapper"); + + pwrap_clean_stale_dirs(tmp_config_dir); + pwrap.config_dir = strdup(tmp_config_dir); if (pwrap.config_dir == NULL) { PWRAP_LOG(PWRAP_LOG_ERROR, |