Miscellaneous string-handling changes.
diff -uNr Linux-PAM-0.75/modules/pam_env/pam_env.c Linux-PAM-0.75/modules/pam_env/pam_env.c
--- Linux-PAM-0.75/modules/pam_env/pam_env.c	Sun Nov 19 18:54:03 2000
+++ Linux-PAM-0.75/modules/pam_env/pam_env.c	Tue Jul 10 00:14:23 2001
@@ -588,7 +588,8 @@
 	  _log_err(LOG_ERR, "Unterminated expandable variable: <%s>", orig-2);
 	  return PAM_ABORT;
 	}
-	strncpy(tmpval, orig, (size_t) BUF_SIZE);
+	strncpy(tmpval, orig, sizeof(tmpval));
+	tmpval[sizeof(tmpval) - 1] = '\0';
 	orig=ptr;
 	/* 
 	 * so, we know we need to expand tmpval, it is either 
diff -uNr Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c
--- Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c	Tue Jun 20 18:11:45 2000
+++ Linux-PAM-0.75/modules/pam_mkhomedir/pam_mkhomedir.c	Tue Jul 10 00:14:23 2001
@@ -89,12 +89,13 @@
       else if (!strncmp(*argv,"umask=",6))
 	 UMask = strtol(*argv+6,0,0);
       else if (!strncmp(*argv,"skel=",5))
-	 strcpy(SkelDir,*argv+5);
+	 strncpy(SkelDir,*argv+5,sizeof(SkelDir)-1);
       else
       {
 	 _log_err(LOG_ERR, "unknown option; %s", *argv);
       }
    }
+   SkelDir[sizeof(SkelDir) - 1] = '\0';
 
    D(("ctrl = %o", ctrl));
    return ctrl;
diff -uNr Linux-PAM-0.75/modules/pam_unix/md5_crypt.c Linux-PAM-0.75/modules/pam_unix/md5_crypt.c
--- Linux-PAM-0.75/modules/pam_unix/md5_crypt.c	Tue Jun 20 18:12:03 2000
+++ Linux-PAM-0.75/modules/pam_unix/md5_crypt.c	Tue Jul 10 00:14:23 2001
@@ -89,6 +89,8 @@
 			MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
 
 	/* Now make the output string */
+	if(strlen(magic) + sl + 1 + 1 >= sizeof(passwd))
+		return NULL;
 	strcpy(passwd, magic);
 	strncat(passwd, sp, sl);
 	strcat(passwd, "$");
diff -uNr Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c
--- Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c	Sun Nov 26 02:40:04 2000
+++ Linux-PAM-0.75/modules/pam_wheel/pam_wheel.c	Tue Jul 10 00:14:23 2001
@@ -75,10 +74,13 @@
 #define PAM_TRUST_ARG       0x0004
 #define PAM_DENY_ARG        0x0010  
 
-static int _pam_parse(int argc, const char **argv, char *use_group)
+static int _pam_parse(int argc, const char **argv, char *use_group,
+		      size_t group_length)
 {
      int ctrl=0;
 
+     memset(use_group, '\0', group_length);
+
      /* step through arguments */
      for (ctrl=0; argc-- > 0; ++argv) {
 
@@ -93,7 +95,7 @@
           else if (!strcmp(*argv,"deny"))
                ctrl |= PAM_DENY_ARG;
           else if (!strncmp(*argv,"group=",6))
-                strcpy(use_group,*argv+6);
+                strncpy(use_group,*argv+6,group_length-1);
           else {
                _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
           }
@@ -117,11 +117,8 @@
      int retval = PAM_AUTH_ERR;
      char use_group[BUFSIZ];
     
-     /* Init the optional group */
-     bzero(use_group,BUFSIZ);
-     
-     ctrl = _pam_parse(argc, argv, use_group);
-     retval = pam_get_user(pamh,&username,NULL);
+     ctrl = _pam_parse(argc, argv, use_group, sizeof(use_group));
+     retval = pam_get_user(pamh,&username,"login: ");
      if ((retval != PAM_SUCCESS) || (!username)) {
         if (ctrl & PAM_DEBUG_ARG)
             _pam_log(LOG_DEBUG,"can not get the username");
diff -uNr Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c
--- Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c	Sat Feb 10 17:15:23 2001
+++ Linux-PAM-0.75/modules/pam_cracklib/pam_cracklib.c	Tue Jul 10 00:14:23 2001
@@ -123,7 +123,7 @@
 	 if (!strcmp(*argv,"debug"))
 	     ctrl |= PAM_DEBUG_ARG;
 	 else if (!strncmp(*argv,"type=",5))
-	     strcpy(opt->prompt_type, *argv+5);
+	     strncpy(opt->prompt_type, *argv+5, sizeof(opt->prompt_type) - 1);
 	 else if (!strncmp(*argv,"retry=",6)) {
 	     opt->retry_times = strtol(*argv+6,&ep,10);
 	     if (!ep || (opt->retry_times < 1))
@@ -162,6 +162,7 @@
 	     _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
 	 }
      }
+     opt->prompt_type[sizeof(opt->prompt_type) - 1] = '\0';
 
      return ctrl;
 }
@@ -444,7 +445,7 @@
         char remark[BUFSIZ];
         
         memset(remark,0,sizeof(remark));
-        sprintf(remark,"BAD PASSWORD: %s",msg);
+        snprintf(remark,sizeof(remark),"BAD PASSWORD: %s",msg);
         if (ctrl && PAM_DEBUG_ARG)
             _pam_log(LOG_NOTICE, "new passwd fails strength check: %s",
                                   msg);
@@ -489,7 +490,7 @@
 	D(("prelim check"));
 
         memset(buf,0,sizeof(buf)); /* zero the buffer */
-        sprintf(buf,"%s.pwd",CRACKLIB_DICTPATH);
+        snprintf(buf,sizeof(buf),"%s.pwd",CRACKLIB_DICTPATH);
 
         if (!stat(buf,&st) && st.st_size)
             return PAM_SUCCESS;
@@ -560,7 +561,8 @@
 	} else {
             /* Prepare to ask the user for the first time */
             memset(prompt,0,sizeof(prompt));
-            sprintf(prompt,PROMPT1,options.prompt_type);
+            snprintf(prompt,sizeof(prompt),PROMPT1,options.prompt_type,
+		     options.prompt_type[0]?" ":"");
             pmsg[0] = &msg[0];
             msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
             msg[0].msg = prompt;
@@ -604,7 +606,7 @@
             if ((crack_msg = FascistCheck(token1, cracklib_dictpath))) {
                 if (ctrl && PAM_DEBUG_ARG)
                     _pam_log(LOG_DEBUG,"bad password: %s",crack_msg);
-                sprintf(remark,"BAD PASSWORD: %s", crack_msg);
+                snprintf(remark,sizeof(remark),"BAD PASSWORD: %s", crack_msg);
                 make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
                 if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
                     retval = PAM_AUTHTOK_ERR;
@@ -640,7 +642,8 @@
 
         if (options.use_authtok == 0) {
             bzero(prompt,sizeof(prompt));
-            sprintf(prompt,PROMPT2,options.prompt_type);
+            snprintf(prompt,sizeof(prompt),PROMPT2,options.prompt_type,
+		     options.prompt_type[0]?" ":"");
             pmsg[0] = &msg[0];
             msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
             msg[0].msg = prompt;
diff -uNr Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c
--- Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c	Sat Feb 10 17:33:10 2001
+++ Linux-PAM-0.75/modules/pam_lastlog/pam_lastlog.c	Tue Jul 10 00:14:23 2001
@@ -334,9 +334,9 @@
 	    }
 
 	    /* copy to last_login */
-	    strncpy(last_login.ll_host, remote_host
-		    , sizeof(last_login.ll_host));
-	    remote_host = NULL;
+	    strncpy(last_login.ll_host, remote_host,
+		    sizeof(last_login.ll_host));
+	    last_login.ll_host[sizeof(last_login.ll_host) - 1] = '\0';
 
 	    /* set the terminal line */
 	    (void) pam_get_item(pamh, PAM_TTY, (const void **)&terminal_line);
@@ -350,8 +350,9 @@
 	    D(("terminal = %s", terminal_line));
 
 	    /* copy to last_login */
-	    strncpy(last_login.ll_line, terminal_line
-		    , sizeof(last_login.ll_line));
+	    strncpy(last_login.ll_line, terminal_line,
+		    sizeof(last_login.ll_line));
+	    last_login.ll_host[sizeof(last_login.ll_host) - 1] = '\0';
 	    terminal_line = NULL;
 
 	    D(("locking last_log file"));
diff -uNr Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c
--- Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c	Sun Nov 19 18:54:04 2000
+++ Linux-PAM-0.75/modules/pam_listfile/pam_listfile.c	Tue Jul 10 00:14:23 2001
@@ -75,20 +75,16 @@
     if (!strlen(group_name))
         return 0;
     bzero(uname, sizeof(uname));
-    strncpy(uname, user_name, BUFSIZ-1);
+    strncpy(uname, user_name, sizeof(uname)-1);
     bzero(gname, sizeof(gname));
-    strncpy(gname, group_name, BUFSIZ-1);
+    strncpy(gname, group_name, sizeof(gname)-1);
         
-    setpwent();
     pwd = getpwnam(uname);
-    endpwent();
     if (!pwd)
         return 0;
 
     /* the info about this group */
-    setgrent();
     grp = getgrnam(gname);
-    endgrent();
     if (!grp)
         return 0;
     
@@ -97,9 +93,7 @@
         return 1;
 
     /* next check: user primary group is group_name ? */
-    setgrent();
     pgrp = getgrgid(pwd->pw_gid);
-    endgrent();
     if (!pgrp)
         return 0;
     if (!strcmp(pgrp->gr_name, gname))
@@ -120,6 +114,8 @@
 #define APPLY_TYPE_USER		2
 #define APPLY_TYPE_GROUP	3
 
+#define LESSER(a, b) ((a) < (b) ? (a) : (b))
+
 PAM_EXTERN
 int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
@@ -146,14 +142,16 @@
     for(i=0; i < argc; i++) {
 	{
 	    char *junk;
-	    junk = (char *) malloc(strlen(argv[i])+1);
-	    if (junk == NULL) {
-		return PAM_BUF_ERR;
+	    memset(mybuf,'\0',sizeof(mybuf));
+	    memset(myval,'\0',sizeof(mybuf));
+	    junk = strchr(argv[i], '=');
+	    if((junk == NULL) || (junk - argv[i]) >= sizeof(mybuf)) {
+		_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Bad option: \"%s\"",
+			 argv[i]);
+		continue;
 	    }
-	    strcpy(junk,argv[i]);
-	    strncpy(mybuf,strtok(junk,"="),255);
-	    strncpy(myval,strtok(NULL,"="),255);
-	    free(junk);
+	    strncpy(mybuf, argv[i], LESSER(junk - argv[i], sizeof(mybuf) - 1));
+	    strncpy(myval, junk + 1, sizeof(myval) - 1);
 	}
 	if(!strcmp(mybuf,"onerr"))
 	    if(!strcmp(myval,"succeed"))
@@ -192,6 +190,7 @@
 		    citem = 0;
 	    } else if(!strcmp(mybuf,"apply")) {
 		apply_type=APPLY_TYPE_NONE;
+		memset(apply_val,'\0',sizeof(apply_val));
 		if (myval[0]=='@') {
 		    apply_type=APPLY_TYPE_GROUP;
 		    strncpy(apply_val,myval+1,sizeof(apply_val)-1);
@@ -290,10 +289,18 @@
     if(extitem) {
 	switch(extitem) {
 	    case EI_GROUP:
-		setpwent();
 		userinfo = getpwnam(citemp);
-		setgrent();
+		if(userinfo == NULL) {
+			_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed",
+				 citemp);
+			return onerr;
+		}
 		grpinfo = getgrgid(userinfo->pw_gid);
+		if(grpinfo == NULL) {
+			_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getgrgid(%d) failed",
+				 (int)userinfo->pw_gid);
+			return onerr;
+		}
 		itemlist[0] = x_strdup(grpinfo->gr_name);
 		setgrent();
 		for (i=1; (i < sizeof(itemlist)/sizeof(itemlist[0])-1) &&
@@ -302,18 +309,20 @@
 			itemlist[i++] = x_strdup(grpinfo->gr_name);
 		    }
                 }
-		itemlist[i] = NULL;
 		endgrent();
-		endpwent();
+		itemlist[i] = NULL;
 		break;
 	    case EI_SHELL:
-		setpwent();
 		userinfo = getpwnam(citemp); /* 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;
-		endpwent();
 		break;
 	    default:
 		_pam_log(LOG_ERR,
diff -uNr Linux-PAM-0.75/modules/pam_unix/support.c Linux-PAM-0.75/modules/pam_unix/support.c
--- Linux-PAM-0.75/modules/pam_unix/support.c	Sun Feb 11 01:33:53 2001
+++ Linux-PAM-0.75/modules/pam_unix/support.c	Tue Jul 10 00:14:23 2001
@@ -122,9 +122,11 @@
 		D(("PAM_getlogin ttyname: %s", curr_tty));
 		curr_tty += 5;
 		setutent();
-		strncpy(line.ut_line, curr_tty, sizeof line.ut_line);
+		strncpy(line.ut_line, curr_tty, sizeof(line.ut_line));
+		line.ut_line[sizeof(line.ut_line) - 1] = '\0';
 		if ((ut = getutline(&line)) != NULL) {
 			strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
+			curr_user[sizeof(curr_user) - 1] = '\0';
 			retval = curr_user;
 		}
 		endutent();
diff -uNr Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c
--- Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c	Sun Feb 11 01:33:53 2001
+++ Linux-PAM-0.75/modules/pam_unix/unix_chkpwd.c	Tue Jul 10 00:14:23 2001
@@ -171,9 +171,8 @@
 	if (pw == NULL)
 		return NULL;
 
-	memset(username, 0, 32);
-	strncpy(username, pw->pw_name, 32);
-	username[31] = '\0';
+	strncpy(username, pw->pw_name, sizeof(username));
+	username[sizeof(username) - 1] = '\0';
 	
 	return username;
 }
diff -uNr Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c
--- Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c	Sun Feb 11 01:33:53 2001
+++ Linux-PAM-0.75/modules/pam_unix/pam_unix_passwd.c	Tue Jul 10 00:14:23 2001
@@ -284,9 +284,9 @@
 			}
 			pass = crypt_md5_wrapper(oldpass);
 			if (s_pas == NULL)
-				sprintf(nbuf, "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass);
+				snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass);
 			else
-				sprintf(nbuf, "%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass);
+				snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass);
 			if (fputs(nbuf, pwfile) < 0) {
 				retval = PAM_AUTHTOK_ERR;
 				err = 1;
@@ -307,7 +307,7 @@
 			err = 1;
 		} else {
 			pass = crypt_md5_wrapper(oldpass);
-			sprintf(nbuf, "%s:%d:1:%s\n", forwho, pwd->pw_uid, pass);
+			snprintf(nbuf, sizeof(nbuf), "%s:%d:1:%s\n", forwho, pwd->pw_uid, pass);
 			if (fputs(nbuf, pwfile) < 0) {
 				retval = PAM_AUTHTOK_ERR;
 				err = 1;
