diff options
Diffstat (limited to 'modules/pammodutil')
-rw-r--r-- | modules/pammodutil/Makefile | 3 | ||||
-rw-r--r-- | modules/pammodutil/include/security/_pam_modutil.h | 27 | ||||
-rw-r--r-- | modules/pammodutil/modutil_getpwnam.c | 60 | ||||
-rw-r--r-- | modules/pammodutil/modutil_getpwuid.c | 79 |
4 files changed, 158 insertions, 11 deletions
diff --git a/modules/pammodutil/Makefile b/modules/pammodutil/Makefile index c1f1b9a7..c9cd0062 100644 --- a/modules/pammodutil/Makefile +++ b/modules/pammodutil/Makefile @@ -19,7 +19,8 @@ CFLAGS += $(PIC) $(STATIC) $(MOREFLAGS) \ # all the object files we care about LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o \ - modutil_getlogin.o modutil_ioloop.o + modutil_getspnam.o modutil_getgrnam.o modutil_getgrgid.o \ + modutil_ingroup.o modutil_getlogin.o modutil_ioloop.o # static library name LIBSTATIC = $(LIBNAME).a diff --git a/modules/pammodutil/include/security/_pam_modutil.h b/modules/pammodutil/include/security/_pam_modutil.h index 5b95e279..c2ac24c2 100644 --- a/modules/pammodutil/include/security/_pam_modutil.h +++ b/modules/pammodutil/include/security/_pam_modutil.h @@ -19,6 +19,8 @@ */ #include <pwd.h> +#include <grp.h> +#include <shadow.h> #include <sys/types.h> extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, @@ -27,6 +29,31 @@ extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, extern struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid); +extern struct group *_pammodutil_getgrnam(pam_handle_t *pamh, + const char *group); + +extern struct group *_pammodutil_getgrgid(pam_handle_t *pamh, + gid_t gid); + +extern struct spwd *_pammodutil_getspnam(pam_handle_t *pamh, + const char *user); + +extern int _pammodutil_user_in_group_nam_nam(pam_handle_t *pamh, + const char *user, + const char *group); + +extern int _pammodutil_user_in_group_nam_gid(pam_handle_t *pamh, + const char *user, + gid_t group); + +extern int _pammodutil_user_in_group_uid_nam(pam_handle_t *pamh, + uid_t user, + const char *group); + +extern int _pammodutil_user_in_group_uid_gid(pam_handle_t *pamh, + uid_t user, + gid_t group); + extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data, int error_status); diff --git a/modules/pammodutil/modutil_getpwnam.c b/modules/pammodutil/modutil_getpwnam.c index 287dc065..891b0b58 100644 --- a/modules/pammodutil/modutil_getpwnam.c +++ b/modules/pammodutil/modutil_getpwnam.c @@ -9,9 +9,32 @@ #include "pammodutil.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 @@ -41,9 +64,40 @@ struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) 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; diff --git a/modules/pammodutil/modutil_getpwuid.c b/modules/pammodutil/modutil_getpwuid.c index e200dd1e..f28ed4e4 100644 --- a/modules/pammodutil/modutil_getpwuid.c +++ b/modules/pammodutil/modutil_getpwuid.c @@ -9,12 +9,45 @@ #include "pammodutil.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; +} + +static int longlen(long number) +{ + int len = 2; + while (number != 0) { + number /= 10; + len++; + } + return len; +} + struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid) { -#ifdef HAVE_GETPWNAM_R +#ifdef HAVE_GETPWUID_R void *buffer=NULL; size_t length = PWD_INITIAL_LENGTH; @@ -41,9 +74,41 @@ struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid) status = getpwuid_r(uid, buffer, sizeof(struct passwd) + (char *) buffer, length, &result); - if (!status && result) { - status = pam_set_data(pamh, "_pammodutil_getpwuid", result, - _pammodutil_cleanup); + if (!status && (result == buffer)) { + char *data_name; + const void *ignore; + int i; + + data_name = malloc(strlen("_pammodutil_getpwuid") + 1 + + longlen((long) uid) + 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_getpwuid_%ld_%d", + (long) uid, 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; @@ -67,14 +132,14 @@ struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid) free(buffer); return NULL; -#else /* ie. ifndef HAVE_GETPWNAM_R */ +#else /* ie. ifndef HAVE_GETPWUID_R */ /* * Sorry, there does not appear to be a reentrant version of - * getpwnam(). So, we use the standard libc function. + * getpwuid(). So, we use the standard libc function. */ return getpwuid(uid); -#endif /* def HAVE_GETPWNAM_R */ +#endif /* def HAVE_GETPWUID_R */ } |