]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: 490938
authorAndrew G. Morgan <morgan@kernel.org>
Sun, 9 Dec 2001 22:15:11 +0000 (22:15 +0000)
committerAndrew G. Morgan <morgan@kernel.org>
Sun, 9 Dec 2001 22:15:11 +0000 (22:15 +0000)
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.

12 files changed:
CHANGELOG
examples/xsh.c
modules/Makefile
modules/Simple.Rules
modules/pam_rhosts/pam_rhosts_auth.c
modules/pammodutil/Makefile [new file with mode: 0644]
modules/pammodutil/README [new file with mode: 0644]
modules/pammodutil/include/security/_pam_modutil.h [new file with mode: 0644]
modules/pammodutil/modutil_cleanup.c [new file with mode: 0644]
modules/pammodutil/modutil_getpwnam.c [new file with mode: 0644]
modules/pammodutil/modutil_getpwuid.c [new file with mode: 0644]
modules/pammodutil/pammodutil.h [new file with mode: 0644]

index 7ceb3318489858146f877d5a87a9aeb2a7957d0a..5b9af1e615722443e2e23ca858be814945b82b1b 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -55,6 +55,9 @@ bug report - outstanding bugs are listed here:
 0.76: please submit patches for this section with actual code/doc
       patches!
 
+* added a static module helper library object includes a few changes
+  to examples/xsh.c for testing purposes, and also modified the
+  pam_rhosts_auth module to use this new library. (Bug 490938 - agmorgan)
 * documentation: random typo fixes from Nalin and more stuff from me
   (Bug 476949, Tasks 43507, 17426 - agmorgan)
 * pam_unix: fix 'likeauth' to kill off the memory leak once and for all.
index 7babce42fc066f220851ec590f7e0073e8794a96..dbb2416cf7ccb5bd8afd41ad1cd9f904f0fb24a3 100644 (file)
 
 #include <security/_pam_aconf.h>
 
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 /* ------ some local (static) functions ------- */
 
 static void bail_out(pam_handle_t *pamh,int really, int code, const char *fn)
@@ -56,6 +60,26 @@ int main(int argc, char **argv)
      retcode = pam_start(service, username, &conv, &pamh);
      bail_out(pamh,1,retcode,"pam_start");
 
+     /* fill in the RUSER and RHOST fields */
+     {
+        char buffer[100];
+        struct passwd *pw;
+
+        pw = getpwuid(getuid());
+        if (pw != NULL) {
+            retcode = pam_set_item(pamh, PAM_RUSER, pw->pw_name);
+            bail_out(pamh,1,retcode,"pam_set_item(PAM_RUSER)");
+        }
+        retcode = gethostname(buffer, sizeof(buffer)-1);
+        if (retcode) {
+            perror("failed to look up hostname");
+            retcode = pam_end(pamh, PAM_ABORT);
+            bail_out(pamh,1,retcode,"pam_end");
+        }
+        retcode = pam_set_item(pamh, PAM_RHOST, buffer);
+        bail_out(pamh,1,retcode,"pam_set_item(PAM_RHOST)");
+     }
+
      /* to avoid using goto we abuse a loop here */
      for (;;) {
          /* authenticate the user --- `0' here, could have been PAM_SILENT
index 51964e5bf1e94ab0446a5c3a18d4e9316cf996f1..938910290bf857bacf6dbf1cf9b5579c4ab61eb8 100644 (file)
@@ -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
index 04fafc1280e41bbab3cbeb73ec5fd6d669d995dd..2d79b00c5078e47a4e0e33c016fb35befcc83082 100644 (file)
@@ -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
index 7ee77f1d56453a7d68e8a5c180132c6e4b4a4ad6..7266b4e838fd1f6cd5c1edf3653818e789bd1c9c 100644 (file)
@@ -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 (file)
index 0000000..a97388e
--- /dev/null
@@ -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 (file)
index 0000000..241f83a
--- /dev/null
@@ -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 (file)
index 0000000..af8a7ae
--- /dev/null
@@ -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 (file)
index 0000000..e95d610
--- /dev/null
@@ -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 (file)
index 0000000..287dc06
--- /dev/null
@@ -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 (file)
index 0000000..e200dd1
--- /dev/null
@@ -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 (file)
index 0000000..efcc98e
--- /dev/null
@@ -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 */