summaryrefslogtreecommitdiff
path: root/modules/pammodutil
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pammodutil')
-rw-r--r--modules/pammodutil/Makefile3
-rw-r--r--modules/pammodutil/include/security/_pam_modutil.h27
-rw-r--r--modules/pammodutil/modutil_getpwnam.c60
-rw-r--r--modules/pammodutil/modutil_getpwuid.c79
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 */
}