4 * This function provides a thread safer version of getpwuid() for use
5 * with PAM modules that care about this sort of thing.
7 * XXX - or at least it should provide a thread-safe alternative.
10 #include "pammodutil.h"
18 static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER;
19 static void _pammodutil_lock(void)
21 pthread_mutex_lock(&_pammodutil_mutex);
23 static void _pammodutil_unlock(void)
25 pthread_mutex_unlock(&_pammodutil_mutex);
28 static int intlen(int number)
38 static int longlen(long number)
48 struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid)
50 #ifdef HAVE_GETPWUID_R
53 size_t length = PWD_INITIAL_LENGTH;
58 struct passwd *result = NULL;
60 new_buffer = realloc(buffer, sizeof(struct passwd) + length);
61 if (new_buffer == NULL) {
65 /* no memory for the user - so delete the memory */
73 /* make the re-entrant call to get the pwd structure */
74 status = getpwuid_r(uid, buffer,
75 sizeof(struct passwd) + (char *) buffer,
77 if (!status && (result == buffer)) {
82 data_name = malloc(strlen("_pammodutil_getpwuid") + 1 +
83 longlen((long) uid) + 1 + intlen(INT_MAX) + 1);
84 if ((pamh != NULL) && (data_name == NULL)) {
85 D(("was unable to register the data item [%s]",
86 pam_strerror(pamh, status)));
92 for (i = 0; i < INT_MAX; i++) {
93 sprintf(data_name, "_pammodutil_getpwuid_%ld_%d",
96 status = PAM_NO_MODULE_DATA;
97 if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
98 status = pam_set_data(pamh, data_name,
99 result, _pammodutil_cleanup);
101 _pammodutil_unlock();
102 if (status == PAM_SUCCESS) {
107 status = PAM_SUCCESS;
112 if (status == PAM_SUCCESS) {
117 D(("was unable to register the data item [%s]",
118 pam_strerror(pamh, status)));
127 } while (length < PWD_ABSURD_PWD_LENGTH);
129 D(("pwd structure took %u bytes or so of memory",
130 length+sizeof(struct passwd)));
135 #else /* ie. ifndef HAVE_GETPWUID_R */
138 * Sorry, there does not appear to be a reentrant version of
139 * getpwuid(). So, we use the standard libc function.
142 return getpwuid(uid);
144 #endif /* def HAVE_GETPWUID_R */