summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2001-12-09 22:15:11 +0000
committerAndrew G. Morgan <morgan@kernel.org>2001-12-09 22:15:11 +0000
commitda67a7d6126846939fd43b1ddb5aa8c06ee09301 (patch)
treee9df9e69023b0e8584ee85cd8a44daf210bee75d /modules
parentcb7734d4080f3673a34594ee4c6e7b02dcd89f33 (diff)
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.
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile6
-rw-r--r--modules/Simple.Rules11
-rw-r--r--modules/pam_rhosts/pam_rhosts_auth.c21
-rw-r--r--modules/pammodutil/Makefile53
-rw-r--r--modules/pammodutil/README15
-rw-r--r--modules/pammodutil/include/security/_pam_modutil.h33
-rw-r--r--modules/pammodutil/modutil_cleanup.c16
-rw-r--r--modules/pammodutil/modutil_getpwnam.c80
-rw-r--r--modules/pammodutil/modutil_getpwuid.c80
-rw-r--r--modules/pammodutil/pammodutil.h22
10 files changed, 323 insertions, 14 deletions
diff --git a/modules/Makefile b/modules/Makefile
index 51964e5b..93891029 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -11,6 +11,8 @@ include ../Make.Rules
MODDIRS=$(shell /bin/ls -d pam_*)
all:
+ @echo building the static modutil library
+ make -C pammodutil all
@echo modules sources available are:
@ls -d $(MODDIRS) 2>/dev/null ; echo :--------
@echo
@@ -52,5 +54,5 @@ clean: lclean
if [ -d $$i ]; then { \
$(MAKE) -C $$i clean ; \
} fi ; \
- done
-
+ done
+ make -C pammodutil clean
diff --git a/modules/Simple.Rules b/modules/Simple.Rules
index 04fafc12..2d79b00c 100644
--- a/modules/Simple.Rules
+++ b/modules/Simple.Rules
@@ -19,6 +19,9 @@ LIBOBJ = $(addsuffix .o,$(LIBFILES))
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBOBJS = $(addprefix static/,$(LIBOBJ))
+LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
+INCLUDE_PAMMODUTILS = -I../pammodutil/include
+
ifdef DYNAMIC
LIBSHARED = $(TITLE).so
endif
@@ -32,10 +35,10 @@ endif
all: dirs $(LIBSHARED) $(LIBSTATIC) register
dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
+ $(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
+ $(CC) $(CFLAGS) $(INCLUDE_PAMMODUTILS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
dirs:
ifdef DYNAMIC
@@ -56,7 +59,7 @@ endif
ifdef DYNAMIC
$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C)
+ $(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C) $(LINK_PAMMODUTILS)
endif
@@ -66,7 +69,7 @@ endif
ifdef STATIC
$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS)
+ $(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS) $(LINK_PAMMODUTILS)
endif
install: all
diff --git a/modules/pam_rhosts/pam_rhosts_auth.c b/modules/pam_rhosts/pam_rhosts_auth.c
index 7ee77f1d..7266b4e8 100644
--- a/modules/pam_rhosts/pam_rhosts_auth.c
+++ b/modules/pam_rhosts/pam_rhosts_auth.c
@@ -96,6 +96,7 @@ int innetgr(const char *, const char *, const char *,const char *);
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* to the best of my knowledge, all modern UNIX boxes have 32 bit integers */
#define U32 unsigned int
@@ -232,15 +233,16 @@ static int pam_get_rhost(pam_handle_t *pamh, const char **rhost
* requesting the contents of the PAM_RUSER item.
*/
-static int pam_get_ruser(pam_handle_t *pamh, const char **ruser
- , const char *prompt)
+static int pam_get_ruser(pam_handle_t *pamh, const char **ruser,
+ const char *prompt)
{
int retval;
const char *current;
retval = pam_get_item (pamh, PAM_RUSER, (const void **)&current);
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
return retval;
+ }
if (current == NULL) {
return PAM_AUTH_ERR;
@@ -491,7 +493,7 @@ pam_iruserok(pam_handle_t *pamh,
* Identify user's local .rhosts file
*/
- pwd = getpwnam(luser);
+ pwd = _pammodutil_getpwnam(pamh, luser);
if (pwd == NULL) {
/*
* luser is assumed to be valid because of an earlier check for uid = 0
@@ -660,10 +662,11 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
const char **argv)
{
int retval;
- const char *luser;
- const char *ruser,*rhost;
+ const char *luser = NULL;
+ const char *ruser = NULL, *rhost = NULL;
struct _options opts;
int as_root = 0;
+
/*
* Look at the options and set the flags accordingly.
*/
@@ -675,6 +678,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
for (;;) { /* abuse loop to avoid goto */
/* get the remotehost */
+ D(("getting rhost"));
retval = pam_get_rhost(pamh, &rhost, NULL);
(void) pam_set_item(pamh, PAM_RHOST, rhost);
if (retval != PAM_SUCCESS) {
@@ -685,6 +689,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
}
/* get the remote user */
+ D(("getting ruser"));
retval = pam_get_ruser(pamh, &ruser, NULL);
(void) pam_set_item(pamh, PAM_RUSER, ruser);
if (retval != PAM_SUCCESS) {
@@ -694,8 +699,8 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
}
/* get the local user */
+ D(("getting user"));
retval = pam_get_user(pamh, &luser, NULL);
-
if (retval != PAM_SUCCESS) {
if (opts.opt_debug)
_pam_log(LOG_DEBUG, "could not determine name of local user");
@@ -710,7 +715,7 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
if (! opts.opt_no_uid_check) {
struct passwd *luser_pwd;
- luser_pwd = getpwnam(luser);
+ luser_pwd = _pammodutil_getpwnam(pamh, luser);
if (luser_pwd == NULL) {
if (opts.opt_debug)
_pam_log(LOG_DEBUG, "user '%s' unknown to this system",
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 <morgan@kernel.org>
+ */
+
+#include <pwd.h>
+#include <sys/types.h>
+
+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 <pwd.h>
+#include <stdlib.h>
+
+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 <pwd.h>
+#include <stdlib.h>
+
+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 <morgan@kernel.org>
+ */
+
+#include <security/_pam_aconf.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
+
+#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 */