Try to avoid the non-reentrant nsswitch functions, to guard against broken
applications, which we may not always have sources for.
--- Linux-PAM-0.75/libpam/include/security/_pam_macros.h.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/libpam/include/security/_pam_macros.h	Mon Oct 22 14:24:48 2001
@@ -1,8 +1,13 @@
 #ifndef PAM_MACROS_H
 #define PAM_MACROS_H
 
-#include <string.h>	/* string functions */
+#include <sys/types.h>
+#include <string.h>        /* string functions */
 #include <stdlib.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
 
 /*
  * All kind of macros used by PAM, but usable in some other
@@ -50,6 +55,68 @@
 	free(reply);                              \
 } while (0)
 
+/* Wrappers for Unix98's getpwXXX and getgrXXX _r variants, for handling
+ * ERANGE error conditions and other weirdness. */
+#define DEFINE_PAM_GETENT(fn,qtype,type) \
+static int \
+_pam_##fn(qtype q, type *result, char **buf, size_t *buf_len, type **res) \
+{ \
+    size_t length; \
+    char *buffer, *tmp; \
+    int i; \
+ \
+    memset(result, 0, sizeof(*result)); \
+    *res = NULL; \
+ \
+    *buf_len = length = 0; \
+    *buf = buffer = NULL; \
+ \
+    do { \
+        length += BUFSIZ; /* tune this for speed/memory tradeoffs */ \
+        tmp = realloc(buffer, length); \
+        if(tmp == NULL) { \
+            free(buffer); \
+            return ENOMEM; \
+        } \
+        buffer = tmp; \
+ \
+        i = fn(q, result, buffer, length, res); \
+        if(i != 0) { \
+            *res = NULL; \
+        } else { \
+            break; \
+        } \
+    } while(i == ERANGE); \
+ \
+    if((i == 0) && (*res != NULL)) { \
+        *buf = buffer; \
+        *buf_len = length; \
+        *res = result; \
+    } else { \
+        *buf = NULL; \
+        *buf_len = 0; \
+        *res = NULL; \
+    } \
+ \
+    return i; \
+}
+/* Some pre-built definitions, not actually used unless the including module
+ * defines PAM_<fn>, similar to PAM_SM_xxx function declarations work. */
+#ifdef PAM_GETPWNAM_R
+DEFINE_PAM_GETENT(getpwnam_r,const char *,struct passwd);
+#endif
+#ifdef PAM_GETPWUID_R
+DEFINE_PAM_GETENT(getpwuid_r,uid_t,struct passwd);
+#endif
+#ifdef PAM_GETGRNAM_R
+DEFINE_PAM_GETENT(getgrnam_r,const char *,struct group);
+#endif
+#ifdef PAM_GETGRGID_R
+DEFINE_PAM_GETENT(getgrgid_r,gid_t,struct group);
+#endif
+#ifdef PAM_GETSPNAM_R
+DEFINE_PAM_GETENT(getspnam_r,const char *,struct spwd);
+#endif
 /* some debugging code */
 
 #ifdef DEBUG
--- Linux-PAM-0.75/modules/pam_access/pam_access.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_access/pam_access.c	Mon Oct 22 14:24:48 2001
@@ -63,6 +63,8 @@
 #define PAM_SM_ACCOUNT
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
+#define PAM_GETGRNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 int strcasecmp(const char *s1, const char *s2);
@@ -280,8 +282,10 @@
 static int user_match(char *tok, struct login_info *item)
 {
     char   *string = item->user->pw_name;
+    char   *gbuf = NULL;
+    size_t gbuflen;
     struct login_info fake_item;
-    struct group *group;
+    struct group *group, grp;
     int     i;
     char   *at;
 
@@ -291,7 +295,6 @@
      * token is a group that contains the username, or if the token is the
      * name of the user's primary group.
      */
-
     if ((at = strchr(tok + 1, '@')) != 0) {	/* split user@host pattern */
 	*at = 0;
 	fake_item.from = myhostname();
@@ -300,12 +303,21 @@
 	return (netgroup_match(tok + 1, (char *) 0, string));
     } else if (string_match(tok, string)) {	/* ALL or exact match */
 	return (YES);
-    } else if ((group = getgrnam(tok))) {	/* try group membership */
-	if (item->user->pw_gid == group->gr_gid)
+    } else if ((_pam_getgrnam_r(tok, &grp, &gbuf, &gbuflen, &group) == 0) &&
+	       (group == &grp)) {	/* try group membership */
+	if (item->user->pw_gid == group->gr_gid) {
+            if(gbuf) {
+                free(gbuf);
+	    }
 	    return (YES);
+	}
 	for (i = 0; group->gr_mem[i]; i++)
-	    if (strcasecmp(string, group->gr_mem[i]) == 0)
+	    if (strcasecmp(string, group->gr_mem[i]) == 0) {
+                if(gbuf) {
+                    free(gbuf);
+	        }
 		return (YES);
+	    }
     }
     return (NO);
 }
@@ -349,6 +361,7 @@
            by "string" starts from "tok".
                                1998/01/27  Andrey V. Savochkin <saw@msu.ru>
          */
+
         struct hostent *h;
         char hn[3+1+3+1+3+1+3+1+1];
         int r;
@@ -405,8 +418,9 @@
 {
     struct login_info loginfo;
     const char *user=NULL, *service=NULL;
-    char *from=NULL;
-    struct passwd *user_pw;
+    char *from=NULL, *ubuf = NULL;
+    size_t ubuflen;
+    struct passwd passwd, *user_pw;
 
     if ((pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
 	!= PAM_SUCCESS) || (service == NULL) || (*service == ' ')) {
@@ -453,7 +467,9 @@
 
     }
 
-    if ((user_pw=getpwnam(user))==NULL) return (PAM_USER_UNKNOWN);
+    if (_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &user_pw) != 0)
+	    user_pw = NULL;
+    if (user_pw == NULL) return (PAM_USER_UNKNOWN);
 
     /*
      * Bundle up the arguments to avoid unnecessary clumsiness later on.
@@ -467,13 +483,22 @@
 
     if (!parse_args(&loginfo, argc, argv)) {
 	_log_err("failed to parse the module arguments");
+        if (ubuf) {
+            free(ubuf);
+        }
 	return PAM_ABORT;
     }
 
     if (login_access(&loginfo)) {
+        if (ubuf) {
+            free(ubuf);
+        }
 	return (PAM_SUCCESS);
     } else {
 	_log_err("access denied for user `%s' from `%s'",user,from);
+        if (ubuf) {
+            free(ubuf);
+        }
 	return (PAM_PERM_DENIED);
     }
 }
--- Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c	Mon Oct 22 14:24:48 2001
@@ -392,9 +392,9 @@
 	char *oldmono, *newmono, *wrapped;
 
 	if (strcmp(new, old) == 0) {
-        msg = "is the same as the old one";
-        return msg;
-    }
+            msg = "is the same as the old one";
+            return msg;
+    	}
 
 	newmono = str_lower(x_strdup(new));
 	oldmono = str_lower(x_strdup(old));
--- Linux-PAM-0.75/modules/pam_group/pam_group.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_group/pam_group.c	Mon Oct 22 14:24:48 2001
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <limits.h>
 #include <stdarg.h>
 #include <time.h>
 #include <syslog.h>
@@ -49,6 +50,7 @@
 #define PAM_SM_AUTH
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETGRNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* --- static functions for checking whether the user should be let in --- */
@@ -574,14 +576,20 @@
 	  }
 #else
 	  {
-	      const struct group *grp;
+	      struct group *grp, group;
+	      char *gbuf = NULL;
+	      size_t gbuflen;
 
-	      grp = getgrnam(buf+at);
+	      if (_pam_getgrnam_r(buf+at, &group, &gbuf, &gbuflen, &grp) != 0)
+		  grp = NULL;
 	      if (grp == NULL) {
 		  _log_err("bad group: %s", buf+at);
 	      } else {
 		  D(("group %s exists", buf+at));
 		  (*list)[len++] = grp->gr_gid;
+		  if (gbuf) {
+                      free(gbuf);
+		  }
 	      }
 	  }
 #endif
--- Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c	Mon Oct 22 14:24:48 2001
@@ -77,6 +77,7 @@
 
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* some syslogging */
@@ -400,7 +401,9 @@
 {
     int retval, ctrl;
     const char *user;
-    const struct passwd *pwd;
+    struct passwd *pwd, passwd;
+    char *ubuf;
+    size_t ubuflen;
     uid_t uid;
 
     /*
@@ -420,7 +423,8 @@
 
     /* what uid? */
 
-    pwd = getpwnam(user);
+    if (_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
     if (pwd == NULL) {
 	D(("couldn't identify user %s", user));
 	return PAM_CRED_INSUFFICIENT;
@@ -434,6 +438,9 @@
     /* indicate success or failure */
 
     uid = -1;                                           /* forget this */
+    if (ubuf) {
+        free(ubuf);
+    }
 
     return retval;
 }
--- Linux-PAM-0.75/modules/pam_limits/pam_limits.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_limits/pam_limits.c	Mon Oct 22 14:27:41 2001
@@ -41,8 +41,6 @@
 #include <pwd.h>
 
 /* Module defines */
-#define LINE_LENGTH 1024
-
 #define LIMITS_DEF_USER     0 /* limit was set by an user entry */
 #define LIMITS_DEF_GROUP    1 /* limit was set by a group entry */
 #define LIMITS_DEF_DEFAULT  2 /* limit was set by an default entry */
@@ -82,8 +80,10 @@
 #define LIMIT_HARD  2
 
 #define PAM_SM_SESSION
-
 #include "../../libpam/include/security/pam_modules.h"
+
+#define PAM_GETPWNAM_R
+#define PAM_GETGRNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 #ifdef HAVE_PWDBLIB
@@ -213,9 +213,10 @@
    the user is in the group. */
 static int is_on_group(const char *user_name, const char *group_name)
 {
-    struct passwd *pwd;
-    struct group *grp, *pgrp;
-    char uname[LINE_LENGTH], gname[LINE_LENGTH];
+    struct passwd passwd, *pwd;
+    struct group group, *grp;
+    char uname[LINE_MAX], gname[LINE_MAX], *ubuf = NULL, *gbuf = NULL;
+    size_t ubuflen, gbuflen;
     
     if (!user_name)
         return 0;
@@ -230,26 +231,49 @@
     memset(gname, 0, sizeof(gname));
     strncpy(gname, group_name, sizeof(gname) - 1);
         
-    pwd = getpwnam(uname);
+    if (_pam_getpwnam_r(uname, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
     if (!pwd)
         return 0;
 
     /* the info about this group */
-    grp = getgrnam(gname);
-    if (!grp)
+    if (_pam_getgrnam_r(gname, &group, &gbuf, &gbuflen, &grp) != 0)
+	grp = NULL;
+    if (!grp) {
+        if (ubuf) {
+            free(ubuf);
+        }
         return 0;
+    }
     
     /* first check: is a member of the group_name group ? */
-    if (is_on_list(grp->gr_mem, uname))
+    if (is_on_list(grp->gr_mem, uname)) {
+        if (ubuf) {
+            free(ubuf);
+        }
+        if (gbuf) {
+            free(gbuf);
+        }
         return 1;
+    }
 
-    /* next check: user primary group is group_name ? */
-    pgrp = getgrgid(pwd->pw_gid);
-    if (!pgrp)
-        return 0;
-    if (!strcmp(pgrp->gr_name, gname))
+    /* next check: user primary group is group ? */
+    if (pwd->pw_gid == grp->gr_gid) {
+        if (ubuf) {
+            free(ubuf);
+        }
+        if (gbuf) {
+            free(gbuf);
+        }
         return 1;
+    }
         
+    if (ubuf) {
+        free(ubuf);
+    }
+    if (gbuf) {
+        free(gbuf);
+    }
     return 0;
 }
     
@@ -430,8 +454,7 @@
 	}
     } else 
 	if (limit_item == LIMIT_PRI) {
-		/* additional check */
-		pl->priority = ((limit_value>0)?limit_value:0);
+		pl->priority = limit_value;
 	} else {
 	        if (pl->login_limit_def < source) {
 	            return;
@@ -447,7 +470,7 @@
 			     struct pam_limit_s *pl)
 {
     FILE *fil;
-    char buf[LINE_LENGTH];
+    char buf[LINE_MAX];
     
 #define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE
     /* check for the LIMITS_FILE */
@@ -463,11 +486,11 @@
     /* init things */
     memset(buf, 0, sizeof(buf));
     /* start the show */
-    while (fgets(buf, LINE_LENGTH, fil) != NULL) {
-        char domain[LINE_LENGTH];
-        char ltype[LINE_LENGTH];
-        char item[LINE_LENGTH];
-        char value[LINE_LENGTH];
+    while (fgets(buf, LINE_MAX, fil) != NULL) {
+        char domain[LINE_MAX];
+        char ltype[LINE_MAX];
+        char item[LINE_MAX];
+        char value[LINE_MAX];
         int i,j;
         char *tptr;
         
@@ -580,10 +603,13 @@
 {
     int retval;
     char *user_name;
-    struct passwd *pwd;
+    struct passwd passwd, *pwd;
+    char *ubuf = NULL;
+    size_t ubuflen;
     int ctrl;
     struct pam_limit_s pl;
     char error_buf[BUFSIZ];
+    uid_t uid;
 
     D(("called."));
 
@@ -596,7 +622,8 @@
         return PAM_SESSION_ERR;
      }
 	
-    pwd = getpwnam(user_name);
+    if (_pam_getpwnam_r(user_name, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
     if (!pwd) {
         if (ctrl & PAM_DEBUG_ARG)
             _pam_log(LOG_WARNING, "open_session username '%s' does not exist",
@@ -607,16 +634,25 @@
     retval = init_limits(&pl);
     if (retval != PAM_SUCCESS) {
         _pam_log(LOG_WARNING, "cannot initialize");
+	if (ubuf) {
+            free(ubuf);
+	}
         return PAM_IGNORE;
     }
 
     retval = parse_config_file(pwd->pw_name, ctrl, &pl);
     if (retval == PAM_IGNORE) {
 	D(("the configuration file has an applicable '<domain> -' entry"));
+	if (ubuf) {
+            free(ubuf);
+	}
 	return PAM_SUCCESS;
     }
     if (retval != PAM_SUCCESS) {
         _pam_log(LOG_WARNING, "error parsing the configuration file");
+	if (ubuf) {
+            free(ubuf);
+	}
         return PAM_IGNORE;
     }
 
@@ -634,9 +670,15 @@
 #endif
             printf("%s", error_buf);
         sleep(2);
+        if (ubuf) {
+            free(ubuf);
+        }
         return PAM_PERM_DENIED;
     }
 
+    if (ubuf) {
+        free(ubuf);
+    }
     return PAM_SUCCESS;
 }
 
--- Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c	Mon Oct 22 14:24:48 2001
@@ -39,6 +39,9 @@
 #define PAM_SM_ACCOUNT
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
+#define PAM_GETGRNAM_R
+#define PAM_GETGRGID_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* some syslogging */
@@ -68,9 +71,11 @@
 /* Checks if a user is a member of a group */
 static int is_on_group(const char *user_name, const char *group_name)
 {
-    struct passwd *pwd;
-    struct group *grp, *pgrp;
+    struct passwd passwd, *pwd;
+    struct group group, *grp;
     char uname[BUFSIZ], gname[BUFSIZ];
+    char *ubuf = NULL, *gbuf = NULL;
+    size_t ubuflen, gbuflen;
     
     if (!strlen(user_name))
         return 0;
@@ -81,26 +86,49 @@
     bzero(gname, sizeof(gname));
     strncpy(gname, group_name, sizeof(gname)-1);
         
-    pwd = getpwnam(uname);
+    if (_pam_getpwnam_r(uname, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
     if (!pwd)
         return 0;
 
     /* the info about this group */
-    grp = getgrnam(gname);
-    if (!grp)
+    if (_pam_getgrnam_r(gname, &group, &gbuf, &gbuflen, &grp) != 0)
+	grp = NULL;
+    if (!grp) {
+	if (ubuf) {
+	    free(ubuf);
+	}
         return 0;
+    }
     
     /* first check: is a member of the group_name group ? */
-    if (is_on_list(grp->gr_mem, uname))
+    if (is_on_list(grp->gr_mem, uname)) {
+	if (ubuf) {
+	    free(ubuf);
+	}
+	if (gbuf) {
+	    free(gbuf);
+	}
         return 1;
+    }
 
-    /* next check: user primary group is group_name ? */
-    pgrp = getgrgid(pwd->pw_gid);
-    if (!pgrp)
-        return 0;
-    if (!strcmp(pgrp->gr_name, gname))
+    /* next check: user primary group is group ? */
+    if (pwd->pw_gid == grp->gr_gid) {
+	if (ubuf) {
+	    free(ubuf);
+	}
+	if (gbuf) {
+	    free(gbuf);
+	}
         return 1;
+    }
         
+    if (ubuf) {
+        free(ubuf);
+    }
+    if (gbuf) {
+        free(gbuf);
+    }
     return 0;
 }
 
@@ -295,18 +323,27 @@
     }
 
     if(extitem) {
+        char *ubuf = NULL, *gbuf = NULL;
+	size_t ubuflen, gbuflen;
+	struct passwd passwd;
+	struct group group;
 	switch(extitem) {
 	    case EI_GROUP:
-		userinfo = getpwnam(citemp);
-		if(userinfo == NULL) {
+		if (_pam_getpwnam_r(citemp, &passwd, &ubuf, &ubuflen, &userinfo) != 0)
+		    userinfo = NULL;
+		if (userinfo == NULL) {
 			_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed",
 				 citemp);
 			return onerr;
 		}
-		grpinfo = getgrgid(userinfo->pw_gid);
-		if(grpinfo == NULL) {
+		if (_pam_getgrgid_r(userinfo->pw_gid, &group, &gbuf, &gbuflen, &grpinfo) != 0)
+		    grpinfo = NULL;
+		if (grpinfo == NULL) {
 			_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getgrgid(%d) failed",
 				 (int)userinfo->pw_gid);
+			if (ubuf) {
+			    free(ubuf);
+			}
 			return onerr;
 		}
 		itemlist[0] = x_strdup(grpinfo->gr_name);
@@ -321,16 +358,17 @@
 		itemlist[i] = NULL;
 		break;
 	    case EI_SHELL:
-		userinfo = getpwnam(citemp); /* Assume that we have already gotten
+		if (_pam_getpwnam_r(citemp, &passwd, &ubuf, &ubuflen, &userinfo) != 0)
+		    userinfo = NULL;
+		if (userinfo == NULL) {      /* Assume that we have already gotten
 						PAM_USER in pam_get_item() - a valid
 						assumption since citem gets set to
 						PAM_USER in the extitem switch */
-		if(userinfo == NULL) {
 			_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed",
 				 citemp);
 			return onerr;
 		}
-		citemp = userinfo->pw_shell;
+		citemp = x_strdup(userinfo->pw_shell);
 		break;
 	    default:
 		_pam_log(LOG_ERR,
@@ -339,6 +377,12 @@
 			 extitem);
 		return onerr;
 	}
+	if (ubuf) {
+	    free(ubuf);
+	}
+	if (gbuf) {
+	    free(gbuf);
+	}
     }
 #ifdef DEBUG
     _pam_log(LOG_INFO,
--- Linux-PAM-0.75/modules/pam_mail/pam_mail.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_mail/pam_mail.c	Mon Oct 22 14:24:48 2001
@@ -46,6 +46,7 @@
 #define PAM_SM_AUTH
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* some syslogging */
@@ -172,7 +173,9 @@
     int retval;
     const char *user, *path;
     char *folder;
-    const struct passwd *pwd=NULL;
+    char *ubuf = NULL;
+    size_t ubuflen;
+    struct passwd passwd, *pwd=NULL;
 
     retval = pam_get_user(pamh, &user, NULL);
     if (retval != PAM_SUCCESS || user == NULL) {
@@ -183,7 +186,8 @@
     if (ctrl & PAM_NEW_MAIL_DIR) {
 	path = *path_mail;
 	if (*path == '~') {       /* support for $HOME delivery */
-	    pwd = getpwnam(user);
+	    if (_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 	    if (pwd == NULL) {
 		_log_err(LOG_ERR, "user [%s] unknown", user);
 		_pam_overwrite(*path_mail);
@@ -197,6 +201,9 @@
 		_log_err(LOG_ALERT, "badly formed mail path [%s]", *path_mail);
 		_pam_overwrite(*path_mail);
 		_pam_drop(*path_mail);
+		if (ubuf) {
+		    free(ubuf);
+		}
 		return PAM_ABORT;
 	    }
 	    ctrl |= PAM_HOME_MAIL;
@@ -249,6 +256,9 @@
 
     if (folder == NULL) {
 	_log_err(LOG_CRIT, "out of memory for mail folder");
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_BUF_ERR;
     }
 
--- Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c	Mon Oct 22 14:29:21 2001
@@ -50,6 +50,7 @@
 #define PAM_SM_SESSION
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* argument parsing */
@@ -325,7 +326,9 @@
 {
    int retval, ctrl;
    const char *user;
-   const struct passwd *pwd;
+   struct passwd passwd, *pwd;
+   char *ubuf = NULL;
+   size_t ubuflen;
    struct stat St;
       
    /* Parse the flag values */
@@ -340,7 +343,8 @@
    }
 
    /* Get the password entry */
-   pwd = getpwnam(user);
+   if (_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+      pwd = NULL;
    if (pwd == NULL)
    {
       D(("couldn't identify user %s", user));
@@ -349,10 +353,18 @@
 
    /* Stat the home directory, if something exists then we assume it is
       correct and return a success*/
-   if (stat(pwd->pw_dir,&St) == 0)
+   if (stat(pwd->pw_dir,&St) == 0) {
+      if (ubuf) {
+          free(ubuf);
+      }
       return PAM_SUCCESS;
+   }
 
-   return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir);
+   retval =  create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir);
+   if (ubuf) {
+       free(ubuf);
+   }
+   return retval;
 }
 
 /* Ignore */
--- Linux-PAM-0.75/modules/pam_nologin/pam_nologin.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_nologin/pam_nologin.c	Mon Oct 22 14:24:48 2001
@@ -27,6 +27,7 @@
 #define PAM_SM_ACCOUNT
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* --- authentication management functions (only) --- */
@@ -39,7 +40,9 @@
      int fd;
      const char *username;
      char *mtmp=NULL;
-     struct passwd *user_pwd;
+     struct passwd pwd, *user_pwd;
+     char *ubuf = NULL;
+     size_t ubuflen;
      struct pam_conv *conversation;
      struct pam_message message;
      struct pam_message *pmessage = &message;
@@ -52,9 +55,10 @@
            || !username) {
          return PAM_SERVICE_ERR;
        }
-       user_pwd = getpwnam(username);
+       if (_pam_getpwnam_r(username, &pwd, &ubuf, &ubuflen, &user_pwd) != 0)
+	       user_pwd = NULL;
        if (user_pwd && user_pwd->pw_uid == 0) {
-         message.msg_style = PAM_TEXT_INFO;
+           message.msg_style = PAM_TEXT_INFO;
        } else {
 	   if (!user_pwd) {
 	       retval = PAM_USER_UNKNOWN;
@@ -65,8 +69,12 @@
        }
 
        /* fill in message buffer with contents of /etc/nologin */
-       if (fstat(fd, &st) < 0) /* give up trying to display message */
-         return retval;
+       if (fstat(fd, &st) < 0) { /* give up trying to display message */
+           if (ubuf) {
+	       free(ubuf);
+	   }
+           return retval;
+       }
        message.msg = mtmp = malloc(st.st_size+1);
        /* if malloc failed... */
        if (!message.msg) return retval;
@@ -82,6 +90,9 @@
 	   _pam_drop_reply(resp, 1);
      }
 
+     if (ubuf) {
+	 free(ubuf);
+     }
      return retval;
 }
 
--- Linux-PAM-0.75/modules/pam_rhosts/pam_rhosts_auth.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_rhosts/pam_rhosts_auth.c	Mon Oct 22 14:24:48 2001
@@ -46,6 +46,7 @@
 #include <sys/fsuid.h>
 #include <sys/types.h>
 #include <sys/uio.h>
+#include <limits.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -87,6 +88,8 @@
 #define PAM_SM_AUTH  /* only defines this management group */
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
+#define PAM_GETGRGID_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* to the best of my knowledge, all modern UNIX boxes have 32 bit integers */
@@ -453,11 +456,13 @@
 {
     const char *cp;
     struct stat sbuf;
-    struct passwd *pwd;
+    struct passwd passwd, *pwd;
     FILE *hostf;
     uid_t uid;
     int answer;
     char pbuf[MAXPATHLEN];               /* potential buffer overrun */
+    char *ubuf = NULL, *gbuf = NULL;
+    size_t ubuflen, gbuflen;
 
     if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) {
 
@@ -481,7 +486,8 @@
      * Identify user's local .rhosts file
      */
 
-    pwd = getpwnam(luser);
+    if (_pam_getpwnam_r(luser, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
     if (pwd == NULL) {
 	/* 
 	 * luser is assumed to be valid because of an earlier check for uid = 0
@@ -495,6 +501,9 @@
     if (strlen(pwd->pw_dir) + sizeof(USER_RHOSTS_FILE) + 2 >= MAXPATHLEN) {
 	if (opts->opt_debug)
 	    _pam_log(LOG_DEBUG,"home directory for `%s' is too long", luser);
+	if (ubuf) {
+            free(ubuf);
+	}
 	return 1;                               /* to dangerous to try */
     }
 
@@ -543,10 +552,12 @@
 
 	/* private group caveat */
 	if (opts->opt_private_group) {
-	    struct group *grp = getgrgid(sbuf.st_gid);
+	    struct group group, *grp;
 
-	    if (NULL == grp || NULL == grp->gr_name
-		|| strcmp(luser,grp->gr_name)) {
+	    if (_pam_getgrgid_r(sbuf.st_gid, &group, &gbuf, &gbuflen, &grp) != 0)
+                grp = NULL;
+	    if ((NULL == grp) || (NULL == grp->gr_name) ||
+	        (strcmp(luser, grp->gr_name) != 0)) {
 		cp = ".rhosts writable by public group";
 	    } else if (grp->gr_mem) {
 		int gcount;
@@ -592,6 +603,12 @@
 
     if (hostf != NULL)
         (void) fclose(hostf);
+    if (ubuf) {
+	free(ubuf);
+    }
+    if (gbuf) {
+	free(gbuf);
+    }
 
     return answer;
 }
@@ -654,6 +671,8 @@
     const char *ruser,*rhost;
     struct _options opts;
     int as_root = 0;
+    char *ubuf = NULL;
+    size_t ubuflen;
     /*
      * Look at the options and set the flags accordingly.
      */
@@ -698,9 +717,10 @@
 
 	/* check if the luser uid == 0... --cristiang */
 	if (! opts.opt_no_uid_check) {
-	    struct passwd *luser_pwd;
+	    struct passwd passwd, *luser_pwd;
 
-	    luser_pwd = getpwnam(luser);
+	    if (_pam_getpwnam_r(luser, &passwd, &ubuf, &ubuflen, &luser_pwd) != 0)
+		luser_pwd = NULL;
 	    if (luser_pwd == NULL) {
 		if (opts.opt_debug)
 		    _pam_log(LOG_DEBUG, "user '%s' unknown to this system",
@@ -729,6 +749,9 @@
 	break;
     }
 
+    if (ubuf) {
+	free(ubuf);
+    }
     return retval;
 }
 
--- Linux-PAM-0.75/modules/pam_securetty/pam_securetty.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_securetty/pam_securetty.c	Mon Oct 22 14:24:48 2001
@@ -16,6 +16,7 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <limits.h>
 #include <unistd.h>
 #include <syslog.h>
 #include <stdarg.h>
@@ -34,6 +35,7 @@
 #define PAM_SM_ACCOUNT
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* some syslogging */
@@ -83,8 +85,10 @@
     char *uttyname;
     char ttyfileline[256];
     char ptname[256];
+    char *ubuf = NULL;
+    size_t ubuflen;
     struct stat ttyfileinfo;
-    struct passwd *user_pwd;
+    struct passwd passwd, *user_pwd;
     FILE *ttyfile;
     int ctrl;
 
@@ -100,16 +104,16 @@
 		? PAM_INCOMPLETE:PAM_SERVICE_ERR);
     }
 
-    /* The PAM_TTY item may be prefixed with "/dev/" - skip that */
-    if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
-	uttyname += sizeof(TTY_PREFIX)-1;
-
-    user_pwd = getpwnam(username);
+    if (_pam_getpwnam_r(username, &passwd, &ubuf, &ubuflen, &user_pwd) != 0)
+	user_pwd = NULL;
     if (user_pwd == NULL) {
 	return PAM_IGNORE;
     } else if (user_pwd->pw_uid != 0) { /* If the user is not root,
 					   securetty's does not apply
 					   to them */
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_SUCCESS;
     }
 
@@ -118,11 +122,21 @@
         if (ctrl & PAM_DEBUG_ARG) {
             _pam_log(LOG_WARNING, "cannot determine user's tty");
 	}
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_SERVICE_ERR;
     }
 
+    /* The PAM_TTY item may be prefixed with "/dev/" - skip that */
+    if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
+	uttyname += sizeof(TTY_PREFIX)-1;
+
     if (stat(SECURETTY_FILE, &ttyfileinfo)) {
 	_pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE);
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_SUCCESS; /* for compatibility with old securetty handling,
 			       this needs to succeed.  But we still log the
 			       error. */
@@ -134,6 +148,9 @@
 	   normal file, return error */
 	_pam_log(LOG_ERR, SECURETTY_FILE
 		 " is either world writable or not a normal file");
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_AUTH_ERR;
     }
 
@@ -141,6 +158,9 @@
     if(ttyfile == NULL) { /* Check that we opened it successfully */
 	_pam_log(LOG_ERR,
 		 "Error opening " SECURETTY_FILE);
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_SERVICE_ERR;
     }
     /* There should be no more errors from here on */
@@ -167,6 +187,9 @@
     if ((retval == PAM_SUCCESS) && (ctrl & PAM_DEBUG_ARG))
 	_pam_log(LOG_DEBUG, "access allowed for '%s' on '%s'",
 		 username, uttyname);
+    if (ubuf) {
+        free(ubuf);
+    }
     return retval;
 }
 
--- Linux-PAM-0.75/modules/pam_shells/pam_shells.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_shells/pam_shells.c	Mon Oct 22 14:24:48 2001
@@ -10,6 +10,7 @@
 
 #include "../../_pam_aconf.h"
 
+#include <limits.h>
 #include <pwd.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -29,6 +30,7 @@
 #define PAM_SM_AUTH
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* some syslogging */
@@ -54,8 +56,10 @@
      const char *userName;
      char *userShell;
      char shellFileLine[256];
+     char *ubuf = NULL;
+     size_t ubuflen;
      struct stat sb;
-     struct passwd * pw;
+     struct passwd passwd, *pw;
      FILE * shellFile;
 
      retval = pam_get_user(pamh,&userName,NULL);
@@ -69,7 +73,8 @@
 	  return PAM_SERVICE_ERR;
      }
 
-     pw = getpwnam(userName);
+     if (_pam_getpwnam_r(userName, &passwd, &ubuf, &ubuflen, &pw) != 0)
+	pw = NULL;
      if (!pw)
 	return PAM_AUTH_ERR;		/* user doesn't exist */
      userShell = pw->pw_shell;
@@ -77,12 +82,18 @@
      if(stat(SHELL_FILE,&sb)) {
 	_pam_log(LOG_ERR,
 	        "%s cannot be stat'd (it probably does not exist)", SHELL_FILE);
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_AUTH_ERR;		/* must have /etc/shells */
      }
 
      if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
 	_pam_log(LOG_ERR,
 	        "%s is either world writable or not a normal file", SHELL_FILE);
+	if (ubuf) {
+	    free(ubuf);
+	}
 	return PAM_AUTH_ERR;
      }
 
@@ -90,7 +101,10 @@
      if(shellFile == NULL) { /* Check that we opened it successfully */
 	_pam_log(LOG_ERR,
 	        "Error opening %s", SHELL_FILE);
-       return PAM_SERVICE_ERR;
+	if (ubuf) {
+	   free(ubuf);
+        }
+        return PAM_SERVICE_ERR;
      }
      /* There should be no more errors from here on */
      retval=PAM_AUTH_ERR;
@@ -105,6 +119,9 @@
      fclose(shellFile);
      if(retval)
        retval = PAM_AUTH_ERR;
+     if (ubuf) {
+       free(ubuf);
+     }
      return retval;
 }
 
--- Linux-PAM-0.75/modules/pam_tally/pam_tally.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_tally/pam_tally.c	Mon Oct 22 14:24:48 2001
@@ -45,6 +45,7 @@
 /* #define PAM_SM_PASSWORD */
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /*---------------------------------------------------------------------*/
@@ -106,7 +107,9 @@
 static int pam_get_uid( pam_handle_t *pamh, uid_t *uid, const char **userp ) 
   {
     const char *user;
-    struct passwd *pw;
+    char *ubuf = NULL;
+    size_t ubuflen;
+    struct passwd passwd, *pw;
 
 #ifdef MAIN
     user = cline_user;
@@ -119,13 +122,16 @@
       return PAM_AUTH_ERR;
     }
 
-    if ( ! ( pw = getpwnam( user ) ) ) {
+    if (_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &pw) != 0)
+      pw = NULL;
+    if (!pw) {
       _pam_log(LOG_ERR,MODULE_NAME ": pam_get_uid; no such user %s",user);
       return PAM_USER_UNKNOWN;
     }
     
     if ( uid )   *uid   = pw->pw_uid;
     if ( userp ) *userp = user;
+    if ( ubuf ) free(ubuf);
     return PAM_SUCCESS;
   }
 
--- Linux-PAM-0.75/modules/pam_unix/md5_crypt.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_unix/md5_crypt.c	Mon Oct 22 14:24:48 2001
@@ -36,7 +36,7 @@
 {
 	const char *magic = "$1$";
 	/* This string is magic for this algorithm.  Having
-	 * it this way, we can get get better later on */
+	 * it this way, we can get better later on */
 	static char passwd[120], *p;
 	static const char *sp, *ep;
 	unsigned char final[16];
--- Linux-PAM-0.75/modules/pam_unix/pam_unix_acct.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_unix/pam_unix_acct.c	Mon Oct 22 14:24:48 2001
@@ -46,6 +46,8 @@
 #include <shadow.h>
 #include <time.h>		/* for time() */
 
+#define PAM_GETPWNAM_R
+#define PAM_GETSPNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* indicate that the following groups are defined */
@@ -71,8 +73,10 @@
 	const char *uname;
 	int retval, daysleft;
 	time_t curdays;
-	struct spwd *spent;
-	struct passwd *pwent;
+	struct spwd spwd, *spent;
+	struct passwd passwd, *pwent;
+	char *ubuf = NULL, *sbuf = NULL;
+	size_t ubuflen, sbuflen;
 	char buf[80];
 
 	D(("called."));
@@ -88,7 +92,8 @@
 		return PAM_USER_UNKNOWN;
 	}
 
-	pwent = getpwnam(uname);
+	if(_pam_getpwnam_r(uname, &passwd, &ubuf, &ubuflen, &pwent) != 0)
+		pwent = NULL;
 	if (!pwent) {
 		_log_err(LOG_ALERT, pamh
 			 ,"could not identify user (from getpwnam(%s))"
@@ -108,11 +113,16 @@
 			if (setreuid( -1, pwent->pw_uid ) == -1) {
 				setreuid( -1, 0 );
 				setreuid( 0, -1 );
-				if(setreuid( -1, pwent->pw_uid ) == -1)
+				if(setreuid( -1, pwent->pw_uid ) == -1) {
+					if (ubuf) {
+						free(ubuf);
+					}
 					return PAM_CRED_INSUFFICIENT;
+				}
 			}
 		}
-		spent = getspnam( uname );
+		if(_pam_getspnam_r(uname, &spwd, &sbuf, &sbuflen, &spent) != 0)
+			spent = NULL;
 		if (save_uid == pwent->pw_uid)
 			setreuid( save_uid, save_euid );
 		else {
@@ -122,17 +132,38 @@
 		}
 
 	} else if (!strcmp( pwent->pw_passwd, "x" )) {
-		spent = getspnam(uname);
+		if(_pam_getspnam_r(uname, &spwd, &sbuf, &sbuflen, &spent) != 0)
+			spent = NULL;
 	} else {
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_SUCCESS;
 	}
 
 	if (!spent)
-		if (ctrl & UNIX_BROKEN_SHADOW)
+		if (ctrl & UNIX_BROKEN_SHADOW) {
+			if (ubuf) {
+				free(ubuf);
+			}
+			if (sbuf) {
+				free(sbuf);
+			}
 			return PAM_SUCCESS;
+		}
 
-	if (!spent)
+	if (!spent) {
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_AUTHINFO_UNAVAIL;	/* Couldn't get username from shadow */
+	}
 
 	curdays = time(NULL) / (60 * 60 * 24);
 	D(("today is %d, last change %d", curdays, spent->sp_lstchg));
@@ -144,6 +175,12 @@
 		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
 			    "Your account has expired; please contact your system administrator");
 		D(("account expired"));
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_ACCT_EXPIRED;
 	}
 	if ((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
@@ -155,6 +192,12 @@
 		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
 			    "Your account has expired; please contact your system administrator");
 		D(("account expired 2"));
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_ACCT_EXPIRED;
 	}
 	D(("when was the last change"));
@@ -165,6 +208,12 @@
 		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
 			    "You are required to change your password immediately (root enforced)");
 		D(("need a new password"));
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_NEW_AUTHTOK_REQD;
 	}
 	if (((spent->sp_lstchg + spent->sp_max) < curdays) && (spent->sp_max != -1)) {
@@ -174,6 +223,12 @@
 		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
 			    "You are required to change your password immediately (password aged)");
 		D(("need a new password 2"));
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_NEW_AUTHTOK_REQD;
 	}
 	if ((curdays > (spent->sp_lstchg + spent->sp_max - spent->sp_warn))
@@ -189,6 +244,12 @@
 
 	D(("all done"));
 
+	if (ubuf) {
+		free(ubuf);
+	}
+	if (sbuf) {
+		free(sbuf);
+	}
 	return PAM_SUCCESS;
 }
 
--- Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c	Mon Oct 22 14:24:48 2001
@@ -61,6 +61,8 @@
 #include <crack.h>
 #endif
 
+#define PAM_GETPWNAM_R
+#define PAM_GETSPNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 /* indicate the following groups are defined */
@@ -252,7 +254,9 @@
 	int err = 0;
 	int oldmask;
 	int found = 0;
-	struct passwd *pwd = NULL;
+	struct passwd passwd, *pwd = NULL;
+	char *ubuf = NULL;
+	size_t ubuflen;
 
 	if (howmany < 0)
 		return retval;
@@ -302,7 +306,8 @@
 	}
 	fclose(opwfile);
 	if (!found) {
-		pwd = getpwnam(forwho);
+		if(_pam_getpwnam_r(forwho, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+			pwd = NULL;
 		if (pwd == NULL) {
 			retval = PAM_AUTHTOK_ERR;
 			err = 1;
@@ -326,6 +331,9 @@
 	else
 		unlink(OPW_TMPFILE);
 
+	if (ubuf) {
+		free(ubuf);
+	}
 	return retval;
 }
 
@@ -387,22 +395,29 @@
 
 static int _update_shadow(const char *forwho, char *towhat)
 {
-	struct spwd *spwdent = NULL, *stmpent = NULL;
+	struct spwd spwd, *spwdent = NULL, *stmpent = NULL;
 	struct stat st;
 	FILE *pwfile, *opwfile;
 	int retval = 0;
 	int err = 0;
 	int oldmask;
+	char *sbuf = NULL;
+	size_t sbuflen;
 
-	spwdent = getspnam(forwho);
+	if(_pam_getspnam_r(forwho, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+		spwdent = NULL;
 	if (spwdent == NULL)
 		return PAM_USER_UNKNOWN;
 	oldmask = umask(077);
 	pwfile = fopen(SH_TMPFILE, "w");
 	umask(oldmask);
 	opwfile = fopen("/etc/shadow", "r");
-	if (pwfile == NULL || opwfile == NULL)
+	if (pwfile == NULL || opwfile == NULL) {
+		if (sbuf) {
+			free(sbuf);
+		}
 		return PAM_AUTHTOK_ERR;
+	}
 	if(fstat(fileno(opwfile), &st) == -1) {
 		chown(SH_TMPFILE, 0, 0);
 		chmod(SH_TMPFILE, 0600);
@@ -440,20 +455,24 @@
 	else
 		unlink(SH_TMPFILE);
 
+	if (sbuf) {
+		free(sbuf);
+	}
 	return retval;
 }
 
 static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
 		       char *towhat, unsigned int ctrl, int remember)
 {
-	struct passwd *pwd = NULL;
+	struct passwd passwd, *pwd = NULL;
+	char *ubuf = NULL;
+	size_t ubuflen;
 	int retval = 0;
 
 	D(("called"));
 
-	setpwent();
-	pwd = getpwnam(forwho);
-	endpwent();
+	if(_pam_getpwnam_r(forwho, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 
 	if (pwd == NULL)
 		return PAM_AUTHTOK_ERR;
@@ -467,8 +486,12 @@
 		int err = 0;
 
 		/* Make RPC call to NIS server */
-		if ((master = getNISserver(pamh)) == NULL)
+		if ((master = getNISserver(pamh)) == NULL) {
+			if (ubuf) {
+				free(ubuf);
+			}
 			return PAM_TRY_AGAIN;
+		}
 
 		/* Initialize password information */
 		yppwd.newpw.pw_passwd = pwd->pw_passwd;
@@ -516,10 +539,16 @@
 #ifdef DEBUG
 		sleep(5);
 #endif
+		if (ubuf) {
+			free(ubuf);
+		}
 		return retval;
 	}
 	/* first, save old password */
 	if (save_old_password(forwho, fromwhat, remember)) {
+		if (ubuf) {
+			free(ubuf);
+		}
 		return PAM_AUTHTOK_ERR;
 	}
 	if (_unix_comesfromsource(forwho, 1, 0)) {
@@ -532,43 +561,55 @@
 		}
 	}
 
+	if (ubuf) {
+		free(ubuf);
+	}
 	return retval;
 }
 
 static int _unix_verify_shadow(const char *user, unsigned int ctrl)
 {
-	struct passwd *pwd = NULL;	/* Password and shadow password */
-	struct spwd *spwdent = NULL;	/* file entries for the user */
+	struct passwd passwd, *pwd = NULL;	/* Password and shadow */
+	struct spwd spwd, *spwdent = NULL;	/* file entries for the user */
 	time_t curdays;
+	char *ubuf = NULL, *sbuf = NULL;
+	size_t ubuflen, sbuflen;
 	int retval = PAM_SUCCESS;
 
 	/* UNIX passwords area */
-	setpwent();
-	pwd = getpwnam(user);	/* Get password file entry... */
-	endpwent();
+	if(_pam_getpwnam_r(user, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 	if (pwd == NULL)
 		return PAM_AUTHINFO_UNAVAIL;	/* We don't need to do the rest... */
 
 	if (strcmp(pwd->pw_passwd, "x") == 0) {
 		/* ...and shadow password file entry for this user, if shadowing
 		   is enabled */
-		setspent();
-		spwdent = getspnam(user);
-		endspent();
+		if(_pam_getspnam_r(user, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+			spwdent = NULL;
 
-		if (spwdent == NULL)
+		if (spwdent == NULL) {
+			if (ubuf) {
+				free(ubuf);
+			}
 			return PAM_AUTHINFO_UNAVAIL;
+		}
 	} else {
 		if (strcmp(pwd->pw_passwd,"*NP*") == 0) { /* NIS+ */                 
 			uid_t save_uid;
 
 			save_uid = geteuid();
 			seteuid (pwd->pw_uid);
-			spwdent = getspnam( user );
+			if(_pam_getspnam_r(user, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;
 			seteuid (save_uid);
 
-			if (spwdent == NULL)
+			if (spwdent == NULL) {
+				if (ubuf) {
+					free(ubuf);
+				}
 				return PAM_AUTHINFO_UNAVAIL;
+			}
 		} else
 			spwdent = NULL;
 	}
@@ -598,6 +639,12 @@
 				retval = PAM_ACCT_EXPIRED;
 		}
 	}
+	if (ubuf) {
+		free(ubuf);
+	}
+	if (sbuf) {
+		free(sbuf);
+	}
 	return retval;
 }
 
--- Linux-PAM-0.75/modules/pam_unix/support.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_unix/support.c	Mon Oct 22 14:24:48 2001
@@ -20,6 +20,8 @@
 #include <ctype.h>
 #include <rpcsvc/ypclnt.h>
 
+#define PAM_GETPWNAM_R
+#define PAM_GETSPNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 #include "../../libpam/include/security/pam_modules.h"
 
@@ -420,8 +422,10 @@
 
 int _unix_blankpasswd(unsigned int ctrl, const char *name)
 {
-	struct passwd *pwd = NULL;
-	struct spwd *spwdent = NULL;
+	struct passwd passwd, *pwd = NULL;
+	struct spwd spwd, *spwdent = NULL;
+	char *ubuf = NULL, *sbuf = NULL;
+	size_t ubuflen, sbuflen;
 	char *salt = NULL;
 	int retval;
 
@@ -437,7 +441,8 @@
 		return 0;	/* will fail but don't let on yet */
 
 	/* UNIX passwords area */
-	pwd = getpwnam(name);	/* Get password file entry... */
+	if(_pam_getpwnam_r(name, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 
 	if (pwd != NULL) {
 		if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
@@ -453,13 +458,18 @@
 				if (setreuid( -1, pwd->pw_uid ) == -1) {
 					setreuid( -1, 0 );
 					setreuid( 0, -1 );
-					if(setreuid( -1, pwd->pw_uid ) == -1)
+					if(setreuid( -1, pwd->pw_uid ) == -1) {
 						/* Will fail elsewhere. */
+						if (ubuf) {
+							free(ubuf);
+						}
 						return 0;
+					}
 				}
 			}
-	
-			spwdent = getspnam( name );
+
+			if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;	
 			if (save_uid == pwd->pw_uid)
 				setreuid( save_uid, save_euid );
 			else {
@@ -472,7 +482,8 @@
 			 * ...and shadow password file entry for this user,
 			 * if shadowing is enabled
 			 */
-			spwdent = getspnam(name);
+			if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;	
 		}
 		if (spwdent)
 			salt = x_strdup(spwdent->sp_pwdp);
@@ -494,6 +505,12 @@
 	if (salt)
 		_pam_delete(salt);
 
+	if (ubuf) {
+		free(ubuf);
+	}
+	if (sbuf) {
+		free(sbuf);
+	}
 	return retval;
 }
 
@@ -576,11 +593,13 @@
 int _unix_verify_password(pam_handle_t * pamh, const char *name
 			  ,const char *p, unsigned int ctrl)
 {
-	struct passwd *pwd = NULL;
-	struct spwd *spwdent = NULL;
+	struct passwd passwd, *pwd = NULL;
+	struct spwd spwd, *spwdent = NULL;
 	char *salt = NULL;
 	char *pp = NULL;
 	char *data_name;
+	char *ubuf = NULL, *sbuf = NULL;
+	size_t ubuflen, sbuflen;
 	int retval;
 
 	D(("called"));
@@ -597,7 +616,8 @@
 	D(("locating user's record"));
 
 	/* UNIX passwords area */
-	pwd = getpwnam(name);	/* Get password file entry... */
+	if(_pam_getpwnam_r(name, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 
 	if (pwd != NULL) {
 		if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
@@ -613,12 +633,17 @@
 				if (setreuid( -1, pwd->pw_uid ) == -1) {
 					setreuid( -1, 0 );
 					setreuid( 0, -1 );
-					if(setreuid( -1, pwd->pw_uid ) == -1)
+					if(setreuid( -1, pwd->pw_uid ) == -1) {
+						if (ubuf) {
+							free(ubuf);
+						}
 						return PAM_CRED_INSUFFICIENT;
+					}
 				}
 			}
-	
-			spwdent = getspnam( name );
+
+			if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;	
 			if (save_uid == pwd->pw_uid)
 				setreuid( save_uid, save_euid );
 			else {
@@ -631,7 +656,8 @@
 			 * ...and shadow password file entry for this user,
 			 * if shadowing is enabled
 			 */
-			spwdent = getspnam(name);
+			if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;	
 		}
 		if (spwdent)
 			salt = x_strdup(spwdent->sp_pwdp);
@@ -791,6 +817,13 @@
 	if (pp)
 		_pam_overwrite(pp);
 
+	if (ubuf) {
+		free(ubuf);
+	}
+	if (sbuf) {
+		free(sbuf);
+	}
+
 	D(("done [%d].", retval));
 
 	return retval;
--- Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c.reentrant	Mon Oct 22 14:24:48 2001
+++ Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c	Mon Oct 22 14:24:48 2001
@@ -28,6 +28,9 @@
 
 #define MAXPASS		200	/* the maximum length of a password */
 
+#define PAM_GETPWNAM_R
+#define PAM_GETPWUID_R
+#define PAM_GETSPNAM_R
 #include "../../libpam/include/security/_pam_macros.h"
 
 #include "md5.h"
@@ -83,25 +86,25 @@
 
 static int _unix_verify_password(const char *name, const char *p, int nullok)
 {
-	struct passwd *pwd = NULL;
-	struct spwd *spwdent = NULL;
+	struct passwd passwd, *pwd = NULL;
+	struct spwd spwd, *spwdent = NULL;
 	char *salt = NULL;
 	char *pp = NULL;
+	char *ubuf = NULL, *sbuf = NULL;
+	size_t ubuflen, sbuflen;
 	int retval = UNIX_FAILED;
 
 	/* UNIX passwords area */
-	setpwent();
-	pwd = getpwnam(name);	/* Get password file entry... */
-	endpwent();
+	if(_pam_getpwnam_r(name, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+		pwd = NULL;
 	if (pwd != NULL) {
 		if (strcmp(pwd->pw_passwd, "x") == 0) {
 			/*
 			 * ...and shadow password file entry for this user,
 			 * if shadowing is enabled
 			 */
-			setspent();
-			spwdent = getspnam(name);
-			endspent();
+			if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+				spwdent = NULL;
 			if (spwdent != NULL)
 				salt = x_strdup(spwdent->sp_pwdp);
 			else
@@ -112,7 +115,8 @@
 
 				save_uid = geteuid();
 				seteuid(pwd->pw_uid);
-				spwdent = getspnam(name);
+				if(_pam_getspnam_r(name, &spwd, &sbuf, &sbuflen, &spwdent) != 0)
+					spwdent = NULL;
 				seteuid(save_uid);
 
 				salt = x_strdup(spwdent->sp_pwdp);
@@ -124,13 +128,33 @@
 	if (pwd == NULL || salt == NULL) {
 		_log_err(LOG_ALERT, "check pass; user unknown");
 		p = NULL;
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return retval;
 	}
 
-	if (strlen(salt) == 0)
+	if (strlen(salt) == 0) {
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return (nullok == 0) ? UNIX_FAILED : UNIX_PASSED;
-	if (p == NULL)
+	}
+	if (p == NULL) {
+		if (ubuf) {
+			free(ubuf);
+		}
+		if (sbuf) {
+			free(sbuf);
+		}
 		return UNIX_FAILED;
+	}
 
 	/* the moment of truth -- do we agree with the password? */
 	retval = UNIX_FAILED;
@@ -170,21 +194,35 @@
 		pp = tp = NULL;
 	}
 
+	if (ubuf) {
+		free(ubuf);
+	}
+	if (sbuf) {
+		free(sbuf);
+	}
+
 	return retval;
 }
 
 static char *getuidname(uid_t uid)
 {
-	struct passwd *pw;
+	struct passwd passwd, *pw;
 	static char username[32];
+	char *ubuf = NULL;
+	size_t ubuflen;
 
-	pw = getpwuid(uid);
+	if(_pam_getpwuid_r(uid, &passwd, &ubuf, &ubuflen, &pw) != 0)
+		pw = NULL;
 	if (pw == NULL)
 		return NULL;
 
 	strncpy(username, pw->pw_name, sizeof(username));
 	username[sizeof(username) - 1] = '\0';
-	
+
+	if (ubuf) {
+		free(ubuf);
+	}
+
 	return username;
 }
 
--- Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c.reentrant	Mon Oct 22 14:39:12 2001
+++ Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c	Mon Oct 22 14:42:45 2001
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <syslog.h>
 #include <stdarg.h>
+#include <limits.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
@@ -40,9 +41,14 @@
 
 #define PAM_SM_AUTH
 #define PAM_SM_ACCOUNT
-
 #include "../../libpam/include/security/pam_modules.h"
 
+#define PAM_GETPWNAM_R
+#define PAM_GETPWUID_R
+#define PAM_GETGRNAM_R
+#define PAM_GETGRGID_R
+#include "../../libpam/include/security/_pam_macros.h"
+
 /* some syslogging */
 
 static void _pam_log(int err, const char *format, ...)
@@ -115,10 +121,12 @@
      int ctrl = 0;
      const char *username = NULL;
      char *fromsu = NULL;
-     struct passwd *pwd = NULL, *tpwd = NULL;
-     struct group *grp = NULL;
+     struct passwd passwd, *pwd = NULL, *tpwd = NULL;
+     struct group group, *grp = NULL;
      int retval = PAM_AUTH_ERR;
      char use_group[BUFSIZ];
+     char *ubuf = NULL, *gbuf = NULL, *tbuf = NULL;
+     size_t ubuflen, gbuflen, tbuflen;
     
      ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group));
      retval = pam_get_user(pamh,&username,"login: ");
@@ -129,7 +137,8 @@
      }
 
      /* su to a uid 0 account ? */
-     pwd = getpwnam(username);
+     if (_pam_getpwnam_r(username, &passwd, &ubuf, &ubuflen, &pwd) != 0)
+	pwd = NULL;
      if (!pwd) {
         if (ctrl & PAM_DEBUG_ARG)
             _pam_log(LOG_NOTICE,"unknown user %s",username);
@@ -143,7 +152,8 @@
       */
 
      if (ctrl & PAM_USE_UID_ARG) {
-         tpwd = getpwuid(getuid());
+         if (_pam_getpwuid_r(getuid(), &passwd, &tbuf, &tbuflen, &tpwd) != 0)
+	    tpwd = NULL;
          if (!tpwd) {
             if (ctrl & PAM_DEBUG_ARG)
                 _pam_log(LOG_NOTICE,"who is running me ?!");
@@ -152,8 +162,9 @@
          fromsu = tpwd->pw_name;
      } else {
          fromsu = getlogin();
-         tpwd = getpwnam(fromsu);
-         if (!fromsu || !tpwd) {
+	 if (_pam_getpwnam_r(fromsu, &passwd, &tbuf, &tbuflen, &tpwd) != 0)
+	     tpwd = NULL;
+	 if((!fromsu) || (!tpwd)) {
              if (ctrl & PAM_DEBUG_ARG)
                 _pam_log(LOG_NOTICE,"who is running me ?!");
              return PAM_SERVICE_ERR;
@@ -161,11 +172,15 @@
      }
      
      if (!use_group[0]) {
-	 if ((grp = getgrnam("wheel")) == NULL) {
-	     grp = getgrgid(0);
+	 if (_pam_getgrnam_r("wheel", &group, &gbuf, &gbuflen, &grp) != 0)
+	     grp = NULL;
+	 if (grp == NULL) {
+	 	if(_pam_getgrgid_r(0, &group, &gbuf, &gbuflen, &grp) != 0)
+			grp = NULL;
 	 }
      } else
-	 grp = getgrnam(use_group);
+	 if(_pam_getgrnam_r(use_group, &group, &gbuf, &gbuflen, &grp) != 0)
+		grp = NULL;
         
      if (!grp || (!grp->gr_mem && (tpwd->pw_gid != grp->gr_gid))) {
         if (ctrl & PAM_DEBUG_ARG) {
@@ -174,14 +189,33 @@
             else
                 _pam_log(LOG_NOTICE,"no members in '%s' group",use_group);
         }
-        if (ctrl & PAM_DENY_ARG)
+        if (ctrl & PAM_DENY_ARG) {
             /* if this was meant to deny access to the members
              * of this group and the group does not exist, allow
              * access
              */
+            if (ubuf) {
+                free(ubuf);
+	    }
+            if (gbuf) {
+                free(gbuf);
+	    }
+            if (tbuf) {
+                free(tbuf);
+	    }
             return PAM_IGNORE;
-        else
+	} else {
+            if (ubuf) {
+                free(ubuf);
+	    }
+            if (gbuf) {
+                free(gbuf);
+	    }
+            if (tbuf) {
+                free(tbuf);
+	    }
             return PAM_AUTH_ERR;
+	}
      }
         
      if (is_on_list(grp->gr_mem, fromsu) || (tpwd->pw_gid == grp->gr_gid)) {
@@ -189,6 +223,15 @@
             _pam_log(LOG_NOTICE,"Access %s to '%s' for '%s'",
                      (ctrl & PAM_DENY_ARG)?"denied":"granted",
                      fromsu,username);
+        if (ubuf) {
+            free(ubuf);
+	}
+        if (gbuf) {
+            free(gbuf);
+	}
+        if (tbuf) {
+            free(tbuf);
+	}
         if (ctrl & PAM_DENY_ARG)
             return PAM_PERM_DENIED;
         else
@@ -201,6 +244,15 @@
      if (ctrl & PAM_DEBUG_ARG)
         _pam_log(LOG_NOTICE,"Access %s for '%s' to '%s'",
         (ctrl & PAM_DENY_ARG)?"granted":"denied",fromsu,username);
+     if (ubuf) {
+        free(ubuf);
+     }
+     if (gbuf) {
+        free(gbuf);
+     }
+     if (tbuf) {
+        free(tbuf);
+     }
      if (ctrl & PAM_DENY_ARG)
         if (ctrl & PAM_TRUST_ARG)
             return PAM_SUCCESS;
