changeset 10008:b5d6e292a984

PSARC 2008/295 NISPASSWD_VERS2 6563443 nisaddcred and chkey have issues in md5 password encyption with passwords > eight characters
author Ashok Kumar T <Ashok.Kumar@Sun.COM>
date Wed, 01 Jul 2009 22:27:19 +0530
parents 1b2a9b424228
children 11b987df0f95
files usr/src/cmd/keyserv/chkey.c usr/src/cmd/keyserv/newkey.c usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c usr/src/head/rpcsvc/nispasswd.x usr/src/lib/libnsl/common/llib-lnsl usr/src/lib/libnsl/common/mapfile-vers usr/src/lib/libnsl/nis/gen/npd_lib.c usr/src/lib/passwdutil/nisplus_attr.c usr/src/lib/passwdutil/npd_clnt.c
diffstat 13 files changed, 929 insertions(+), 475 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/keyserv/chkey.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/keyserv/chkey.c	Wed Jul 01 22:27:19 2009 +0530
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -49,6 +49,7 @@
 #include <rpc/rpc.h>
 #include <rpc/key_prot.h>
 #include <rpcsvc/nis.h>
+#include <rpcsvc/nispasswd.h>
 #include <rpcsvc/nis_dhext.h>
 #include <rpcsvc/ypclnt.h>
 #include <nsswitch.h>
@@ -96,6 +97,8 @@
 char		**rpc_pws = NULL; /* List of S-RPC passwords */
 int		rpc_pw_count = 0; /* Number of passwords entered by user */
 char		*login_pw = NULL; /* Unencrypted login password */
+char		short_login_pw[DESCREDPASSLEN + 1];
+/* Short S-RPC password, which has first 8 chars of login_pw */
 
 static int add_cred_obj(nis_object *, char *);
 static nis_error auth_exists(char *, char *, char *, char *);
@@ -153,7 +156,7 @@
 usage()
 {
 	fprintf(stderr, "usage: %s [-p] [-s ldap | nisplus | nis | files] \n",
-		program_name);
+	    program_name);
 	exit(1);
 }
 
@@ -169,8 +172,8 @@
 			char		*crypt = NULL;
 
 			if (!xencrypt_g(slist[mcount], CURMECH->keylen,
-					CURMECH->algtype, login_pw, netname,
-					&crypt, TRUE)) {
+			    CURMECH->algtype, short_login_pw, netname,
+			    &crypt, TRUE)) {
 				/* Could not crypt key */
 				crypt = NULL;
 			} else
@@ -181,15 +184,15 @@
 		char		*crypt = NULL;
 
 		if (!(crypt =
-			(char *)malloc(HEXKEYBYTES + KEYCHECKSUMSIZE + 1))) {
+		    (char *)malloc(HEXKEYBYTES + KEYCHECKSUMSIZE + 1))) {
 			fprintf(stderr, "%s: Malloc failure.\n", program_name);
 			exit(1);
 		}
 
-		memcpy(crypt, slist[0], HEXKEYBYTES);
-		memcpy(crypt + HEXKEYBYTES, slist[0], KEYCHECKSUMSIZE);
+		(void) memcpy(crypt, slist[0], HEXKEYBYTES);
+		(void) memcpy(crypt + HEXKEYBYTES, slist[0], KEYCHECKSUMSIZE);
 		crypt[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
-		xencrypt(crypt, login_pw);
+		xencrypt(crypt, short_login_pw);
 
 		clist[0] = crypt;
 		ccount++;
@@ -197,7 +200,7 @@
 
 	if (!ccount) {
 		fprintf(stderr, "%s: Could not encrypt any secret keys.\n",
-			program_name);
+		    program_name);
 		exit(1);
 	}
 }
@@ -211,7 +214,8 @@
 
 	if (!nomech) {
 		assert(mechs && mechs[0]);
-		for (mcount = 0; CURMECH; mcount++);
+		for (mcount = 0; CURMECH; mcount++)
+			;
 	} else
 		mcount = 1;
 
@@ -245,17 +249,17 @@
 			hexkeylen = ((CURMECH->keylen / 8) * 2) + 1;
 			if (!(public = (char *)malloc(hexkeylen))) {
 				fprintf(stderr, "%s: Malloc failure.\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 			if (!getpublickey_g(netname, CURMECH->keylen,
-					    CURMECH->algtype, public,
-					    hexkeylen)) {
+			    CURMECH->algtype, public,
+			    hexkeylen)) {
 				/* Could not get public key */
 				fprintf(stderr,
-					"Could not get %s public key.\n",
-					VALID_ALIAS(CURMECH->alias) ?
-					CURMECH->alias : "");
+				    "Could not get %s public key.\n",
+				    VALID_ALIAS(CURMECH->alias) ?
+				    CURMECH->alias : "");
 				free(public);
 				public = NULL;
 			} else
@@ -281,11 +285,11 @@
 
 	if (!pcount) {
 		fprintf(stderr, "%s: cannot get any public keys for %s.\n",
-			program_name, pw->pw_name);
+		    program_name, pw->pw_name);
 		error_msg();
 		fprintf(stderr,
 	"Make sure that the public keys are stored in the domain %s.\n",
-			local_domain);
+		    local_domain);
 		exit(1);
 	}
 }
@@ -309,22 +313,22 @@
 
 			if (!(public = malloc(hexkeylen))) {
 				fprintf(stderr, "%s: Malloc failure.\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 			if (!(secret = malloc(hexkeylen))) {
 				fprintf(stderr, "%s: Malloc failure.\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 
 			if (!(__gen_dhkeys_g(public, secret, CURMECH->keylen,
-					CURMECH->algtype, login_pw))) {
+			    CURMECH->algtype, short_login_pw))) {
 				/* Could not generate key pair */
 				fprintf(stderr,
 				"WARNING  Could not generate key pair %s\n",
-					VALID_ALIAS(CURMECH->alias) ?
-					CURMECH->alias : "");
+				    VALID_ALIAS(CURMECH->alias) ?
+				    CURMECH->alias : "");
 				free(public);
 				free(secret);
 				public = NULL;
@@ -348,7 +352,7 @@
 			exit(1);
 		}
 
-		__gen_dhkeys(public, secret, login_pw);
+		__gen_dhkeys(public, secret, short_login_pw);
 
 		plist[0] = public;
 		slist[0] = secret;
@@ -366,19 +370,25 @@
 	char	baseprompt[] = "Please enter the login password for";
 	char	prompt[BUFSIZ];
 	char	*en_login_pw = spw->sp_pwdp;
+	char    short_en_login_pw[DESCREDPASSLEN + 1];
 	char	*try_en_login_pw;
 	bool_t	pwmatch = FALSE;
 	int	done = 0, tries = 0, pcount;
 
 	snprintf(prompt, BUFSIZ, "%s %s:", baseprompt, pw->pw_name);
 
+	(void) strlcpy(short_en_login_pw, en_login_pw,
+	    sizeof (short_en_login_pw));
+
 	if (en_login_pw && (strlen(en_login_pw) != 0)) {
 		for (pcount = 0; pcount < rpc_pw_count; pcount++) {
 			char	*try_en_rpc_pw;
 
-			try_en_rpc_pw = crypt(rpc_pws[pcount], en_login_pw);
-			if (strcmp(try_en_rpc_pw, en_login_pw) == 0) {
+		try_en_rpc_pw = crypt(rpc_pws[pcount], short_en_login_pw);
+			if (strcmp(try_en_rpc_pw, short_en_login_pw) == 0) {
 				login_pw = rpc_pws[pcount];
+				(void) strlcpy(short_login_pw, login_pw,
+				    sizeof (short_login_pw));
 				pwmatch = TRUE;
 				break;
 			}
@@ -387,14 +397,16 @@
 			/* pw don't match */
 			while (!done) {
 				/* ask for the pw */
-				login_pw = getpass(prompt);
+				login_pw = getpassphrase(prompt);
+				(void) strlcpy(short_login_pw, login_pw,
+				    sizeof (short_login_pw));
 				if (login_pw && strlen(login_pw)) {
 					/* pw was not empty */
 					try_en_login_pw = crypt(login_pw,
-								en_login_pw);
+					    en_login_pw);
 					/* compare the pw's */
 					if (!(strcmp(try_en_login_pw,
-							en_login_pw))) {
+					    en_login_pw))) {
 						/* pw was correct */
 						return;
 					} else {
@@ -402,15 +414,15 @@
 						if (tries++) {
 							/* Sorry */
 							fprintf(stderr,
-								"Sorry.\n");
+							    "Sorry.\n");
 							exit(1);
 						} else {
 							/* Try again */
 							snprintf(prompt,
-									BUFSIZ,
+							    BUFSIZ,
 							"Try again. %s %s:",
-								baseprompt,
-								pw->pw_name);
+							    baseprompt,
+							    pw->pw_name);
 						}
 					}
 				} else {
@@ -419,15 +431,15 @@
 						/* Unchanged */
 						fprintf(stderr,
 					"%s: key-pair(s) unchanged for %s.\n",
-							program_name,
-							pw->pw_name);
+						    program_name,
+						    pw->pw_name);
 						exit(1);
 					} else {
 						/* Need a password */
 						snprintf(prompt, BUFSIZ,
 						"Need a password. %s %s:",
-								baseprompt,
-								pw->pw_name);
+						    baseprompt,
+						    pw->pw_name);
 					}
 				}
 			}
@@ -438,7 +450,7 @@
 		/* no pw found */
 		fprintf(stderr,
 		"%s: no passwd found for %s in the shadow passwd entry.\n",
-			program_name, pw->pw_name);
+		    program_name, pw->pw_name);
 		exit(1);
 	}
 }
@@ -453,24 +465,24 @@
 
 	if (flavor)
 		snprintf(prompt, BUFSIZ,
-			"Please enter the %s Secure-RPC password for %s:",
-			flavor, pw->pw_name);
+		    "Please enter the %s Secure-RPC password for %s:",
+		    flavor, pw->pw_name);
 	else
 		snprintf(prompt, BUFSIZ,
-				"Please enter the Secure-RPC password for %s:",
-				pw->pw_name);
+		    "Please enter the Secure-RPC password for %s:",
+		    pw->pw_name);
 
 	cur_pw = getpass(prompt);
 	if (!cur_pw) {
 		/* No changes */
 		fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n",
-			program_name, pw->pw_name);
+		    program_name, pw->pw_name);
 		exit(1);
 	}
 
 	rpc_pw_count++;
 	if (!(rpc_pws =
-		(char **)realloc(rpc_pws, sizeof (char *) * rpc_pw_count))) {
+	    (char **)realloc(rpc_pws, sizeof (char *) * rpc_pw_count))) {
 		fprintf(stderr, "%s: Realloc failure.\n", program_name);
 		exit(1);
 	}
@@ -495,17 +507,17 @@
 
 			hexkeylen = ((CURMECH->keylen / 8) * 2) + 1;
 			if (!(secret = (char *)calloc(hexkeylen,
-							sizeof (char)))) {
+			    sizeof (char)))) {
 				fprintf(stderr, "%s: Malloc failure.\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 
 			for (pcount = 0; pcount < rpc_pw_count; pcount++) {
 				if (!getsecretkey_g(netname, CURMECH->keylen,
-						    CURMECH->algtype, secret,
-						    hexkeylen,
-						    rpc_pws[pcount]))
+				    CURMECH->algtype, secret,
+				    hexkeylen,
+				    rpc_pws[pcount]))
 					continue;
 
 				if (secret[0] == 0)
@@ -524,11 +536,11 @@
 					 */
 					getrpcpws(CURMECH->alias);
 					if (!getsecretkey_g(netname,
-							    CURMECH->keylen,
-							    CURMECH->algtype,
-							    secret,
-							    hexkeylen,
-							    rpc_pws[pcount])) {
+					    CURMECH->keylen,
+					    CURMECH->algtype,
+					    secret,
+					    hexkeylen,
+					    rpc_pws[pcount])) {
 						/*
 						 * Could not retreive
 						 * secret key, abort
@@ -551,7 +563,7 @@
 				} else {
 					fprintf(stderr,
 					"%s: key-pair unchanged for %s.\n",
-						program_name, pw->pw_name);
+					    program_name, pw->pw_name);
 					exit(1);
 				}
 			} else
@@ -570,8 +582,8 @@
 	getsecrets_tryagain:
 		if (!getsecretkey(netname, secret, rpc_pws[0])) {
 			fprintf(stderr,
-				"%s: could not get secret key for '%s'\n",
-				program_name, netname);
+			    "%s: could not get secret key for '%s'\n",
+			    program_name, netname);
 			exit(1);
 		}
 
@@ -586,8 +598,8 @@
 				goto getsecrets_tryagain;
 			} else {
 				fprintf(stderr,
-					"%s: key-pair unchanged for %s.\n",
-					program_name, pw->pw_name);
+				    "%s: key-pair unchanged for %s.\n",
+				    program_name, pw->pw_name);
 				exit(1);
 			}
 		}
@@ -599,7 +611,7 @@
 	if (!scount) {
 		(void) fprintf(stderr,
 		"%s: could not get nor decrypt any secret keys for '%s'\n",
-					program_name, netname);
+		    program_name, netname);
 		error_msg();
 		exit(1);
 	}
@@ -635,7 +647,7 @@
 		perror("Warning: NFS credentials not destroyed");
 #endif /* NFS_AUTH */
 
-	memcpy(netst.st_priv_key, secret, HEXKEYBYTES);
+	(void) memcpy(netst.st_priv_key, secret, HEXKEYBYTES);
 
 	netst.st_pub_key[0] = '\0';
 	netst.st_netname = strdup(netname);
@@ -659,15 +671,15 @@
 			if (keylen == CURMECH->keylen &&
 			    algtype == CURMECH->algtype) {
 				if (key_setnet_g(netname, slist[mcount],
-							CURMECH->keylen,
-							NULL, 0,
-							CURMECH->algtype)
+				    CURMECH->keylen,
+				    NULL, 0,
+				    CURMECH->algtype)
 				    < 0)
 					fprintf(stderr,
 					"Could not set %s's %s secret key\n",
-						netname,
-					VALID_ALIAS(CURMECH->alias) ?
-						CURMECH->alias : "");
+					    netname,
+					    VALID_ALIAS(CURMECH->alias) ?
+					    CURMECH->alias : "");
 			}
 		}
 	} else {
@@ -749,14 +761,14 @@
 	if ((rootfd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) < 0) {
 		perror("Could not open /etc/.rootkey for writing");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
 		goto rootkey_err;
 	}
 	if (!(rootfile = fdopen(rootfd, "w"))) {
 		perror("Could not open /etc/.rootkey for writing");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		close(rootfd);
 		unlink(ROOTKEY_FILE);
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
@@ -765,7 +777,7 @@
 	if (!(bakfile = fopen(ROOTKEY_FILE_BACKUP, "r"))) {
 		perror("Could not open /etc/.rootkey.bak for reading");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		fclose(rootfile);
 		unlink(ROOTKEY_FILE);
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
@@ -830,7 +842,7 @@
 
 rootkey_err:
 	fprintf(stderr, "WARNING: Could not write %s key to /etc/.rootkey\n",
-		flavor);
+	    flavor);
 }
 
 
@@ -846,7 +858,7 @@
 	if (nis_princ == NULL) {
 		(void) fprintf(stderr,
 		"%s: you must create a \"LOCAL\" credential for '%s' first.\n",
-			program_name, netname);
+		    program_name, netname);
 		(void) fprintf(stderr, "\tSee nisaddcred(1).\n");
 		return (0);
 	}
@@ -856,15 +868,15 @@
 	if (nis_princ[len-1] != '.') {
 		(void) fprintf(stderr,
 		"%s: invalid principal name: '%s' (forgot ending dot?).\n",
-			program_name, nis_princ);
+		    program_name, nis_princ);
 		return (0);
 	}
 
 	/* Sanity check 1.  We only deal with one type of netnames. */
 	if (strncmp(netname, "unix", 4) != 0) {
 		(void) fprintf(stderr,
-			"%s: unrecognized netname type: '%s'.\n",
-			program_name, netname);
+		"%s: unrecognized netname type: '%s'.\n",
+		    program_name, netname);
 		return (0);
 	}
 
@@ -873,7 +885,7 @@
 	if (strcasecmp(princdomain, domain) != 0) {
 		(void) fprintf(stderr,
 "%s: domain of principal '%s' does not match destination domain '%s'.\n",
-			program_name, nis_princ, domain);
+		    program_name, nis_princ, domain);
 		(void) fprintf(stderr,
 	"Should only add DES credential of principal in its home domain\n");
 		return (0);
@@ -886,7 +898,7 @@
 	netdomain = (char *)strchr(netname, '@');
 	if (! netdomain || netname[strlen(netname)-1] == '.') {
 		(void) fprintf(stderr, "%s: invalid netname: '%s'. \n",
-			program_name, netname);
+		    program_name, netname);
 		return (0);
 	}
 	netdomain++; /* skip '@' */
@@ -894,7 +906,7 @@
 	if (strlcpy(netdomainaux, netdomain, sizeof (netdomainaux)) >=
 	    sizeof (netdomainaux)) {
 		(void) fprintf(stderr, "%s: net domain name %s is too long\n",
-			    program_name, netdomain);
+		    program_name, netdomain);
 		return (0);
 	}
 
@@ -902,8 +914,8 @@
 		if (strlcat(netdomainaux, ".", sizeof (netdomainaux)) >=
 		    sizeof (netdomainaux)) {
 			(void) fprintf(stderr,
-				    "%s: net domain name %s is too long\n",
-				    program_name, netdomainaux);
+			    "%s: net domain name %s is too long\n",
+			    program_name, netdomainaux);
 			return (0);
 		}
 	}
@@ -911,7 +923,7 @@
 	if (strcasecmp(princdomain, netdomainaux) != 0) {
 		(void) fprintf(stderr,
 	"%s: domain of netname %s should be same as that of principal %s\n",
-			program_name, netname, nis_princ);
+		    program_name, netname, nis_princ);
 		return (0);
 	}
 
@@ -937,31 +949,31 @@
 		break;
 	case PK_NISPLUS:
 		nis_princ = get_nisplus_principal(nis_local_directory(),
-							geteuid());
+		    geteuid());
 		break;
 	case PK_YP:
 		yp_get_default_domain(&ypdomain);
 		if (yp_master(ypdomain, PKMAP, &ypmaster) != 0) {
 			fprintf(stderr,
 			"%s: cannot find master of NIS publickey database\n",
-				program_name);
+			    program_name);
 			exit(1);
 		}
 		fprintf(stdout,
-			"Sending key change request to %s ...\n", ypmaster);
+		    "Sending key change request to %s ...\n", ypmaster);
 		break;
 	case PK_FILES:
 		if (geteuid() != 0) {
 			fprintf(stderr,
 		"%s: non-root users cannot change their key-pair in %s\n",
-				program_name, PKFILE);
+			    program_name, PKFILE);
 			exit(1);
 		}
 		break;
 	default:
 		fprintf(stderr,
-			"could not update; database %d unknown\n",
-			dest_service);
+		    "could not update; database %d unknown\n",
+		    dest_service);
 		exit(1);
 	}
 
@@ -973,38 +985,38 @@
 				continue;
 
 			__nis_mechalias2authtype(CURMECH->alias, authtype,
-							MECH_MAXATNAME);
+			    MECH_MAXATNAME);
 			if (!authtype) {
 				fprintf(stderr,
 				"Could not generate auth_type for %s.\n",
-					CURMECH->alias);
+				    CURMECH->alias);
 				continue;
 			}
 
 			snprintf(pkent, MAXPKENTLEN, "%s:%s:%d",
-					plist[mcount], clist[mcount],
-					CURMECH->algtype);
+			    plist[mcount], clist[mcount],
+			    CURMECH->algtype);
 
 			switch (dest_service) {
 			case PK_LDAP:
 				if (ldap_update(CURMECH->alias, netname,
-						plist[mcount], clist[mcount],
-						login_pw))
+				    plist[mcount], clist[mcount],
+				    login_pw))
 					fprintf(stderr,
 			"%s: unable to update %s key in LDAP database\n",
-						program_name, authtype);
+					    program_name, authtype);
 				else
 					ucount++;
 				break;
 
 			case PK_NISPLUS:
 				if (nisplus_update(nis_princ,
-							authtype,
-							plist[mcount],
-							clist[mcount]))
+				    authtype,
+				    plist[mcount],
+				    clist[mcount]))
 					fprintf(stderr,
 			"%s: unable to update %s key in nisplus database\n",
-						program_name, authtype);
+					    program_name, authtype);
 				else
 					ucount++;
 				break;
@@ -1027,11 +1039,11 @@
 		switch (dest_service) {
 		case PK_LDAP:
 			if (ldap_update("dh192-0", netname,
-					plist[0], clist[0],
-					login_pw)) {
+			    plist[0], clist[0],
+			    login_pw)) {
 				fprintf(stderr,
 			"%s: unable to update %s key in LDAP database\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 			break;
@@ -1039,25 +1051,25 @@
 		case PK_NISPLUS:
 			assert(plist[0] && clist[0]);
 			if (nisplus_update(nis_princ,
-						AUTH_DES_AUTH_TYPE,
-						plist[0],
-						clist[0])) {
-					fprintf(stderr,
+			    AUTH_DES_AUTH_TYPE,
+			    plist[0],
+			    clist[0])) {
+				fprintf(stderr,
 			"%s: unable to update nisplus database\n",
-						program_name);
+				    program_name);
 					exit(1);
 			}
 			break;
 
 		case PK_YP:
 			if (status = yp_update(ypdomain, PKMAP,
-						YPOP_STORE, netname,
-						strlen(netname), pkent,
-						strlen(pkent))) {
+			    YPOP_STORE, netname,
+			    strlen(netname), pkent,
+			    strlen(pkent))) {
 				fprintf(stderr,
 				"%s: unable to update NIS database (%u): %s\n",
-					program_name, status,
-					yperr_string(status));
+				    program_name, status,
+				    yperr_string(status));
 				exit(1);
 			}
 			break;
@@ -1066,7 +1078,7 @@
 			if (localupdate(netname, PKFILE, YPOP_STORE, pkent)) {
 				fprintf(stderr,
 			"%s: hence, unable to update publickey database\n",
-					program_name);
+				    program_name);
 				exit(1);
 			}
 			break;
@@ -1079,7 +1091,7 @@
 	}
 	if (!ucount) {
 		fprintf(stderr, "%s: unable to update any key-pairs for %s.\n",
-			program_name, pw->pw_name);
+		    program_name, pw->pw_name);
 		exit(1);
 	}
 }
@@ -1095,13 +1107,13 @@
 	char *foundprinc;
 
 	(void) sprintf(sname, "[auth_name=%s,auth_type=%s],%s.%s",
-		auth_name, auth_type, CRED_TABLE, domain);
+	    auth_name, auth_type, CRED_TABLE, domain);
 	if (sname[strlen(sname)-1] != '.')
 		strcat(sname, ".");
 	/* Don't want FOLLOW_PATH here */
 	res = nis_list(sname,
-		MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS,
-		NULL, NULL);
+	    MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS,
+	    NULL, NULL);
 
 	status = res->status;
 	switch (res->status) {
@@ -1109,14 +1121,14 @@
 		break;
 	case NIS_TRYAGAIN:
 		(void) fprintf(stderr,
-			"%s: NIS+ server busy, try again later.\n",
-			program_name);
+		"%s: NIS+ server busy, try again later.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_PERMISSION:
 		(void) fprintf(stderr,
 		"%s: insufficient permission to look up old credentials.\n",
-			program_name);
+		    program_name);
 		exit(1);
 		break;
 	case NIS_SUCCESS:
@@ -1124,14 +1136,14 @@
 		if (nis_dir_cmp(foundprinc, princname) != SAME_NAME) {
 			(void) fprintf(stderr,
 	"%s: %s credentials with auth_name '%s' already belong to '%s'.\n",
-			program_name, auth_type, auth_name, foundprinc);
+			    program_name, auth_type, auth_name, foundprinc);
 			exit(1);
 		}
 		break;
 	default:
 		(void) fprintf(stderr,
-			"%s: error looking at cred table, NIS+ error: %s\n",
-			program_name, nis_sperrno(res->status));
+		"%s: error looking at cred table, NIS+ error: %s\n",
+		    program_name, nis_sperrno(res->status));
 		exit(1);
 	}
 	nis_freeresult(res);
@@ -1148,15 +1160,15 @@
 	nis_error status;
 
 	snprintf(sname, NIS_MAXNAMELEN,
-			"[cname=\"%s\",auth_type=%s],%s.%s",
-			nisprinc, flavor, CRED_TABLE, domain);
+	    "[cname=\"%s\",auth_type=%s],%s.%s",
+	    nisprinc, flavor, CRED_TABLE, domain);
 	if (sname[strlen(sname)-1] != '.')
 		strcat(sname, ".");
 
 	/* Don't want FOLLOW_PATH here */
 	res = nis_list(sname,
-				MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS,
-				NULL, NULL);
+	    MASTER_ONLY+USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS,
+	    NULL, NULL);
 
 	status = res->status;
 	switch (status) {
@@ -1164,14 +1176,14 @@
 		break;
 	case NIS_TRYAGAIN:
 		fprintf(stderr,
-			"%s: NIS+ server busy, try again later.\n",
-			program_name);
+		"%s: NIS+ server busy, try again later.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_PERMISSION:
 		(void) fprintf(stderr,
 		"%s: insufficient permission to look at credentials table\n",
-			program_name);
+		    program_name);
 		exit(1);
 		break;
 	case NIS_SUCCESS:
@@ -1179,8 +1191,8 @@
 		break;
 	default:
 		(void) fprintf(stderr,
-			"%s: error looking at cred table, NIS+ error: %s\n",
-			program_name, nis_sperrno(res->status));
+		"%s: error looking at cred table, NIS+ error: %s\n",
+		    program_name, nis_sperrno(res->status));
 		exit(1);
 	}
 	nis_freeresult(res);
@@ -1200,14 +1212,14 @@
 	switch (res->status) {
 	case NIS_TRYAGAIN:
 		(void) fprintf(stderr,
-			"%s: NIS+ server busy, try again later.\n",
-			program_name);
+		"%s: NIS+ server busy, try again later.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_PERMISSION:
 		(void) fprintf(stderr,
-			"%s: insufficient permission to update credentials.\n",
-			program_name);
+		"%s: insufficient permission to update credentials.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_SUCCESS:
@@ -1215,8 +1227,8 @@
 		break;
 	default:
 		(void) fprintf(stderr,
-			"%s: error modifying credential, NIS+ error: %s.\n",
-			program_name, nis_sperrno(res->status));
+		"%s: error modifying credential, NIS+ error: %s.\n",
+		    program_name, nis_sperrno(res->status));
 		exit(1);
 	}
 	nis_freeresult(res);
@@ -1238,14 +1250,14 @@
 	switch (res->status) {
 	case NIS_TRYAGAIN:
 		(void) fprintf(stderr,
-			"%s: NIS+ server busy, try again later.\n",
-			program_name);
+		"%s: NIS+ server busy, try again later.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_PERMISSION:
 		(void) fprintf(stderr,
-			"%s: insufficient permission to update credentials.\n",
-			program_name);
+		"%s: insufficient permission to update credentials.\n",
+		    program_name);
 		exit(1);
 		break;
 	case NIS_SUCCESS:
@@ -1253,8 +1265,8 @@
 		break;
 	default:
 		(void) fprintf(stderr,
-			"%s: error creating credential, NIS+ error: %s.\n",
-			program_name, nis_sperrno(res->status));
+		"%s: error creating credential, NIS+ error: %s.\n",
+		    program_name, nis_sperrno(res->status));
 		exit(1);
 	}
 	nis_freeresult(res);
@@ -1274,7 +1286,7 @@
 
 	if (!(userdomain = strchr(netname, '@'))) {
 		fprintf(stderr, "%s: invalid netname: '%s'.\n",
-			program_name, netname);
+		    program_name, netname);
 		exit(1);
 	}
 	userdomain++;
@@ -1282,8 +1294,8 @@
 	if (strlcpy(cmpdomain, userdomain, sizeof (cmpdomain)) >=
 	    sizeof (cmpdomain)) {
 		(void) fprintf(stderr,
-			    "%s: net domain name %s is too long\n",
-			    program_name, cmpdomain);
+		"%s: net domain name %s is too long\n",
+		    program_name, cmpdomain);
 			exit(1);
 	}
 
@@ -1291,8 +1303,8 @@
 		if (strlcat(cmpdomain, ".", sizeof (cmpdomain)) >=
 		    sizeof (cmpdomain)) {
 			(void) fprintf(stderr,
-				    "%s: net domain name %s is too long\n",
-				    program_name, cmpdomain);
+			"%s: net domain name %s is too long\n",
+			    program_name, cmpdomain);
 			exit(1);
 		}
 	}
@@ -1327,8 +1339,8 @@
 		obj->zo_domain = domain;
 		/* owner: r, group: rmcd */
 		obj->zo_access = ((NIS_READ_ACC<<16)|
-				(NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC|
-				NIS_DESTROY_ACC)<<8);
+		    (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC|
+		    NIS_DESTROY_ACC)<<8);
 		status = add_cred_obj(obj, domain);
 	} else {
 		obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED;
@@ -1359,28 +1371,29 @@
 					 */
 					numspecmech++;
 					if ((mechs =
-						(mechanism_t **)realloc(mechs,
-				sizeof (mechanism_t *) * (numspecmech + 1))) ==
-					    NULL) {
+					    (mechanism_t **)realloc(mechs,
+					    sizeof (mechanism_t *) *
+					    (numspecmech + 1))) == NULL) {
 						perror("Can not change keys");
 						exit(1);
 					}
 
 					if ((mechs[numspecmech - 1] =
-		(mechanism_t *)malloc(sizeof (mechanism_t))) == NULL) {
+					    (mechanism_t *)malloc(
+					    sizeof (mechanism_t))) == NULL) {
 						perror("Can not change keys");
 						exit(1);
 					}
 					if (realmechlist[i]->mechname)
 					mechs[numspecmech - 1]->mechname =
-					strdup(realmechlist[i]->mechname);
+					    strdup(realmechlist[i]->mechname);
 					if (realmechlist[i]->alias)
 					mechs[numspecmech - 1]->alias =
-						strdup(realmechlist[i]->alias);
+					    strdup(realmechlist[i]->alias);
 					mechs[numspecmech - 1]->keylen =
-						realmechlist[i]->keylen;
+					    realmechlist[i]->keylen;
 					mechs[numspecmech - 1]->algtype =
-						realmechlist[i]->algtype;
+					    realmechlist[i]->algtype;
 					mechs[numspecmech] = NULL;
 					__nis_release_mechanisms(realmechlist);
 					return;
@@ -1389,13 +1402,13 @@
 
 		fprintf(stderr,
 		"WARNING: Mechanism '%s' not configured, skipping...\n",
-			mechtype);
+		    mechtype);
 		__nis_release_mechanisms(realmechlist);
 		return;
 	}
 	fprintf(stderr,
-		"WARNING: Mechanism '%s' not configured, skipping...\n",
-		mechtype);
+	"WARNING: Mechanism '%s' not configured, skipping...\n",
+	    mechtype);
 }
 
 
@@ -1452,7 +1465,7 @@
 	}
 	if (!__getnetnamebyuid(netname, uid = getuid())) {
 		fprintf(stderr, "%s: cannot generate netname for uid %d\n",
-			program_name, uid);
+		    program_name, uid);
 		exit(1);
 	}
 	sec_domain = strdup(strchr(netname, '@') + 1);
@@ -1467,7 +1480,7 @@
 		if (dest_service == PK_YP || dest_service == PK_FILES) {
 			fprintf(stderr,
 		"%s: can not add non-DES public keys to %s, skipping.\n",
-				program_name, service);
+			    program_name, service);
 			__nis_release_mechanisms(mechs);
 			mechs = NULL;
 			initkeylist(TRUE);
@@ -1482,8 +1495,8 @@
 	/* Get password information */
 	if ((pw = getpwuid(uid)) == NULL) {
 		fprintf(stderr,
-			"%s: Can not find passwd information for %d.\n",
-			program_name, uid);
+		"%s: Can not find passwd information for %d.\n",
+		    program_name, uid);
 		exit(1);
 	}
 
@@ -1506,10 +1519,10 @@
 				keylogin(CURMECH->keylen, CURMECH->algtype);
 				if ((uid == 0) && (makenew == FALSE))
 					write_rootkey(slist[mcount],
-					VALID_ALIAS(CURMECH->alias) ?
-							CURMECH->alias :
-							"",
-							keylen, algtype);
+					    VALID_ALIAS(CURMECH->alias) ?
+					    CURMECH->alias :
+					    "",
+					    keylen, algtype);
 			}
 		}
 	} else {
@@ -1544,8 +1557,8 @@
 		(void) seteuid(uid);
 
 		(void) fprintf(stderr,
-			"%s: cannot find shadow entry for %s.\n",
-			program_name, pw->pw_name);
+		"%s: cannot find shadow entry for %s.\n",
+		    program_name, pw->pw_name);
 		exit(1);
 	}
 
@@ -1555,7 +1568,7 @@
 	if (strcmp(spw->sp_pwdp, NOPWDRTR) == 0) {
 		(void) fprintf(stderr,
 		"%s: do not have read access to the passwd field for %s\n",
-				program_name, pw->pw_name);
+		    program_name, pw->pw_name);
 		exit(1);
 	}
 
@@ -1566,10 +1579,12 @@
 	if (force) {
 		char	*prompt = "Please enter New password:";
 
-		login_pw = getpass(prompt);
+		login_pw = getpassphrase(prompt);
+		(void) strlcpy(short_login_pw, login_pw,
+		    sizeof (short_login_pw));
 		if (!login_pw || !(strlen(login_pw))) {
 			fprintf(stderr, "%s: key-pair(s) unchanged for %s.\n",
-				program_name, pw->pw_name);
+			    program_name, pw->pw_name);
 			exit(1);
 		}
 	} else {
@@ -1598,9 +1613,9 @@
 					if (!slist[mcount])
 						continue;
 					write_rootkey(slist[mcount],
-							CURMECH->alias,
-							CURMECH->keylen,
-							CURMECH->algtype);
+					    CURMECH->alias,
+					    CURMECH->keylen,
+					    CURMECH->algtype);
 				}
 			} else {
 				assert(slist[0]);
@@ -1610,7 +1625,7 @@
 		if (mechs) {
 			for (mcount = 0; CURMECH; mcount++)
 				keylogin(CURMECH->keylen,
-						CURMECH->algtype);
+				    CURMECH->algtype);
 		} else
 			keylogin_des();
 	}
--- a/usr/src/cmd/keyserv/newkey.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/keyserv/newkey.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -37,8 +36,6 @@
  * contributors.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Administrative tool to add a new user to the publickey database
  */
@@ -56,6 +53,7 @@
 #include <sys/resource.h>
 #include <netdir.h>
 #include <rpcsvc/nis.h>
+#include <rpcsvc/nispasswd.h>
 
 #define	MAXMAPNAMELEN	256
 #define	MAXPASSWD	256	/* max significant characters in password */
@@ -93,7 +91,8 @@
 	char	crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
 	int	status;
 	char	*pass, *target_host = NULL,
-		*username = NULL, *pk_service = NULL;
+	    *username = NULL, *pk_service = NULL;
+	char	short_pass[DESCREDPASSLEN + 1];
 	struct passwd	*pw;
 	NCONF_HANDLE	*nc_handle;
 	struct	netconfig *nconf;
@@ -146,7 +145,7 @@
 		pw = getpwnam(username);
 		if (pw == NULL) {
 			(void) fprintf(stderr, "%s: unknown user: '%s'\n",
-				program_name, username);
+			    program_name, username);
 			exit(1);
 		}
 		uid = pw->pw_uid;
@@ -154,17 +153,17 @@
 			if (! getnetname(name)) {
 				(void) fprintf(stderr,
 			"%s: could not get the equivalent netname for %s\n",
-				program_name, username);
+				    program_name, username);
 				usage();
 			}
 			if (pk_database == PK_NISPLUS)
 				target_host = nis_local_host();
 			else {
 				if (gethostname(host_pname, NIS_MAXNAMELEN)
-					< 0) {
+				    < 0) {
 					(void) fprintf(stderr,
 				"%s: could not get the hostname for %s\n",
-					program_name, username);
+					    program_name, username);
 					usage();
 				}
 				target_host = host_pname;
@@ -173,12 +172,12 @@
 		if (__getnetnamebyuid(name, uid) == 0) {
 			(void) fprintf(stderr,
 			"%s: could not get the equivalent netname for %s\n",
-				program_name, username);
+			    program_name, username);
 			usage();
 		}
 		if (pk_database == PK_NISPLUS)
 			nprinc = get_nisplus_principal(nis_local_directory(),
-					uid);
+			    uid);
 	} else {
 		/* -h hostname option */
 		service.h_host = target_host;
@@ -189,8 +188,8 @@
 		if (nc_handle == NULL) {
 			/* fails to open netconfig file */
 			(void) fprintf(stderr,
-				"%s: failed in routine setnetconfig()\n",
-				program_name);
+			"%s: failed in routine setnetconfig()\n",
+			    program_name);
 			exit(2);
 		}
 		while (nconf = getnetconfig(nc_handle)) {
@@ -205,14 +204,14 @@
 		endnetconfig(nc_handle);
 		if (!validhost) {
 			(void) fprintf(stderr, "%s: unknown host: %s\n",
-				program_name, target_host);
+			    program_name, target_host);
 			exit(1);
 		}
 		(void) host2netname(name, target_host, (char *)NULL);
 		if (pk_database == PK_NISPLUS) {
 			if (target_host[strlen(target_host) - 1] != '.') {
 				sprintf(host_pname, "%s.%s",
-					target_host, nis_local_directory());
+				    target_host, nis_local_directory());
 				nprinc = host_pname;
 			} else
 				nprinc = target_host;
@@ -226,36 +225,37 @@
 	if (pass == NULL)
 		exit(1);
 
-	(void) __gen_dhkeys(public, secret, pass);
+	(void) strlcpy(short_pass, pass, sizeof (short_pass));
+	(void) __gen_dhkeys(public, secret, short_pass);
 
-	memcpy(crypt1, secret, HEXKEYBYTES);
-	memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
+	(void) memcpy(crypt1, secret, HEXKEYBYTES);
+	(void) memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
 	crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
-	xencrypt(crypt1, pass);
+	xencrypt(crypt1, short_pass);
 
 	if (status = setpublicmap(name, public, crypt1, pk_database,
-				nprinc, pass)) {
+	    nprinc, short_pass)) {
 		switch (pk_database) {
 		case PK_YP:
 			(void) fprintf(stderr,
-				"%s: unable to update NIS database (%u): %s\n",
-				program_name, status,
-				yperr_string(status));
+			    "%s: unable to update NIS database (%u): %s\n",
+			    program_name, status,
+			    yperr_string(status));
 			break;
 		case PK_FILES:
 			(void) fprintf(stderr,
-			"%s: hence, unable to update publickey database\n",
-				program_name);
+			    "%s: hence, unable to update publickey database\n",
+			    program_name);
 			break;
 		case PK_NISPLUS:
 			(void) fprintf(stderr,
-				"%s: unable to update nisplus database\n",
-				program_name);
+			    "%s: unable to update nisplus database\n",
+			    program_name);
 			break;
 		default:
 			(void) fprintf(stderr,
-				"%s: could not update unknown database: %d\n",
-				program_name, pk_database);
+			    "%s: could not update unknown database: %d\n",
+			    program_name, pk_database);
 		}
 		exit(1);
 	}
@@ -326,11 +326,11 @@
 usage(void)
 {
 	(void) fprintf(stderr,
-		"usage:\t%s -u username [-s ldap | nisplus | nis | files]\n",
-		program_name);
+	    "usage:\t%s -u username [-s ldap | nisplus | nis | files]\n",
+	    program_name);
 	(void) fprintf(stderr,
-		"\t%s -h hostname [-s ldap | nisplus | nis | files]\n",
-		program_name);
+	    "\t%s -h hostname [-s ldap | nisplus | nis | files]\n",
+	    program_name);
 	exit(1);
 }
 
@@ -397,7 +397,7 @@
 	    (void) sprintf(prompt, "Enter %s's login password:",
 		pw->pw_name);
 
-	pass = getpass(prompt);
+	pass = getpassphrase(prompt);
 	if (pass && strlen(pass) == 0) {
 		(void) fprintf(stderr, "%s: Invalid password.\n",
 			program_name);
@@ -411,7 +411,7 @@
 		/*
 		 * Give another chance for typo
 		 */
-		pass = getpass("Please retype password:");
+		pass = getpassphrase("Please retype password:");
 	    if (pass && strlen(pass) == 0) {
 		(void) fprintf(stderr, "%s: Invalid password.\n",
 			program_name);
@@ -447,7 +447,7 @@
 		(void) sprintf(prompt,
 		    "Enter %s's root login password:",
 		    target_host);
-		pass = getpass(prompt);
+		pass = getpassphrase(prompt);
 		if (!pass) {
 			(void) fprintf(stderr,
 			    "%s: getpass failed.\n",
@@ -469,7 +469,7 @@
 		(void) sprintf(prompt,
 		    "Please confirm %s's root login password:",
 		    target_host);
-		pass = getpass(prompt);
+		pass = getpassphrase(prompt);
 		if (!pass) {
 			(void) fprintf(stderr,
 			    "%s: getpass failed.\n",
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svc.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  *	npd_svc.c
@@ -28,8 +27,6 @@
  *
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <syslog.h>
 #include <string.h>
 #include <ctype.h>
@@ -67,6 +64,31 @@
 nispasswd_authresult *result;
 struct svc_req *rqstp;
 {
+	return (nispasswd_authenticate_common_svc(argp,
+	    result, rqstp, NISPASSWD_VERS));
+}
+
+/*
+ * service routine for first part of the nispasswd update2
+ * protocol.
+ */
+bool_t
+nispasswd_authenticate_2_svc(argp, result, rqstp)
+npd_request *argp;
+nispasswd_authresult *result;
+struct svc_req *rqstp;
+{
+	return (nispasswd_authenticate_common_svc(argp,
+	    result, rqstp, NISPASSWD_VERS2));
+}
+
+bool_t
+nispasswd_authenticate_common_svc(argp, result, rqstp, vers)
+npd_request *argp;
+nispasswd_authresult *result;
+struct svc_req *rqstp;
+rpcvers_t vers;
+{
 	bool_t	check_aging = TRUE;	/* default == check */
 	bool_t	same_user = TRUE;	/* default == same user */
 	bool_t	is_admin = FALSE;	/* default == not an admin */
@@ -75,7 +97,6 @@
 	bool_t	refresh = FALSE;	/* default == do not refresh */
 	int	ans = 0;
 	char	prin[NIS_MAXNAMELEN];
-	unsigned char	xpass[_NPD_PASSMAXLEN];
 	struct	update_item	*entry = NULL;
 	nis_result	*pass_res;
 	nis_object	*pobj;
@@ -86,6 +107,22 @@
 	uint32_t	rval, ident;
 	keylen_t pkeylen;  /* public key length (bits) */
 	algtype_t algtype; /* public key algorithm type */
+	int passlen = __NPD2_MAXPASSBYTES;
+	unsigned char *xpass;
+
+	if (vers == NISPASSWD_VERS) {
+		passlen = __NPD_MAXPASSBYTES;
+	} else if (vers == NISPASSWD_VERS2) {
+		passlen = __NPD2_MAXPASSBYTES;
+	}
+
+	if ((xpass = malloc(passlen + 1)) == NULL) {
+		syslog(LOG_ERR,
+		    "nispasswd_authenticate_common_svc: Out of memory");
+		result->status = NPD_FAILED;
+		result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR;
+		return (TRUE);
+	}
 
 	if (verbose)
 		syslog(LOG_ERR, "received NIS+ auth request for %s",
@@ -96,7 +133,7 @@
 		syslog(LOG_ERR, "not master for %s", argp->domain);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_NOTMASTER;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 
 again:
@@ -126,7 +163,7 @@
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err =
 				NPD_BUFTOOSMALL;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 		(void) sprintf(prin, "%s.%s", argp->username, argp->domain);
 		if (prin[strlen(prin) - 1] != '.')
@@ -166,7 +203,7 @@
 				result->status = NPD_FAILED;
 				result->nispasswd_authresult_u.npd_err =
 					NPD_PASSINVALID;
-				return (TRUE);
+				goto auth_free_xpass;
 			}
 			if (argp->ident == 0) {
 				/*
@@ -191,7 +228,7 @@
 				result->status = NPD_FAILED;
 				result->nispasswd_authresult_u.npd_err =
 						NPD_IDENTINVALID;
-				return (TRUE);
+				goto auth_free_xpass;
 			}
 	}
 
@@ -203,7 +240,7 @@
 			argp->username, argp->domain);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_NOSUCHENTRY;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 	switch (pass_res->status) {
 	case NIS_SUCCESS:
@@ -215,7 +252,7 @@
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_NOSUCHENTRY;
-		return (TRUE);
+		goto auth_free_xpass;
 	default:
 		syslog(LOG_ERR,
 			"NIS+ error (%d) getting passwd entry for %s",
@@ -223,7 +260,7 @@
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_NISERROR;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 
 	/* if user check if 'min' days have passed since 'lastchg' */
@@ -236,7 +273,7 @@
 			(void) nis_freeresult(pass_res);
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err = ans;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 	/* if ans == NPD_NOSHDWINFO then aging cannot be enforced */
 	}
@@ -261,7 +298,7 @@
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err =
 				NPD_INVALIDARGS;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 	}
 
@@ -277,27 +314,27 @@
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_CKGENFAILED;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 	/* decrypt the passwd sent */
-	if (argp->npd_authpass.npd_authpass_len != _NPD_PASSMAXLEN) {
+	if (argp->npd_authpass.npd_authpass_len != passlen) {
 		syslog(LOG_ERR, "password length wrong");
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_TRYAGAIN;
 		result->nispasswd_authresult_u.npd_err = NPD_PASSINVALID;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 	(void) memcpy(xpass, argp->npd_authpass.npd_authpass_val,
-			_NPD_PASSMAXLEN);
+			passlen);
 
 	ivec.key.high = ivec.key.low = 0;
 	if (AUTH_DES_KEY(pkeylen, algtype))
 		status = cbc_crypt(deskeys[0].c, (char *)xpass,
-					_NPD_PASSMAXLEN, DES_DECRYPT | DES_HW,
+					passlen, DES_DECRYPT | DES_HW,
 					(char *)&ivec);
 	else
 		status = __cbc_triple_crypt(deskeys, (char *)xpass,
-					_NPD_PASSMAXLEN, DES_DECRYPT | DES_HW,
+					passlen, DES_DECRYPT | DES_HW,
 					(char *)&ivec);
 
 	if (DES_FAILED(status)) {
@@ -305,7 +342,7 @@
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_DECRYPTFAIL;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 
 	/* assign an ID and generate R on the first call of a session */
@@ -316,7 +353,7 @@
 			(void) nis_freeresult(pass_res);
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err = NPD_SYSTEMERR;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 		(void) __npd_gen_rval(&randval);
 	} else {
@@ -331,7 +368,7 @@
 				result->status = NPD_FAILED;
 				result->nispasswd_authresult_u.npd_err =
 					NPD_SYSTEMERR;
-				return (TRUE);
+				goto auth_free_xpass;
 			}
 		} else {
 			if (strcmp(entry->ul_user, argp->username) != 0) {
@@ -349,7 +386,7 @@
 		(void) nis_freeresult(pass_res);
 		result->status = NPD_FAILED;
 		result->nispasswd_authresult_u.npd_err = NPD_ENCRYPTFAIL;
-		return (TRUE);
+		goto auth_free_xpass;
 	}
 	/* encrypt the passwd and compare with that stored in NIS+ */
 	if (same_user) {
@@ -357,7 +394,7 @@
 			(void) nis_freeresult(pass_res);
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err = NPD_NOPASSWD;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 		if (strcmp(crypt((const char *)xpass,
 		    (const char *)oldpass), oldpass) != 0) {
@@ -397,7 +434,7 @@
 			}
 			if (verbose)
 				(void) __npd_print_entry(prin);
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 	} else {
 		if (is_admin == FALSE) {	/* not privileged */
@@ -405,7 +442,7 @@
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err =
 					NPD_PERMDENIED;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 		/* admin changing another users password */
 		if (__authenticate_admin(prin, (char *)xpass) == FALSE) {
@@ -434,7 +471,7 @@
 							NPD_SYSTEMERR;
 				}
 			}
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 	}
 	/* done with pass_res */
@@ -448,7 +485,7 @@
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err =
 					NPD_SYSTEMERR;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 	} else {
 		if (entry->ul_oldpass != NULL)
@@ -458,7 +495,7 @@
 			result->status = NPD_FAILED;
 			result->nispasswd_authresult_u.npd_err =
 					NPD_SYSTEMERR;
-			return (TRUE);
+			goto auth_free_xpass;
 		}
 		if (upd_entry == TRUE) {
 			entry->ul_ident = ident;
@@ -473,6 +510,10 @@
 			htonl(cryptbuf.key.low);
 	if (verbose)
 		(void) __npd_print_entry(prin);
+
+auth_free_xpass:
+	if (xpass != NULL)
+		free(xpass);
 	return (TRUE);
 }
 
@@ -487,9 +528,38 @@
 nispasswd_updresult	*res;
 struct svc_req	*rqstp;
 {
+	return (nispasswd_update_common_svc((void *) updreq,
+	    res, rqstp, NISPASSWD_VERS));
+}
+
+/*
+ * service routine for second part of the nispasswd update2
+ * protocol.
+ */
+/* ARGSUSED2 */
+bool_t
+nispasswd_update_2_svc(updreq, res, rqstp)
+npd_update2		*updreq;
+nispasswd_updresult	*res;
+struct svc_req	*rqstp;
+{
+	return (nispasswd_update_common_svc((void *) updreq,
+	    res, rqstp, NISPASSWD_VERS2));
+}
+
+/*
+ * service routine for second part of the nispasswd update common
+ * protocol.
+ */
+/* ARGSUSED2 */
+bool_t
+nispasswd_update_common_svc(tmp_updreq, res, rqstp, vers)
+void    *tmp_updreq;
+nispasswd_updresult	*res;
+struct svc_req	*rqstp;
+rpcvers_t   vers;
+{
 	struct update_item *entry;
-	npd_newpass	cryptbuf;
-	passbuf	pass;
 	char	*newpass, buf[NIS_MAXNAMELEN];
 	uint32_t	rand;
 	struct nis_result *pass_res = NULL, *mod_res = NULL;
@@ -505,16 +575,56 @@
 	uint_t		eobj_col_len;
 	int pwflag = FALSE;
 	int chg_passwd = TRUE;
+	char	*pass;
+	int	passlen = __NPD2_MAXPASSBYTES;
+	npd_newpass	cryptbuf1;
+	npd_newpass2	cryptbuf2;
+	npd_update	*updreq1;
+	npd_update2	*updreq2;
+	char *gecos;
+	char *shell;
+
+	if (vers == NISPASSWD_VERS) {
+		passlen = __NPD_MAXPASSBYTES;
+		updreq1 = (npd_update *)tmp_updreq;
+		gecos = updreq1->pass_info.pw_gecos;
+		shell = updreq1->pass_info.pw_shell;
+	} else if (vers == NISPASSWD_VERS2) {
+		passlen = __NPD2_MAXPASSBYTES;
+		updreq2 = (npd_update2 *)tmp_updreq;
+		gecos = updreq2->pass_info.pw_gecos;
+		shell = updreq2->pass_info.pw_shell;
+	}
+
+	if ((pass = malloc(passlen + 1)) == NULL) {
+		syslog(LOG_ERR,
+		    "nispasswd_update_common_svc: Out of memory");
+		res->status = NPD_FAILED;
+		res->nispasswd_updresult_u.npd_err = NPD_SYSTEMERR;
+		return (TRUE);
+	}
 
 	/* set to success, and reset to error when warranted */
 	res->status = NPD_SUCCESS;
 
-	entry = (struct update_item *)__npd_item_by_key(updreq->ident);
-	if (entry == NULL) {
-		syslog(LOG_ERR, "invalid identifier: %ld", updreq->ident);
-		res->status = NPD_FAILED;
-		res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID;
-		return (TRUE);
+	if (vers == NISPASSWD_VERS) {
+		entry = (struct update_item *)__npd_item_by_key(updreq1->ident);
+		if (entry == NULL) {
+			syslog(LOG_ERR, "invalid identifier: %ld",
+			    updreq1->ident);
+			res->status = NPD_FAILED;
+			res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID;
+			goto upd_free_pass;
+		}
+	} else if (vers == NISPASSWD_VERS2) {
+		entry = (struct update_item *)__npd_item_by_key(updreq2->ident);
+		if (entry == NULL) {
+			syslog(LOG_ERR, "invalid identifier: %ld",
+			    updreq2->ident);
+			res->status = NPD_FAILED;
+			res->nispasswd_updresult_u.npd_err = NPD_IDENTINVALID;
+			goto upd_free_pass;
+		}
 	}
 
 	if (verbose) {
@@ -528,19 +638,40 @@
 	 */
 	for (; entry != NULL;
 	    entry = (struct update_item *)entry->ul_item.next) {
-
-		/* decrypt R and new passwd */
-		cryptbuf.npd_xrandval = ntohl(updreq->xnewpass.npd_xrandval);
-		for (i = 0; i < __NPD_MAXPASSBYTES; i++)
-			cryptbuf.pass[i] = updreq->xnewpass.pass[i];
+		if (vers == NISPASSWD_VERS) {
+			/* decrypt R and new passwd */
+			cryptbuf1.npd_xrandval =
+			    ntohl(updreq1->xnewpass.npd_xrandval);
+			for (i = 0; i < passlen; i++)
+				cryptbuf1.pass[i] = updreq1->xnewpass.pass[i];
 
-		if (! __npd_cbc_crypt(&rand, pass, __NPD_MAXPASSBYTES,
-			&cryptbuf, _NPD_PASSMAXLEN, DES_DECRYPT,
-			&entry->ul_key)) {
-			syslog(LOG_ERR, "failed to decrypt verifier");
-			res->status = NPD_FAILED;
-			res->nispasswd_updresult_u.npd_err = NPD_DECRYPTFAIL;
-			return (TRUE);
+			if (! __npd_cbc_crypt(&rand, pass, passlen,
+				&cryptbuf1, _NPD_PASSMAXLEN, DES_DECRYPT,
+				&entry->ul_key)) {
+				syslog(LOG_ERR, "failed to decrypt verifier");
+				res->status = NPD_FAILED;
+				res->nispasswd_updresult_u.npd_err =
+				    NPD_DECRYPTFAIL;
+				goto upd_free_pass;
+			}
+		} else if (vers == NISPASSWD_VERS2) {
+			/* decrypt R and new passwd */
+
+			cryptbuf2.npd_xrandval =
+			    ntohl(updreq2->xnewpass.npd_xrandval);
+			cryptbuf2.npd_pad = ntohl(updreq2->xnewpass.npd_pad);
+			for (i = 0; i < passlen; i++)
+				cryptbuf2.pass[i] = updreq2->xnewpass.pass[i];
+
+			if (! __npd2_cbc_crypt(&rand, pass, passlen,
+				&cryptbuf2, sizeof (cryptbuf2), DES_DECRYPT,
+				&entry->ul_key)) {
+				syslog(LOG_ERR, "failed to decrypt verifier");
+				res->status = NPD_FAILED;
+				res->nispasswd_updresult_u.npd_err =
+				    NPD_DECRYPTFAIL;
+				goto upd_free_pass;
+			}
 		}
 
 		/* check if R sent/decrypted matches cached R */
@@ -561,7 +692,7 @@
 			syslog(LOG_ERR, "update failed; no rand matches");
 		res->status = NPD_FAILED;
 		res->nispasswd_updresult_u.npd_err = NPD_VERFINVALID;
-		return (TRUE);
+		goto upd_free_pass;
 	}
 
 	/* create passwd struct with this pass & gecos/shell */
@@ -572,7 +703,7 @@
 			entry->ul_user, entry->ul_domain);
 		res->status = NPD_FAILED;
 		res->nispasswd_updresult_u.npd_err = NPD_NOSUCHENTRY;
-		return (TRUE);
+		goto upd_free_pass;
 	}
 
 	switch (pass_res->status) {
@@ -585,7 +716,7 @@
 		(void) nis_freeresult(pass_res);
 		res->status = NPD_FAILED;
 		res->nispasswd_updresult_u.npd_err = NPD_NOSUCHENTRY;
-		return (TRUE);
+		goto upd_free_pass;
 	default:
 		syslog(LOG_ERR,
 			"NIS+ error (%d) getting passwd entry for %s",
@@ -593,7 +724,7 @@
 		(void) nis_freeresult(pass_res);
 		res->status = NPD_FAILED;
 		res->nispasswd_updresult_u.npd_err = NPD_NISERROR;
-		return (TRUE);
+		goto upd_free_pass;
 	}
 
 	old_pass =  ENTRY_VAL(pobj, 1);
@@ -607,7 +738,7 @@
 	(void) memset(errlist, 0, sizeof (errlist));
 
 	/* if a gecos field is provided... */
-	if (*updreq->pass_info.pw_gecos != '\0') {
+	if (*gecos != '\0') {
 		chg_passwd = FALSE;
 		if (__npd_can_do(NIS_MODIFY_ACC, pobj,
 			entry->ul_item.name, 4) == FALSE) {
@@ -619,17 +750,17 @@
 			errlist[0].npd_code = NPD_PERMDENIED;
 			errlist[0].next = NULL;
 		} else if (old_gecos == NULL ||
-			strcmp(updreq->pass_info.pw_gecos, old_gecos) != 0) {
+			strcmp(gecos, old_gecos) != 0) {
 
 			ecol[4].ec_value.ec_value_val =
-				updreq->pass_info.pw_gecos;
+				gecos;
 			ecol[4].ec_value.ec_value_len =
-				strlen(updreq->pass_info.pw_gecos) + 1;
+				strlen(gecos) + 1;
 			ecol[4].ec_flags = EN_MODIFIED;
 		}
 	}
 		/* if a shell field is provided... */
-	if (*updreq->pass_info.pw_shell != '\0') {
+	if (*shell != '\0') {
 		chg_passwd = FALSE;
 		if (__npd_can_do(NIS_MODIFY_ACC, pobj,
 			entry->ul_item.name, 6) == FALSE) {
@@ -654,11 +785,11 @@
 				errlist[0].next = NULL;
 			}
 		} else if (old_shell == NULL ||
-			strcmp(updreq->pass_info.pw_shell, old_shell) != 0) {
+			strcmp(shell, old_shell) != 0) {
 			ecol[6].ec_value.ec_value_val =
-				updreq->pass_info.pw_shell;
+				shell;
 			ecol[6].ec_value.ec_value_len =
-				strlen(updreq->pass_info.pw_shell) + 1;
+				strlen(shell) + 1;
 			ecol[6].ec_flags = EN_MODIFIED;
 		}
 	}
@@ -866,6 +997,10 @@
 	if (mod_res) (void) nis_freeresult(mod_res);
 	if (pass_res) (void) nis_freeresult(pass_res);
 	if (entry) (void) free_upd_item(entry);
+
+upd_free_pass:
+	if (pass != NULL)
+		free(pass);
 	return (TRUE);
 }
 
@@ -1236,3 +1371,19 @@
 
 	return (1);
 }
+
+/* ARGSUSED */
+int
+nispasswd_prog_2_freeresult(transp, xdr_result, result)
+SVCXPRT *transp;
+xdrproc_t xdr_result;
+caddr_t result;
+{
+
+	/*
+	 * (void) xdr_free(xdr_result, result);
+	 * Insert additional freeing code here, if needed
+	 */
+
+	return (1);
+}
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/npd_svcsubr.h	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 1994-2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  *
  */
@@ -28,9 +27,8 @@
 #ifndef _NPD_SVCSUBR_H
 #define	_NPD_SVCSUBR_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <rpcsvc/yppasswd.h>
+#include <rpcsvc/nispasswd.h>
 
 #ifdef	__cplusplus
 extern "C" {
@@ -53,8 +51,18 @@
 
 bool_t nispasswd_authenticate_1_svc(npd_request *argp,
 	nispasswd_authresult *result, struct svc_req *rqstp);
+bool_t nispasswd_authenticate_2_svc(npd_request *argp,
+	nispasswd_authresult *result, struct svc_req *rqstp);
+bool_t nispasswd_authenticate_common_svc(npd_request *argp,
+	nispasswd_authresult *result, struct svc_req *rqstp, rpcvers_t vers);
+
 bool_t nispasswd_update_1_svc(npd_update *updreq, nispasswd_updresult *res,
 	struct svc_req *rqstp);
+bool_t nispasswd_update_2_svc(npd_update2 *updreq, nispasswd_updresult *res,
+	struct svc_req *rqstp);
+bool_t nispasswd_update_common_svc(void *updreq, nispasswd_updresult *res,
+	struct svc_req *rqstp, rpcvers_t vers);
+
 bool_t yppasswdproc_update_1_svc(struct yppasswd *yppass, int *result,
 	struct svc_req *rqstp);
 
@@ -70,6 +78,11 @@
 extern bool_t __npd_cbc_crypt(uint32_t *val, char *str, unsigned int strsize,
 	npd_newpass *buf, unsigned int bufsize, unsigned int mode,
 	des_block *deskey);
+
+extern bool_t __npd2_cbc_crypt(uint32_t *val, char *str, unsigned int strsize,
+	npd_newpass2 *buf, unsigned int bufsize, unsigned int mode,
+	des_block *deskey);
+
 extern void __free_nis_server(nis_server *server);
 
 #ifdef	__cplusplus
--- a/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/rpcsvc/nis/rpc.nispasswdd/rpc.nispasswdd.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 #include <stdlib.h>	/* getenv, exit */
 #include <signal.h>
@@ -59,6 +56,8 @@
 static void __msgout(const char *msg);
 static int __svc_priv_port_create(void);
 static void nispasswd_prog(struct svc_req *rqstp, register SVCXPRT *transp);
+static void nispasswd_prog_ver2(struct svc_req *rqstp,
+				    register SVCXPRT *transp);
 static void yppasswd_prog(struct svc_req *rqstp, register SVCXPRT *transp);
 static void set_rpc_gss_svc_names(void);
 
@@ -83,7 +82,7 @@
 			if (max_attempts < 0) {
 				fprintf(stderr,
 				"%s: invalid number of maximum attempts\n",
-					argv[0]);
+				    argv[0]);
 				exit(1);
 			}
 			break;
@@ -91,7 +90,7 @@
 			mins = atoi(optarg);
 			if (mins <= 0) {
 				fprintf(stderr,
-					"%s: invalid cache time\n", argv[0]);
+				    "%s: invalid cache time\n", argv[0]);
 				exit(1);
 			}
 			cache_time = (ulong_t)mins * 60;
@@ -107,14 +106,14 @@
 			break;
 		case 'Y':	/* YP forward mode */
 			if (!(ypfwd = strdup(optarg))) {
-			    fprintf(stderr, "%s: out of memory\n", argv[0]);
-			    exit(1);
+				fprintf(stderr, "%s: out of memory\n", argv[0]);
+				exit(1);
 			}
 			break;
 		case '?':
 			fprintf(stderr,
 			"Usage: %s [-a attempts] [-c minutes] [-D] [-g] [-v]\n",
-				argv[0]);
+			    argv[0]);
 			exit(1);
 		}
 	}
@@ -129,7 +128,7 @@
 	if (geteuid() != (uid_t)0) {
 		char err_string[256];
 		snprintf(err_string, sizeof (err_string),
-			"must be superuser to run %s", argv[0]);
+		    "must be superuser to run %s", argv[0]);
 		__msgout(err_string);
 		exit(1);
 	}
@@ -160,11 +159,11 @@
 		if (debug == TRUE)
 			(void) fprintf(stderr,
 			"no host/address information for local host, %d\n",
-			status);
+			    status);
 		else
 			syslog(LOG_ERR,
 			"no host/address information for local host, %d",
-			status);
+			    status);
 		__msgout("exiting ...");
 		exit(1);
 	}
@@ -184,7 +183,7 @@
 		exit(1);
 	}
 	if ((strcmp(tagres[0].tag_val, "<Unknown Statistics>") == 0) ||
-		(strcmp(tagres[1].tag_val, "<Unknown Statistics>") == 0)) {
+	    (strcmp(tagres[1].tag_val, "<Unknown Statistics>") == 0)) {
 
 		/* old server */
 	__msgout("NIS+ server does not support the new statistics tags");
@@ -227,12 +226,24 @@
 		exit(1);
 	}
 	if (svc_create(nispasswd_prog, NISPASSWD_PROG, NISPASSWD_VERS,
-		"circuit_v") == 0) {
+	    "circuit_v") == 0) {
 		__msgout("unable to create (NISPASSWD_PROG, NISPASSWD_VERS)");
 		__msgout(" ... exiting ...");
 		exit(1);
 	}
 
+	if (rpcb_unset(NISPASSWD_PROG, NISPASSWD_VERS2, 0) == FALSE) {
+	__msgout("unable to de-register (NISPASSWD_PROG, NISPASSWD_VERS2)");
+		__msgout(" ... exiting ...");
+		exit(1);
+	}
+	if (svc_create(nispasswd_prog_ver2, NISPASSWD_PROG, NISPASSWD_VERS2,
+	    "circuit_v") == 0) {
+		__msgout("unable to create (NISPASSWD_PROG, NISPASSWD_VERS2)");
+		__msgout(" ... exiting ...");
+		exit(1);
+	}
+
 	if (verbose == TRUE)
 		__msgout("starting rpc.nispasswdd ...");
 	svc_run();
@@ -266,9 +277,9 @@
 	}
 
 	while ((nconf = getnetconfig(handlep)) != 0 &&
-		(nconf4 == 0 || nconf6 == 0)) {
+	    (nconf4 == 0 || nconf6 == 0)) {
 		if ((nconf->nc_semantics == NC_TPI_CLTS) &&
-				strcmp(nconf->nc_proto, NC_UDP) == 0) {
+		    strcmp(nconf->nc_proto, NC_UDP) == 0) {
 			if (strcmp(nconf->nc_protofmly, NC_INET) == 0)
 				nconf4 = nconf;
 			else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0)
@@ -320,10 +331,10 @@
 
 	if (transp4 != 0)
 		svc4 = svc_reg(transp4, YPPASSWDPROG, YPPASSWDVERS,
-				yppasswd_prog, nconf4);
+		    yppasswd_prog, nconf4);
 	if (transp6 != 0)
 		svc6 = svc_reg(transp6, YPPASSWDPROG, YPPASSWDVERS,
-				yppasswd_prog, nconf6);
+		    yppasswd_prog, nconf6);
 	if (svc4 == 0 && svc6 == 0) {
 		__msgout("unable to register (YPPASSWDPROG, YPPASSWDVERS)");
 		if (transp4 != 0)
@@ -402,6 +413,71 @@
 }
 
 static void
+nispasswd_prog_ver2(rqstp, transp)
+struct svc_req	*rqstp;
+register SVCXPRT *transp;
+{
+
+	union {
+		npd_request nispasswd_authenticate_2_arg;
+		npd_update2 nispasswd_update_2_arg;
+	} argument;
+	union {
+		nispasswd_authresult nispasswd_authenticate_2_res;
+		nispasswd_updresult nispasswd_update_2_res;
+	} result;
+	bool_t retval;
+	xdrproc_t xdr_argument, xdr_result;
+	bool_t (*local)(char *, void *, struct svc_req *);
+
+	switch (rqstp->rq_proc) {
+	case NULLPROC:
+		__msgout("received NIS+ null proc call");
+		(void) svc_sendreply(transp,
+			(xdrproc_t)xdr_void, (char *)NULL);
+		return;
+
+	case NISPASSWD_AUTHENTICATE:
+		xdr_argument = (xdrproc_t)xdr_npd_request;
+		xdr_result = (xdrproc_t)xdr_nispasswd_authresult;
+		local = (bool_t (*) (char *, void *, struct svc_req *))
+				nispasswd_authenticate_2_svc;
+		break;
+
+	case NISPASSWD_UPDATE:
+		xdr_argument = (xdrproc_t)xdr_npd_update2;
+		xdr_result = (xdrproc_t)xdr_nispasswd_updresult;
+		local = (bool_t (*) (char *, void *, struct svc_req *))
+				nispasswd_update_2_svc;
+		break;
+
+	default:
+		svcerr_noproc(transp);
+		return;
+	}
+	(void) memset((char *)&argument, 0, sizeof (argument));
+	if (svc_getargs(transp, xdr_argument, (caddr_t)&argument) == 0) {
+		svcerr_decode(transp);
+		return;
+	}
+	(void) memset((char *)&result, 0, sizeof (result));
+	retval = (bool_t)(*local)((char *)&argument, (void *)&result, rqstp);
+	if (retval == TRUE && (svc_sendreply(transp, xdr_result,
+						(char *)&result) == 0)) {
+		svcerr_systemerr(transp);
+	}
+	if (svc_freeargs(transp, xdr_argument, (caddr_t)&argument) == 0) {
+		__msgout("unable to free arguments");
+		exit(1);
+	}
+	if (nispasswd_prog_2_freeresult(transp, xdr_result,
+				(caddr_t)&result) == 0)
+		__msgout("unable to free results");
+
+	/* NOTREACHED */
+}
+
+static void
 yppasswd_prog(rqstp, transp)
 struct svc_req	*rqstp;
 register SVCXPRT *transp;
@@ -504,7 +580,7 @@
 
 		/* '@' + NUL = 2 */
 		if (strlen(lh) + strlen(NIS_SVCNAME_NISPASSWD) + 2 >
-							sizeof (svc_name)) {
+		    sizeof (svc_name)) {
 			syslog(LOG_ERR,
 		"can't set RPC GSS service name:  svc_name bufsize too small");
 			__nis_release_mechanisms(mechs);
@@ -519,6 +595,7 @@
 
 		for (mpp = mechs; *mpp; mpp++) {
 			mechanism_t *mp = *mpp;
+			bool_t	val;
 
 			if (AUTH_DES_COMPAT_CHK(mp))
 				break;
@@ -526,21 +603,44 @@
 			if (! VALID_MECH_ENTRY(mp))
 				continue;
 
-			if (rpc_gss_set_svc_name(svc_name,  mp->mechname,
-							0, NISPASSWD_PROG,
-							NISPASSWD_VERS)) {
+			val = rpc_gss_set_svc_name(svc_name,  mp->mechname,
+			    0, NISPASSWD_PROG,
+			    NISPASSWD_VERS);
+			if (val) {
 				if (verbose)
 					syslog(LOG_INFO,
 				"RPC GSS service name for mechanism '%s' set",
-						mp->mechname);
+					    mp->mechname);
 			} else {
 				rpc_gss_error_t	err;
 
 				rpc_gss_get_error(&err);
 				syslog(LOG_ERR,
-"can't set RPC GSS svc name '%s' for mech '%s': RPC GSS err = %d, sys err = %d",
-					svc_name, mp->mechname,
-					err.rpc_gss_error, err.system_error);
+				    "can't set RPC GSS svc name '%s'"
+				    "for mech '%s': RPC GSS err = %d,"
+				    "sys err = %d",
+				    svc_name, mp->mechname,
+				    err.rpc_gss_error, err.system_error);
+			}
+
+			val = rpc_gss_set_svc_name(svc_name,  mp->mechname,
+			    0, NISPASSWD_PROG,
+			    NISPASSWD_VERS2);
+			if (val) {
+				if (verbose)
+					syslog(LOG_INFO,
+				"RPC GSS service name for mechanism '%s' set",
+					    mp->mechname);
+			} else {
+				rpc_gss_error_t	err;
+
+				rpc_gss_get_error(&err);
+				syslog(LOG_ERR,
+				    "can't set RPC GSS svc name '%s'"
+				    "for mech '%s': RPC GSS err = %d,"
+				    "sys err = %d",
+				    svc_name, mp->mechname,
+				    err.rpc_gss_error, err.system_error);
 			}
 		}
 		__nis_release_mechanisms(mechs);
--- a/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedescred.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -22,12 +21,10 @@
 /*
  *	makedescred.c
  *
- *	Copyright (c) 1988-1992,2001 by Sun Microsystems, Inc.
- *	All rights reserved.
+ *	Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ *	Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * makedescred.c
  *
@@ -45,6 +42,7 @@
 #include <nsswitch.h>
 #include <netdb.h>
 #include <rpcsvc/nis.h>
+#include <rpcsvc/nispasswd.h>
 #include <rpcsvc/nis_dhext.h>
 #include <rpc/key_prot.h>
 #include "nisaddcred.h"
@@ -84,7 +82,7 @@
 	struct key_netstarg netst;
 
 	netst.st_pub_key[0] = 0;
-	memcpy(netst.st_priv_key, secret, HEXKEYBYTES);
+	(void) memcpy(netst.st_priv_key, secret, HEXKEYBYTES);
 	netst.st_netname = netname;
 
 #ifdef NFS_AUTH
@@ -134,6 +132,7 @@
 {
 	nis_object	*obj = init_entry();
 	char 		*pass;
+	char		short_pass[DESCREDPASSLEN + 1];
 	uid_t		uid;
 	char 		public[HEXKEYBYTES + 1];
 	char		secret[HEXKEYBYTES + 1];
@@ -166,17 +165,18 @@
 	if (pass == 0)
 		return (0);
 
+	(void) strlcpy(short_pass, pass, sizeof (short_pass));
 	/* Get password with which to encrypt secret key. */
 	(void) printf("%s key pair for %s (%s).\n",
-			addition? "Adding" : "Updating", netname, nis_princ);
+	    addition? "Adding" : "Updating", netname, nis_princ);
 
 
 	/* Encrypt secret key */
-	(void) __gen_dhkeys(public, secret, pass);
-	memcpy(crypt1, secret, HEXKEYBYTES);
-	memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
+	(void) __gen_dhkeys(public, secret, short_pass);
+	(void) memcpy(crypt1, secret, HEXKEYBYTES);
+	(void) memcpy(crypt1 + HEXKEYBYTES, secret, KEYCHECKSUMSIZE);
 	crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
-	xencrypt(crypt1, pass);
+	xencrypt(crypt1, short_pass);
 
 
 	/* Now we have a key pair, build up the cred entry */
@@ -205,8 +205,8 @@
 		obj->zo_domain = domain;
 		/* owner: r, group: rmcd */
 		obj->zo_access = ((NIS_READ_ACC<<16)|
-				(NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC|
-					NIS_DESTROY_ACC)<<8);
+		    (NIS_READ_ACC|NIS_MODIFY_ACC|NIS_CREATE_ACC|
+		    NIS_DESTROY_ACC)<<8);
 		status = add_cred_obj(obj, domain);
 	} else {
 		obj->EN_data.en_cols.en_cols_val[3].ec_flags |= EN_MODIFIED;
@@ -236,8 +236,8 @@
 	if (mechlist = (mechanism_t **)__nis_get_mechanisms(FALSE)) {
 		while (mechlist[i]) {
 			status = make_dhext_cred(nis_princ, netname,
-							domain,
-							mechlist[i]->alias);
+			    domain,
+			    mechlist[i]->alias);
 			if (!status)
 				return (status);
 			i++;
--- a/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/cmd/rpcsvc/nis/utils/nisaddcred/makedhextcred.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -22,12 +21,10 @@
 /*
  *	makedescred.c
  *
- *	Copyright (c) 1997 Sun Microsystems Inc
- *	All Rights Reserved.
+ *	Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ *	Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * makedescred.c
  *
@@ -45,11 +42,13 @@
 #include <nsswitch.h>
 #include <netdb.h>
 #include <rpcsvc/nis.h>
+#include <rpcsvc/nispasswd.h>
 #include <rpcsvc/nis_dhext.h>
 #include <rpc/key_prot.h>
 #include "nisaddcred.h"
 
 extern char *getpass();
+extern char *getpassphrase();
 extern char *crypt();
 extern int add_cred_obj(nis_object *, char *);
 extern nis_error auth_exists(char *, char *, char *, char *);
@@ -82,11 +81,11 @@
 	static char policy[256];
 	int previous = 0;
 
-	memset((char *)policy, 0, 256);
+	(void) memset((char *)policy, 0, 256);
 
 	for (look = conf->lookups; look; look = look->next) {
 		if (previous)
-			strcat(policy, " ");
+			(void) strcat(policy, " ");
 		strcat(policy, look->service_name);
 		previous = 1;
 	}
@@ -106,8 +105,8 @@
 is_switch_policy(struct __nsw_switchconfig *conf, char *target)
 {
 	return (conf && conf->lookups &&
-		strcmp(conf->lookups->service_name, target) == 0 &&
-		conf->lookups->next == NULL);
+	    strcmp(conf->lookups->service_name, target) == 0 &&
+	    conf->lookups->next == NULL);
 }
 
 
@@ -124,25 +123,25 @@
 	if (no_switch_policy(conf)) {
 		if (!is_switch_policy(default_conf, target_service)) {
 			fprintf(stderr,
-				"\n%s\n There is no publickey entry in %s.\n",
-				head_msg, __NSW_CONFIG_FILE);
+			    "\n%s\n There is no publickey entry in %s.\n",
+			    head_msg, __NSW_CONFIG_FILE);
 			fprintf(stderr,
 			" The default publickey policy is \"publickey: %s\".\n",
-			switch_policy_str(default_conf));
+			    switch_policy_str(default_conf));
 			policy_correct = 0;
 		}
 	} else if (!is_switch_policy(conf, target_service)) {
 		fprintf(stderr,
 		"\n%s\n The publickey entry in %s is \"publickey: %s\".\n",
-			head_msg, __NSW_CONFIG_FILE,
-			switch_policy_str(conf));
+		    head_msg, __NSW_CONFIG_FILE,
+		    switch_policy_str(conf));
 		policy_correct = 0;
 	}
 	/* should we exit ? */
 	if (policy_correct == 0)
 		fprintf(stderr,
 		" It should be \"publickey: %s\"%s.\n\n",
-			target_service, tail_msg);
+		    target_service, tail_msg);
 	if (conf)
 		__nsw_freeconfig(conf);
 
@@ -160,17 +159,17 @@
 	/* Sanity check 0. Do we have a nis+ principal name to work with? */
 	if (nis_princ == NULL) {
 		fprintf(stderr,
-			"%s: you must create a \"local\" credential first.\n",
-			program_name);
+		    "%s: you must create a \"local\" credential first.\n",
+		    program_name);
 		fprintf(stderr,
-			"rerun this command as : %s local \n", program_name);
+		    "rerun this command as : %s local \n", program_name);
 		return (0);
 	}
 
 	/* Sanity check 1.  We only deal with one type of netnames. */
 	if (strncmp(netname, OPSYS, OPSYS_LEN) != 0) {
 		fprintf(stderr, "%s: unrecognized netname type: '%s'.\n",
-			program_name, netname);
+		    program_name, netname);
 		return (0);
 	}
 
@@ -179,7 +178,7 @@
 	if (strcasecmp(princdomain, domain) != 0) {
 		fprintf(stderr,
 "%s: domain of principal '%s' does not match destination domain '%s'.\n",
-			program_name, nis_princ, domain);
+		    program_name, nis_princ, domain);
 		fprintf(stderr,
 	"Should only add DES credential of principal in its home domain\n");
 		return (0);
@@ -192,7 +191,7 @@
 	netdomain = (char *)strchr(netname, '@');
 	if (! netdomain) {
 		fprintf(stderr, "%s: invalid netname, missing @: '%s'. \n",
-			program_name, netname);
+		    program_name, netname);
 		return (0);
 	}
 	if (netname[strlen(netname)-1] == '.')
@@ -210,7 +209,7 @@
 
 	/* Check publickey policy and warn user if it is not NIS+ */
 	check_switch_policy("publickey", "nisplus", &publickey_default,
-			    "WARNING:", " when using NIS+");
+	    "WARNING:", " when using NIS+");
 
 	/* Another principal owns same credentials? (exits if that happens) */
 	(void) auth_exists(nis_princ, netname, authtype, domain);
@@ -231,13 +230,13 @@
 			if (keylen == mechs[mcount]->keylen &&
 			    algtype == mechs[mcount]->algtype) {
 				if (key_setnet_g(netname, secret,
-							mechs[mcount]->keylen,
-							NULL, 0,
-							mechs[mcount]->algtype)
+				    mechs[mcount]->keylen,
+				    NULL, 0,
+				    mechs[mcount]->algtype)
 				    < 0) {
 					fprintf(stderr,
 					"Could not set %s's %s secret key\n",
-						netname, flavor);
+					    netname, flavor);
 					fprintf(stderr,
 					"May be the keyserv is down?\n");
 					return (0);
@@ -325,14 +324,14 @@
 	if ((rootfd = open(ROOTKEY_FILE, O_WRONLY+O_CREAT, 0600)) < 0) {
 		perror("Could not open /etc/.rootkey for writing");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
 		goto rootkey_err;
 	}
 	if (!(rootfile = fdopen(rootfd, "w"))) {
 		perror("Could not open /etc/.rootkey for writing");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		close(rootfd);
 		unlink(ROOTKEY_FILE);
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
@@ -341,7 +340,7 @@
 	if (!(bakfile = fopen(ROOTKEY_FILE_BACKUP, "r"))) {
 		perror("Could not open /etc/.rootkey.bak for reading");
 		fprintf(stderr,
-			"Attempting to restore original /etc/.rootkey\n");
+		    "Attempting to restore original /etc/.rootkey\n");
 		fclose(rootfile);
 		unlink(ROOTKEY_FILE);
 		rename(ROOTKEY_FILE_BACKUP, ROOTKEY_FILE);
@@ -400,7 +399,7 @@
 
 rootkey_err:
 	fprintf(stderr, "WARNING: Could not write %s key to /etc/.rootkey\n",
-		flavor);
+	    flavor);
 }
 
 
@@ -431,14 +430,14 @@
 			if (! pw) {
 				fprintf(stderr,
 			"%s: unable to locate password record for uid %d\n",
-					program_name, uid);
+				    program_name, uid);
 				return (0);
 			}
 			spw = getspnam(pw->pw_name);
 			if (!spw) {
 				fprintf(stderr,
 			"%s: unable to locate password record for uid 0\n",
-					program_name);
+				    program_name);
 				return (0);
 			}
 			login_password = spw->sp_pwdp;
@@ -460,14 +459,14 @@
 		sprintf(prompt, "Enter login password:");
 	else if (uid == 0) {
 		sprintf(prompt, "Enter %s's root login password:",
-			target_host);
+		    target_host);
 	} else
 		sprintf(prompt, "Enter %s's login password:",
-			pw->pw_name);
-	pass = getpass(prompt);
+		    pw->pw_name);
+	pass = getpassphrase(prompt);
 	if (strlen(pass) == 0) {
 		(void) fprintf(stderr, "%s: Password unchanged.\n",
-								program_name);
+		    program_name);
 		return (0);
 	}
 	strcpy(password, pass);
@@ -481,7 +480,7 @@
 		else {
 			fprintf(stderr,
 			"%s: %s: password differs from login password.\n",
-				program_name, force? "WARNING" : "ERROR");
+			    program_name, force? "WARNING" : "ERROR");
 			if (!force)
 				return (0);
 		}
@@ -489,10 +488,10 @@
 
 	/* Check for mis-typed password */
 	if (!passwords_matched) {
-		pass = getpass("Retype password:");
+		pass = getpassphrase("Retype password:");
 		if (strcmp(password, pass) != 0) {
 			(void) fprintf(stderr, "%s: password incorrect.\n",
-								program_name);
+			    program_name);
 			return (0);
 		}
 	}
@@ -532,6 +531,7 @@
 	uid_t		uid;
 	static char	*pass;
 	char		*public, *secret, *crypt1;
+	char		short_pass[DESCREDPASSLEN + 1];
 	char		authtype[MECH_MAXATNAME];
 	char		target_host[MAXHOSTNAMELEN+1];
 	int		same_host = 0;
@@ -573,6 +573,8 @@
 	if (!pass)
 		goto badstatus;
 
+	(void) strlcpy(short_pass, pass, sizeof (short_pass));
+
 	/* Get password with which to encrypt secret key. */
 	(void) printf("%s %s key pair for %s (%s).\n",
 			addition? "Adding" : "Updating", flavor,
@@ -585,9 +587,9 @@
 	    goto badstatus;
 
 	/* Encrypt secret key */
-	if (!(__gen_dhkeys_g(public, secret, kl, at, pass)))
+	if (!(__gen_dhkeys_g(public, secret, kl, at, short_pass)))
 		goto badstatus;
-	if (!(xencrypt_g(secret, kl, at, pass, netname, &crypt1, TRUE)))
+	if (!(xencrypt_g(secret, kl, at, short_pass, netname, &crypt1, TRUE)))
 		goto badstatus;
 
 	/* Now we have a key pair, build up the cred entry */
--- a/usr/src/head/rpcsvc/nispasswd.x	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/head/rpcsvc/nispasswd.x	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -22,12 +21,13 @@
 /*
  * NIS+ password update protocol
  *
- * Copyright (c) 1994, 1997 by Sun Microsystems Inc
- * All Rights Reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  *
- * ident	"%Z%%M%	%I%	%E% SMI"
  */
 
+%#include <limits.h>
+
 /*
  * Protocol description:
  * 	Request from client:
@@ -151,6 +151,21 @@
 	passwd_info	pass_info;		/* other information */
 };
 
+%#define DESCREDPASSLEN sizeof (des_block)
+const __NPD2_MAXPASSBYTES = 256;		/* _PASS_MAX */
+
+struct npd_newpass2 {
+	unsigned int	npd_xrandval;		/* R */
+	opaque	pass[__NPD2_MAXPASSBYTES];	/* "clear" new passwd */
+	unsigned int	npd_pad;	/* pad size to modulo des_block */
+};
+
+struct npd_update2 {
+	unsigned int	ident;			/* identifier */
+	npd_newpass2	xnewpass;		/* encrypted */
+	passwd_info	pass_info;		/* other information */
+};
+
 struct nispasswd_verf {
 	unsigned int	npd_xid;		/* encrypted identifier */
 	unsigned int	npd_xrandval;		/* encrypted R */
@@ -191,4 +206,16 @@
 		 */
 		nispasswd_updresult	NISPASSWD_UPDATE(npd_update) = 2;
 	} = 1;
+
+	version NISPASSWD_VERS2 {
+		/*
+		 * authenticate passwd update request
+		 */
+		nispasswd_authresult NISPASSWD_AUTHENTICATE(npd_request) = 1;
+
+		/*
+		 * send new passwd information
+		 */
+		nispasswd_updresult	NISPASSWD_UPDATE(npd_update2) = 2;
+	} = 2;
 } = 100303;
--- a/usr/src/lib/libnsl/common/llib-lnsl	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/lib/libnsl/common/llib-lnsl	Wed Jul 01 22:27:19 2009 +0530
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -446,6 +446,9 @@
 bool_t __npd_cbc_crypt(uint32_t *val, char *str, uint_t strsize,
 			npd_newpass *buf, uint_t bufsize, uint_t mode,
 			des_block *deskey);
+bool_t __npd2_cbc_crypt(uint32_t *val, char *str, uint_t strsize,
+			npd_newpass2 *buf, uint_t bufsize, uint_t mode,
+			des_block *deskey);
 
 /* print_obj.c */
 void nis_print_rights(u_int r);
--- a/usr/src/lib/libnsl/common/mapfile-vers	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/lib/libnsl/common/mapfile-vers	Wed Jul 01 22:27:19 2009 +0530
@@ -587,6 +587,7 @@
 	__nis_ss_used;
 	__nis_translate_mechanism;
 	nis_write_obj;
+	__npd2_cbc_crypt;
 	__npd_cbc_crypt;
 	__npd_ecb_crypt;
 	__nsl_dom;
--- a/usr/src/lib/libnsl/nis/gen/npd_lib.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/lib/libnsl/nis/gen/npd_lib.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -30,8 +29,6 @@
  *	and the client-side for NIS+ passwd update deamon.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include "mt.h"
 #include <string.h>
 #include <memory.h>
@@ -72,12 +69,12 @@
 		IXDR_PUT_U_INT32(ixdr, *val2);
 
 		status = ecb_crypt((char *)deskey, (char *)buf,
-				bufsize, mode | DES_HW);
+		    bufsize, mode | DES_HW);
 		if (DES_FAILED(status))
 			return (FALSE);
 	} else {
 		status = ecb_crypt((char *)deskey, (char *)buf,
-				bufsize, mode | DES_HW);
+		    bufsize, mode | DES_HW);
 
 		if (DES_FAILED(status))
 			return (FALSE);
@@ -106,8 +103,6 @@
 	int32_t	*ixdr;
 	des_block	ivec;
 
-	if (bufsize > MAX_KEY_CRYPT_LEN)
-		return (FALSE);
 	ivec.key.low = ivec.key.high = 0;
 	ixdr = (int32_t *)buf;
 	if (mode == DES_ENCRYPT) {
@@ -119,12 +114,12 @@
 			buf->pass[i] = '\0';
 
 		status = cbc_crypt((char *)deskey, (char *)buf,
-				bufsize, mode | DES_HW, (char *)&ivec);
+		    bufsize, mode | DES_HW, (char *)&ivec);
 		if (DES_FAILED(status))
 			return (FALSE);
 	} else {
 		status = cbc_crypt((char *)deskey, (char *)buf,
-				bufsize, mode | DES_HW, (char *)&ivec);
+		    bufsize, mode | DES_HW, (char *)&ivec);
 
 		if (DES_FAILED(status))
 			return (FALSE);
@@ -136,3 +131,50 @@
 	}
 	return (TRUE);
 }
+
+/*
+ * encrypt/decrypt R (val) and password (str)
+ * return FALSE on failure and TRUE on success
+ */
+bool_t
+__npd2_cbc_crypt(
+	uint32_t	*val,
+	char		*str,
+	unsigned int	strsize,
+	npd_newpass2	*buf,
+	unsigned int	bufsize,
+	unsigned int	mode,
+	des_block	*deskey)
+{
+	int	status, i;
+	int32_t	*ixdr;
+	des_block	ivec;
+
+	ivec.key.low = ivec.key.high = 0;
+	ixdr = (int32_t *)buf;
+	if (mode == DES_ENCRYPT) {
+		if ((strsize + 8) > bufsize)
+			return (FALSE);
+		IXDR_PUT_U_INT32(ixdr, *val);
+		(void) strcpy((char *)buf->pass, str);
+		for (i = strsize; i < __NPD2_MAXPASSBYTES; i++)
+			buf->pass[i] = '\0';
+		buf->npd_pad = 0;
+		status = cbc_crypt((char *)deskey, (char *)buf,
+		    bufsize, mode | DES_HW, (char *)&ivec);
+		if (DES_FAILED(status))
+			return (FALSE);
+	} else {
+		status = cbc_crypt((char *)deskey, (char *)buf,
+		    bufsize, mode | DES_HW, (char *)&ivec);
+
+		if (DES_FAILED(status))
+			return (FALSE);
+
+		*val = IXDR_GET_U_INT32(ixdr);
+		if (strlen((char *)buf->pass) > strsize)
+			return (FALSE);
+		(void) strcpy(str, (char *)buf->pass);
+	}
+	return (TRUE);
+}
--- a/usr/src/lib/passwdutil/nisplus_attr.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/lib/passwdutil/nisplus_attr.c	Wed Jul 01 22:27:19 2009 +0530
@@ -462,7 +462,7 @@
 	struct spwd *spw;
 	char *pword;
 	int len;
-	char newpw[_PASS_MAX_XPG+1];
+	char newpw[_PASS_MAX+1];
 
 	statebuf = (struct statebuf *)buf;
 	pw = statebuf->pwd;
@@ -508,8 +508,10 @@
 			 * This encryption is done by the NPD client
 			 * routines
 			 */
+			if (strlen(p->data.val_s) > __NPD2_MAXPASSBYTES)
+				return (PWU_DENIED);
+
 			(void) strlcpy(newpw, p->data.val_s, sizeof (newpw));
-
 			if ((spw->sp_pwdp = strdup(newpw)) == NULL)
 				return (PWU_NOMEM);
 			statebuf->proto |= PWU_NEW_PROTO;
@@ -736,7 +738,7 @@
 	char *domain;
 	nis_result *cred_res;
 	nis_result *handle;
-	char *newpw;
+	char short_newpw[DESCREDPASSLEN+1], *short_newpwp = NULL;
 
 	entry_col ecol[5];
 	nis_object *eobj;
@@ -786,7 +788,8 @@
 		return (PWU_SUCCESS);
 	}
 
-	newpw = buf->spwd->sp_pwdp;
+	(void) strlcpy(short_newpw, buf->spwd->sp_pwdp, sizeof (short_newpw));
+	short_newpwp = short_newpw;
 
 	for (i = 0; i < cred_res->objects.objects_len; i++) {
 		nis_object *cred_entry;
@@ -805,10 +808,11 @@
 		reencrypt_tries++;
 
 		newcryptsecret = reencrypt_secret(oldcryptsecret, oldrpcpw,
-		    newpw, uid, keylen, algtype);
+		    short_newpwp, uid, keylen, algtype);
 
-		if (newcryptsecret == NULL)
+		if (newcryptsecret == NULL) {
 			continue;
+		}
 
 		reencrypt_success++;
 
@@ -829,7 +833,7 @@
 		    "[cname=%s.%s,auth_type=%s],cred.%s", name, domain,
 		    authtype,
 		    NIS_RES_OBJECT(handle)->zo_domain) > sizeof (mname)-1) {
-			(void) memset(newpw, '\0', strlen(newpw));
+			(void) memset(short_newpw, '\0', strlen(short_newpw));
 			(void) memset(oldrpcpw, '\0', strlen(oldrpcpw));
 			free(newcryptsecret);
 			return (PWU_RECOVERY_ERR);
@@ -854,7 +858,8 @@
 		(void) nis_freeresult(mres);
 	}
 
-	(void) memset(newpw, '\0', strlen(newpw));
+	(void) memset(short_newpw, '\0', strlen(short_newpw));
+	short_newpwp = NULL;
 	(void) memset(oldrpcpw, '\0', strlen(oldrpcpw));
 
 	if (reencrypt_tries > 0 && mod_entry == 0) {
@@ -903,6 +908,7 @@
 	int		retval;
 	int		npd_res;
 	nispasswd_error	*errlist = NULL;
+	char		short_opass[DESCREDPASSLEN+1], *short_opassp = NULL;
 
 	statebuf = (struct statebuf *)buf;
 
@@ -924,9 +930,12 @@
 		goto out;
 	}
 
+	(void) strlcpy(short_opass, oldpw, sizeof (short_opass));
+	short_opassp = short_opass;
+
 	/* Generate a key-pair for this user */
 	if (__gen_dhkeys_g((char *)u_pubkey, u_seckey, srv_keylen,
-	    srv_keyalgtype, oldpw) == 0) {
+	    srv_keyalgtype, short_opassp) == 0) {
 		syslog(LOG_ERR, "Couldn't create a D-H key-pair "
 		    "(len = %d, type = %d)", srv_keylen, srv_keyalgtype);
 		retval = PWU_RECOVERY_ERR;
@@ -1015,7 +1024,7 @@
 			 * We therefore try to update the credentials directly.
 			 */
 			retval = nisplus_update_cred(name,
-			    oldrpcpw ? oldrpcpw : oldpw, rep, buf);
+			    oldrpcpw ? oldrpcpw : short_opassp, rep, buf);
 		} else {
 			/* We don't update creds for gecos/shell updates */
 			retval = PWU_SUCCESS;
@@ -1035,7 +1044,6 @@
 		auth_destroy(clnt->cl_auth);
 		clnt_destroy(clnt);
 	}
-
 	return (retval);
 }
 
@@ -1060,7 +1068,10 @@
 	nis_result *handle;
 	int pw_changed = 0;	/* indicates whether we should update creds */
 	int retval;
+	char short_opass[DESCREDPASSLEN+1], *short_opassp = NULL;
 
+	(void) strlcpy(short_opass, oldpw, sizeof (short_opass));
+	short_opassp = short_opass;
 	statebuf = (struct statebuf *)buf;
 	pw = statebuf->pwd;
 	spw = statebuf->spwd;
@@ -1177,15 +1188,16 @@
 	eobj->EN_data.en_cols.en_cols_val = NULL;
 	eobj->EN_data.en_cols.en_cols_len = 0;
 	(void) nis_destroy_object(eobj);
-	(void) nis_freeresult(result);
-
+	if (result)
+		(void) nis_freeresult(result);
+	result = NULL;
 out:
 	if (ecol[COL_PASSWD].EC_VAL)
 		free(ecol[COL_PASSWD].EC_VAL);
 
 	if (pw_changed == 1 && retval == PWU_SUCCESS)
-		retval = nisplus_update_cred(name, oldrpcpw ? oldrpcpw : oldpw,
-		    rep, buf);
+		retval = nisplus_update_cred(name, oldrpcpw ? oldrpcpw
+		    : short_opassp, rep, buf);
 
 	return (retval);
 
@@ -1205,26 +1217,30 @@
 	struct statebuf *statebuf;
 	int result = PWU_SUCCESS;
 	uid_t cur_euid;
-	char short_pw[_PASS_MAX_XPG+1], short_rpcpw[_PASS_MAX_XPG+1];
-	char *short_pwptr = NULL, *short_rpcpwptr = NULL;
+	char short_rpcpw[_PASS_MAX_XPG+1];
+	char *short_rpcpwptr = NULL;
+	char pw[_PASS_MAX+1];
+	char *pw_ptr = NULL;
 
 	if (strcmp(name, "root") == 0)
 		return (PWU_NOT_FOUND);
 
 	if (oldpw) {
-		(void) strlcpy(short_pw, oldpw, sizeof (short_pw));
-		short_pwptr = short_pw;
-	}
+		(void) strlcpy(pw, oldpw, sizeof (pw));
+		pw_ptr = pw;
+	} else /* oldpw is NULL. rpc.nispasswdd non-responsive ??? */
+		return (PWU_RECOVERY_ERR);
 
 	if (oldrpcpw) {
 		(void) strlcpy(short_rpcpw, oldrpcpw, sizeof (short_rpcpw));
 		short_rpcpwptr = short_rpcpw;
-	}
+	} else
+		return (PWU_RECOVERY_ERR);
 
 	statebuf = (struct statebuf *)buf;
 
 	if (statebuf->proto & PWU_OLD_PROTO) {
-		result = nisplus_old_proto(name, short_pwptr,
+		result = nisplus_old_proto(name, pw_ptr,
 		    short_rpcpwptr, rep, buf);
 	}
 
@@ -1233,9 +1249,8 @@
 		if (getuid() != 0)
 			(void) seteuid(getuid());
 
-		result = nisplus_new_proto(name, short_pwptr,
+		result = nisplus_new_proto(name, pw_ptr,
 		    short_rpcpwptr, rep, buf);
-
 		(void) seteuid(cur_euid);
 	}
 
--- a/usr/src/lib/passwdutil/npd_clnt.c	Wed Jul 01 08:42:32 2009 -0700
+++ b/usr/src/lib/passwdutil/npd_clnt.c	Wed Jul 01 22:27:19 2009 +0530
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,8 +30,6 @@
  *
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <syslog.h>
 #include <string.h>
@@ -48,6 +45,7 @@
 #include <memory.h>
 #include <sys/time.h>
 #include <unistd.h>
+#include <sys/types.h>
 
 #define	_NPD_PASSMAXLEN	16
 
@@ -57,6 +55,10 @@
 extern bool_t	__npd_cbc_crypt(uint32_t *, char *, unsigned int,
 				npd_newpass *, unsigned int, unsigned int,
 				des_block *);
+extern bool_t	__npd2_cbc_crypt(uint32_t *, char *, unsigned int,
+				npd_newpass2 *, unsigned int, unsigned int,
+				des_block *);
+rpcvers_t	clnt_vers = NISPASSWD_VERS2;
 
 /*
  * Loop thru the NIS+ security cf entries until one DH(EXT) mech key is
@@ -96,7 +98,7 @@
 				continue;
 
 			if (hexkey = __nis_dhext_extract_pkey(pkey,
-						mp->keylen, mp->algtype)) {
+			    mp->keylen, mp->algtype)) {
 				if ((*keybuf = malloc(strlen(hexkey) + 1))
 				    == 0) {
 					syslog(LOG_ERR, "malloc failed");
@@ -118,7 +120,7 @@
 	/* no valid cf mech entries or AUTH_DES compat entry found */
 	try_auth_des:
 		if (hexkey = __nis_dhext_extract_pkey(pkey,
-					AUTH_DES_KEYLEN, AUTH_DES_ALGTYPE)) {
+		    AUTH_DES_KEYLEN, AUTH_DES_ALGTYPE)) {
 			if ((*keybuf = malloc(strlen(hexkey) + 1)) == NULL) {
 					syslog(LOG_ERR, "malloc failed");
 					return (FALSE);
@@ -159,6 +161,7 @@
 	nis_server	*master_srv;
 	char		buf[NIS_MAXNAMELEN];
 	CLIENT		*tmpclnt = NULL;
+	rpcvers_t	vers;
 
 	if (domain == NULL || *domain == '\0')
 		domain = nis_local_directory();
@@ -224,10 +227,16 @@
 	 * nis_make_rpchandle() will attempt to use auth_des first,
 	 * if user does not have D-H keys, then it will try auth_sys.
 	 * sendsz and recvsz are 0 ==> choose defaults.
+	 *
+	 * First try NISPASSWD_VERS2. If it fails, fallback to NISPASSWD_VERS
 	 */
-	tmpclnt = nis_make_rpchandle_gss_svc_ruid(master_srv, 0, NISPASSWD_PROG,
-				NISPASSWD_VERS, ZMH_VC+ZMH_AUTH, 0, 0, NULL,
-				NIS_SVCNAME_NISPASSWD);
+	for (vers = NISPASSWD_VERS2;
+		(vers >= NISPASSWD_VERS) && (tmpclnt == NULL); vers--) {
+		tmpclnt = nis_make_rpchandle_gss_svc_ruid(master_srv, 0,
+				NISPASSWD_PROG, vers, ZMH_VC+ZMH_AUTH, 0,
+				0, NULL, NIS_SVCNAME_NISPASSWD);
+		clnt_vers = vers;
+	}
 
 	/* done with server list */
 	(void) nis_freeservlist(srvs);
@@ -270,7 +279,8 @@
 	npd_request	req_arg;
 	nispasswd_authresult	res;
 	des_block	ivec;
-	unsigned char	xpass[_NPD_PASSMAXLEN];
+	unsigned char	xpass[_NPD_PASSMAXLEN+1];
+	unsigned char	xpass2[__NPD2_MAXPASSBYTES+1];
 	des_block	cryptbuf;
 	int		cryptstat;
 	int		i;
@@ -287,28 +297,54 @@
 	(void) memset((char *)&req_arg, 0, sizeof (req_arg));
 	(void) memset((char *)&res, 0, sizeof (res));
 
-	/* encrypt the passwd with the common des key */
-	if (strlen(oldpass) > (size_t)_NPD_PASSMAXLEN) {
-		*err = NPD_BUFTOOSMALL;
-		return (NPD_FAILED);
-	}
-	(void) strcpy((char *)xpass, oldpass);
-	for (i = strlen(oldpass); i < _NPD_PASSMAXLEN; i++)
-		xpass[i] = '\0';
+	if (clnt_vers == NISPASSWD_VERS) {
+		/* encrypt the passwd with the common des key */
+		if (strlen(oldpass) > (size_t)_NPD_PASSMAXLEN) {
+			*err = NPD_BUFTOOSMALL;
+			return (NPD_FAILED);
+		}
+		(void) strlcpy((char *)xpass, oldpass, sizeof (xpass));
+		for (i = strlen(oldpass); i < _NPD_PASSMAXLEN; i++)
+			xpass[i] = '\0';
 
-	ivec.key.high = ivec.key.low = 0;
-	if (AUTH_DES_KEY(keylen, algtype))
-		cryptstat = cbc_crypt((char *)deskeys[0].c, (char *)xpass,
-					_NPD_PASSMAXLEN, DES_ENCRYPT | DES_HW,
-					(char *)&ivec);
-	else
-		cryptstat = __cbc_triple_crypt(deskeys, (char *)xpass,
+		ivec.key.high = ivec.key.low = 0;
+		if (AUTH_DES_KEY(keylen, algtype))
+			cryptstat = cbc_crypt((char *)deskeys[0].c,
+					(char *)xpass, _NPD_PASSMAXLEN,
+					DES_ENCRYPT | DES_HW, (char *)&ivec);
+		else
+			cryptstat = __cbc_triple_crypt(deskeys, (char *)xpass,
 					_NPD_PASSMAXLEN, DES_ENCRYPT | DES_HW,
 					(char *)&ivec);
 
-	if (DES_FAILED(cryptstat)) {
-		*err = NPD_ENCRYPTFAIL;
-		return (NPD_FAILED);
+		if (DES_FAILED(cryptstat)) {
+			*err = NPD_ENCRYPTFAIL;
+			return (NPD_FAILED);
+		}
+	} else {
+		/* encrypt the passwd with the common des key */
+		if (strlen(oldpass) > (size_t)__NPD2_MAXPASSBYTES) {
+			*err = NPD_BUFTOOSMALL;
+			return (NPD_FAILED);
+		}
+		(void) strlcpy((char *)xpass2, oldpass, sizeof (xpass2));
+		for (i = strlen(oldpass); i < __NPD2_MAXPASSBYTES; i++)
+			xpass2[i] = '\0';
+
+		ivec.key.high = ivec.key.low = 0;
+		if (AUTH_DES_KEY(keylen, algtype))
+			cryptstat = cbc_crypt((char *)deskeys[0].c,
+					(char *)xpass2, __NPD2_MAXPASSBYTES,
+					DES_ENCRYPT | DES_HW, (char *)&ivec);
+		else
+			cryptstat = __cbc_triple_crypt(deskeys, (char *)xpass2,
+					__NPD2_MAXPASSBYTES,
+					DES_ENCRYPT | DES_HW, (char *)&ivec);
+
+		if (DES_FAILED(cryptstat)) {
+			*err = NPD_ENCRYPTFAIL;
+			return (NPD_FAILED);
+		}
 	}
 
 	req_arg.username = user;
@@ -317,8 +353,13 @@
 	req_arg.user_pub_key.user_pub_key_len =
 			strlen((char *)u_pubkey) + 1;
 	req_arg.user_pub_key.user_pub_key_val = u_pubkey;
-	req_arg.npd_authpass.npd_authpass_len = _NPD_PASSMAXLEN;
-	req_arg.npd_authpass.npd_authpass_val = xpass;
+	if (clnt_vers == NISPASSWD_VERS) {
+		req_arg.npd_authpass.npd_authpass_len = _NPD_PASSMAXLEN;
+		req_arg.npd_authpass.npd_authpass_val = xpass;
+	} else {
+		req_arg.npd_authpass.npd_authpass_len = __NPD2_MAXPASSBYTES;
+		req_arg.npd_authpass.npd_authpass_val = xpass2;
+	}
 	req_arg.ident = *ident;		/* on re-tries ident is non-zero */
 
 	if (clnt_call(clnt, NISPASSWD_AUTHENTICATE,
@@ -383,10 +424,15 @@
 nispasswd_error	**errlst;	/* error list on partial success, returned */
 {
 	npd_update	send_arg;
+	npd_update2	send_arg2;
 	nispasswd_updresult	result;
-	npd_newpass	cryptbuf;
+	npd_newpass	cryptbuf1;
+	npd_newpass2	cryptbuf2;
 	unsigned int	tmp_xrval;
+	unsigned int	tmp_npd_pad;
 	nispasswd_error	*errl = NULL, *p;
+	char   xnewpass[__NPD_MAXPASSBYTES+1];
+	char   xnewpass2[__NPD2_MAXPASSBYTES+1];
 
 	if ((clnt == (CLIENT *) NULL) ||
 		(deskey == (des_block *) NULL) ||
@@ -394,37 +440,76 @@
 		*err = NPD_INVALIDARGS;
 		return (NPD_FAILED);
 	}
-	(void) memset((char *)&send_arg, 0, sizeof (send_arg));
-	(void) memset((char *)&result, 0, sizeof (result));
+
+	if (clnt_vers == NISPASSWD_VERS) {
+		(void) memset((char *)&send_arg, 0, sizeof (send_arg));
+		(void) memset((char *)&result, 0, sizeof (result));
+		send_arg.ident = ident;
+
+		(void) strlcpy(xnewpass, newpass, sizeof (xnewpass));
 
-	send_arg.ident = ident;
+		if (! __npd_cbc_crypt(&randval, xnewpass, strlen(xnewpass),
+			&cryptbuf1, _NPD_PASSMAXLEN, DES_ENCRYPT, deskey)) {
+			*err = NPD_ENCRYPTFAIL;
+			return (NPD_FAILED);
+		}
+		tmp_xrval = cryptbuf1.npd_xrandval;
+		cryptbuf1.npd_xrandval = htonl(tmp_xrval);
+		send_arg.xnewpass = cryptbuf1;
 
-	if (! __npd_cbc_crypt(&randval, newpass, strlen(newpass),
-		&cryptbuf, _NPD_PASSMAXLEN, DES_ENCRYPT, deskey)) {
+		/* gecos */
+		send_arg.pass_info.pw_gecos = gecos;
+
+		/* shell */
+		send_arg.pass_info.pw_shell = shell;
 
-		*err = NPD_ENCRYPTFAIL;
-		return (NPD_FAILED);
-	}
-	tmp_xrval = cryptbuf.npd_xrandval;
-	cryptbuf.npd_xrandval = htonl(tmp_xrval);
-	send_arg.xnewpass = cryptbuf;
+		if (clnt_call(clnt, NISPASSWD_UPDATE,
+			(xdrproc_t)xdr_npd_update, (caddr_t)&send_arg,
+			(xdrproc_t)xdr_nispasswd_updresult, (caddr_t)&result,
+			TIMEOUT) != RPC_SUCCESS) {
+
+			/* printed to stderr */
+			(void) clnt_perror(clnt,
+			    "update call to rpc.nispasswdd failed");
+			*err = NPD_SRVNOTRESP;
+			return (NPD_FAILED);
+		}
 
-	/* gecos */
-	send_arg.pass_info.pw_gecos = gecos;
+	} else {
+		(void) memset((char *)&send_arg2, 0, sizeof (send_arg2));
+		(void) memset((char *)&result, 0, sizeof (result));
+		send_arg2.ident = ident;
+
+		(void) strlcpy(xnewpass2, newpass, sizeof (xnewpass2));
 
-	/* shell */
-	send_arg.pass_info.pw_shell = shell;
+		if (! __npd2_cbc_crypt(&randval, xnewpass2, strlen(xnewpass2),
+			&cryptbuf2, sizeof (cryptbuf2), DES_ENCRYPT,
+			deskey)) {
+			*err = NPD_ENCRYPTFAIL;
+			return (NPD_FAILED);
+		}
+		tmp_xrval = cryptbuf2.npd_xrandval;
+		tmp_npd_pad = cryptbuf2.npd_pad;
+		cryptbuf2.npd_xrandval = htonl(tmp_xrval);
+		cryptbuf2.npd_pad = htonl(tmp_npd_pad);
 
-	if (clnt_call(clnt, NISPASSWD_UPDATE,
-		(xdrproc_t)xdr_npd_update, (caddr_t)&send_arg,
-		(xdrproc_t)xdr_nispasswd_updresult, (caddr_t)&result,
-		TIMEOUT) != RPC_SUCCESS) {
+		send_arg2.xnewpass = cryptbuf2;
+		/* gecos */
+		send_arg2.pass_info.pw_gecos = gecos;
+		/* shell */
+		send_arg2.pass_info.pw_shell = shell;
 
-		/* printed to stderr */
-		(void) clnt_perror(clnt,
-		    "update call to rpc.nispasswdd failed");
-		*err = NPD_SRVNOTRESP;
-		return (NPD_FAILED);
+		if (clnt_call(clnt, NISPASSWD_UPDATE,
+			(xdrproc_t)xdr_npd_update2, (caddr_t)&send_arg2,
+			(xdrproc_t)xdr_nispasswd_updresult, (caddr_t)&result,
+			TIMEOUT) != RPC_SUCCESS) {
+
+			/* printed to stderr */
+			(void) clnt_perror(clnt,
+			    "update call to rpc.nispasswdd failed");
+			*err = NPD_SRVNOTRESP;
+			return (NPD_FAILED);
+		}
 	}
 	switch (result.status) {
 	case NPD_SUCCESS: