From da67a7d6126846939fd43b1ddb5aa8c06ee09301 Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Sun, 9 Dec 2001 22:15:11 +0000 Subject: Relevant BUGIDs: 490938 Purpose of commit: new feature Commit summary: --------------- Added libpammodutil and link it with every module as its built. The issue here is that there is a lot of code that the various modules use in common, and this staic library can be used to help make this code more maintainable. I do not intend to make this library dynamic. Especially right now, as I want to be free to chop and change the API and don't want to deal with revision control and third party modules. This checkin makes the pam_rhost_auth module make some use of this new library. I don't intend to add support for any other module prior to releasing 0.76. --- modules/pammodutil/Makefile | 53 ++++++++++++++ modules/pammodutil/README | 15 ++++ modules/pammodutil/include/security/_pam_modutil.h | 33 +++++++++ modules/pammodutil/modutil_cleanup.c | 16 +++++ modules/pammodutil/modutil_getpwnam.c | 80 ++++++++++++++++++++++ modules/pammodutil/modutil_getpwuid.c | 80 ++++++++++++++++++++++ modules/pammodutil/pammodutil.h | 22 ++++++ 7 files changed, 299 insertions(+) create mode 100644 modules/pammodutil/Makefile create mode 100644 modules/pammodutil/README create mode 100644 modules/pammodutil/include/security/_pam_modutil.h create mode 100644 modules/pammodutil/modutil_cleanup.c create mode 100644 modules/pammodutil/modutil_getpwnam.c create mode 100644 modules/pammodutil/modutil_getpwuid.c create mode 100644 modules/pammodutil/pammodutil.h (limited to 'modules/pammodutil') diff --git a/modules/pammodutil/Makefile b/modules/pammodutil/Makefile new file mode 100644 index 00000000..a97388ef --- /dev/null +++ b/modules/pammodutil/Makefile @@ -0,0 +1,53 @@ +# +# $Id$ +# +# + +include ../../Make.Rules + +LIBNAME=libpammodutil + +# --------------------------------------------- + +dummy: all + +# --------------------------------------------- + +CFLAGS += $(PIC) $(STATIC) $(MOREFLAGS) \ + -DLIBPAM_VERSION_MAJOR=$(MAJOR_REL) \ + -DLIBPAM_VERSION_MINOR=$(MINOR_REL) + +# all the object files we care about +LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o + +# static library name +LIBSTATIC = $(LIBNAME).a + +SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS) $(STATICOBJ)) + +# --------------------------------------------- +## rules + +all: dirs $(LIBSTATIC) ../../Make.Rules + +dirs: + $(MKDIR) static + +static/%.o : %.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ + +$(LIBSTATIC): $(SLIBOBJECTS) + ar cr $@ $(SLIBOBJECTS) + $(RANLIB) $@ + +install: + @echo "at this time, we're not installing $(LIBSTATIC)" + +remove: + @echo "at this time, there is nothing to remove" + +clean: + rm -f a.out core *~ static/*.o + rm -f *.a *.o + if [ -d dynamic ]; then rmdir dynamic ; fi + if [ -d static ]; then rmdir static ; fi diff --git a/modules/pammodutil/README b/modules/pammodutil/README new file mode 100644 index 00000000..241f83a7 --- /dev/null +++ b/modules/pammodutil/README @@ -0,0 +1,15 @@ +$Id$ + +This is a libarary of routines for use by modules. The routines seem +to have a common use for modules, but are not part of libpam and never +will be. They are also a convenient layer of abstraction for providing +thread-safe functions that may require use of pam_handle_t 'data' +items to make their thread-safeness tied to the use of a single +pam_handle_t per thread. + +Functions provided so far are all listed in + + include/security/_pam_modutil.h + +. + diff --git a/modules/pammodutil/include/security/_pam_modutil.h b/modules/pammodutil/include/security/_pam_modutil.h new file mode 100644 index 00000000..af8a7ae1 --- /dev/null +++ b/modules/pammodutil/include/security/_pam_modutil.h @@ -0,0 +1,33 @@ +#ifndef _PAM_MODUTIL_H +#define _PAM_MODUTIL_H + +/* + * $Id$ + * + * This file is a list of handy libc wrappers that attempt to provide some + * thread-safe and other convenient functionality to modules in a form that + * is common, but not dynamically linked with yet another dynamic pam + * library extension. + * + * A number of these functions reserve space in a pam_[sg]et_data item. + * In all cases, the name of the item is prefixed with "_pammodutil_*". + * + * On systems that simply can't support thread safe programming, these + * functions don't support it either - sorry. + * + * Copyright (c) 2001 Andrew Morgan + */ + +#include +#include + +extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, + const char *user); + +extern struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, + uid_t uid); + +extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data, + int error_status); + +#endif /* _PAM_MODUTIL_H */ diff --git a/modules/pammodutil/modutil_cleanup.c b/modules/pammodutil/modutil_cleanup.c new file mode 100644 index 00000000..e95d6100 --- /dev/null +++ b/modules/pammodutil/modutil_cleanup.c @@ -0,0 +1,16 @@ +/* + * $Id$ + * + * This function provides a common pam_set_data() friendly version of free(). + */ + +#include "pammodutil.h" + +void _pammodutil_cleanup(pam_handle_t *pamh, void *data, int error_status) +{ + if (data) { + /* junk it */ + (void) free(data); + } +} + diff --git a/modules/pammodutil/modutil_getpwnam.c b/modules/pammodutil/modutil_getpwnam.c new file mode 100644 index 00000000..287dc065 --- /dev/null +++ b/modules/pammodutil/modutil_getpwnam.c @@ -0,0 +1,80 @@ +/* + * $Id$ + * + * This function provides a thread safer version of getpwnam() for use + * with PAM modules that care about this sort of thing. + * + * XXX - or at least it should provide a thread-safe alternative. + */ + +#include "pammodutil.h" + +#include +#include + +struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user) +{ +#ifdef HAVE_GETPWNAM_R + + void *buffer=NULL; + size_t length = PWD_INITIAL_LENGTH; + + do { + int status; + void *new_buffer; + struct passwd *result = NULL; + + new_buffer = realloc(buffer, sizeof(struct passwd) + length); + if (new_buffer == NULL) { + + D(("out of memory")); + + /* no memory for the user - so delete the memory */ + if (buffer) { + free(buffer); + } + return NULL; + } + buffer = new_buffer; + + /* make the re-entrant call to get the pwd structure */ + 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 == PAM_SUCCESS) { + D(("success")); + return result; + } + + D(("was unable to register the data item [%s]", + pam_strerror(pamh, status))); + + free(buffer); + return NULL; + + } + + length <<= 1; + + } while (length < PWD_ABSURD_PWD_LENGTH); + + D(("pwd structure took %u bytes or so of memory", + length+sizeof(struct passwd))); + + free(buffer); + return NULL; + +#else /* ie. ifndef HAVE_GETPWNAM_R */ + + /* + * Sorry, there does not appear to be a reentrant version of + * getpwnam(). So, we use the standard libc function. + */ + + return getpwnam(user); + +#endif /* def HAVE_GETPWNAM_R */ +} diff --git a/modules/pammodutil/modutil_getpwuid.c b/modules/pammodutil/modutil_getpwuid.c new file mode 100644 index 00000000..e200dd1e --- /dev/null +++ b/modules/pammodutil/modutil_getpwuid.c @@ -0,0 +1,80 @@ +/* + * $Id$ + * + * This function provides a thread safer version of getpwuid() for use + * with PAM modules that care about this sort of thing. + * + * XXX - or at least it should provide a thread-safe alternative. + */ + +#include "pammodutil.h" + +#include +#include + +struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid) +{ +#ifdef HAVE_GETPWNAM_R + + void *buffer=NULL; + size_t length = PWD_INITIAL_LENGTH; + + do { + int status; + void *new_buffer; + struct passwd *result = NULL; + + new_buffer = realloc(buffer, sizeof(struct passwd) + length); + if (new_buffer == NULL) { + + D(("out of memory")); + + /* no memory for the user - so delete the memory */ + if (buffer) { + free(buffer); + } + return NULL; + } + buffer = new_buffer; + + /* make the re-entrant call to get the pwd structure */ + 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 == PAM_SUCCESS) { + D(("success")); + return result; + } + + D(("was unable to register the data item [%s]", + pam_strerror(pamh, status))); + + free(buffer); + return NULL; + + } + + length <<= 1; + + } while (length < PWD_ABSURD_PWD_LENGTH); + + D(("pwd structure took %u bytes or so of memory", + length+sizeof(struct passwd))); + + free(buffer); + return NULL; + +#else /* ie. ifndef HAVE_GETPWNAM_R */ + + /* + * Sorry, there does not appear to be a reentrant version of + * getpwnam(). So, we use the standard libc function. + */ + + return getpwuid(uid); + +#endif /* def HAVE_GETPWNAM_R */ +} diff --git a/modules/pammodutil/pammodutil.h b/modules/pammodutil/pammodutil.h new file mode 100644 index 00000000..efcc98e1 --- /dev/null +++ b/modules/pammodutil/pammodutil.h @@ -0,0 +1,22 @@ +#ifndef PAMMODUTIL_H +#define PAMMODUTIL_H + +/* + * $Id$ + * + * Copyright (c) 2001 Andrew Morgan + */ + +#include +#include +#include +#include + +#define PWD_INITIAL_LENGTH 0x100 +#define PWD_ABSURD_PWD_LENGTH 0x1000 + +/* This is a simple cleanup, it just free()s the 'data' memory */ +extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data, + int error_status); + +#endif /* PAMMODUTIL_H */ -- cgit v1.2.3