diff options
author | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:47:05 -0800 |
---|---|---|
committer | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:47:05 -0800 |
commit | 4c51da22e068907adb7857d50f5109a467c94d7c (patch) | |
tree | becf5fbae5dfcbe8896355f59042dc8eaefa7f37 /Linux-PAM/modules/pammodutil/modutil_getpwnam.c | |
parent | efd31890b5ed496a5a00c08a262da240e66a4ddc (diff) | |
parent | ab9e8ba11f464fc083fc65a0bc695d60ebc86f3e (diff) | |
download | pam-4c51da22e068907adb7857d50f5109a467c94d7c.tar.gz pam-4c51da22e068907adb7857d50f5109a467c94d7c.tar.bz2 pam-4c51da22e068907adb7857d50f5109a467c94d7c.zip |
New upstream version 0.79
Diffstat (limited to 'Linux-PAM/modules/pammodutil/modutil_getpwnam.c')
-rw-r--r-- | Linux-PAM/modules/pammodutil/modutil_getpwnam.c | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/Linux-PAM/modules/pammodutil/modutil_getpwnam.c b/Linux-PAM/modules/pammodutil/modutil_getpwnam.c index e3a8f270..eb359544 100644 --- a/Linux-PAM/modules/pammodutil/modutil_getpwnam.c +++ b/Linux-PAM/modules/pammodutil/modutil_getpwnam.c @@ -1,5 +1,5 @@ /* - * $Id: modutil_getpwnam.c,v 1.1.1.1 2002/09/15 20:09:04 hartmans Exp $ + * $Id: modutil_getpwnam.c,v 1.4 2005/03/30 14:59:41 kukuk Exp $ * * This function provides a thread safer version of getpwnam() for use * with PAM modules that care about this sort of thing. @@ -9,9 +9,33 @@ #include "pammodutil.h" +#include <errno.h> +#include <limits.h> +#include <pthread.h> #include <pwd.h> +#include <stdio.h> #include <stdlib.h> +static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER; +static void _pammodutil_lock(void) +{ + pthread_mutex_lock(&_pammodutil_mutex); +} +static void _pammodutil_unlock(void) +{ + pthread_mutex_unlock(&_pammodutil_mutex); +} + +static int intlen(int number) +{ + int len = 2; + while (number != 0) { + number /= 10; + len++; + } + return len; +} + struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) { #ifdef HAVE_GETPWNAM_R @@ -38,12 +62,44 @@ struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) buffer = new_buffer; /* make the re-entrant call to get the pwd structure */ + errno = 0; status = getpwnam_r(user, buffer, sizeof(struct passwd) + (char *) buffer, length, &result); - if (!status && result) { - status = pam_set_data(pamh, "_pammodutil_getpwnam", result, - _pammodutil_cleanup); + if (!status && (result == buffer)) { + char *data_name; + const void *ignore; + int i; + + data_name = malloc(strlen("_pammodutil_getpwnam") + 1 + + strlen(user) + 1 + intlen(INT_MAX) + 1); + if ((pamh != NULL) && (data_name == NULL)) { + D(("was unable to register the data item [%s]", + pam_strerror(pamh, status))); + free(buffer); + return NULL; + } + + if (pamh != NULL) { + for (i = 0; i < INT_MAX; i++) { + sprintf(data_name, "_pammodutil_getpwnam_%s_%d", user, i); + _pammodutil_lock(); + status = PAM_NO_MODULE_DATA; + if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) { + status = pam_set_data(pamh, data_name, + result, _pammodutil_cleanup); + } + _pammodutil_unlock(); + if (status == PAM_SUCCESS) { + break; + } + } + } else { + status = PAM_SUCCESS; + } + + free(data_name); + if (status == PAM_SUCCESS) { D(("success")); return result; @@ -55,9 +111,12 @@ struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) free(buffer); return NULL; - } + } else if (errno != ERANGE && errno != EINTR) { + /* no sense in repeating the call */ + break; + } - length <<= 1; + length <<= 2; } while (length < PWD_ABSURD_PWD_LENGTH); |