xref: /titanic_44/usr/src/cmd/krb5/kadmin/kpasswd/kpasswd.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
117c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
127c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
137c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
147c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
177c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
187c478bd9Sstevel@tonic-gate  *	copyright.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
217c478bd9Sstevel@tonic-gate  *
227c478bd9Sstevel@tonic-gate  */
237c478bd9Sstevel@tonic-gate 
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * Copyright 1993-1994 OpenVision Technologies, Inc., All Rights Reserved.
277c478bd9Sstevel@tonic-gate  *
28*159d09a2SMark Phalan  * $Header$
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  *
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
33*159d09a2SMark Phalan static char rcsid[] = "$Id: kpasswd.c 17258 2005-06-21 01:36:03Z raeburn $";
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include <kadm5/admin.h>
367c478bd9Sstevel@tonic-gate #include <krb5.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include "kpasswd_strings.h"
397c478bd9Sstevel@tonic-gate #define string_text error_message
407c478bd9Sstevel@tonic-gate 
4156a424ccSmp153739 #include "kpasswd.h"
4256a424ccSmp153739 
437c478bd9Sstevel@tonic-gate #include <stdio.h>
447c478bd9Sstevel@tonic-gate #include <pwd.h>
457c478bd9Sstevel@tonic-gate #include <string.h>
467c478bd9Sstevel@tonic-gate #include <libintl.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate extern char *whoami;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate extern void display_intro_message();
517c478bd9Sstevel@tonic-gate extern long read_old_password();
527c478bd9Sstevel@tonic-gate extern long read_new_password();
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #define MISC_EXIT_STATUS 6
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate /*
577c478bd9Sstevel@tonic-gate  * Function: kpasswd
587c478bd9Sstevel@tonic-gate  *
597c478bd9Sstevel@tonic-gate  * Purpose: Initialize and call lower level routines to change a password
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * Arguments:
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  *	context		(r) krb5_context to use
647c478bd9Sstevel@tonic-gate  *	argc/argv	(r) principal name to use, optional
657c478bd9Sstevel@tonic-gate  *	read_old_password (f) function to read old password
667c478bd9Sstevel@tonic-gate  *	read_new_password (f) function to read new and change password
677c478bd9Sstevel@tonic-gate  *	display_intro_message (f) function to display intro message
687c478bd9Sstevel@tonic-gate  *	whoami		(extern) argv[0]
697c478bd9Sstevel@tonic-gate  *
707c478bd9Sstevel@tonic-gate  * Returns:
717c478bd9Sstevel@tonic-gate  *                      exit status of 0 for success
727c478bd9Sstevel@tonic-gate  *			1 principal unknown
737c478bd9Sstevel@tonic-gate  *			2 old password wrong
747c478bd9Sstevel@tonic-gate  *			3 cannot initialize admin server session
757c478bd9Sstevel@tonic-gate  *			4 new passwd mismatch or error trying to change pw
767c478bd9Sstevel@tonic-gate  *                      5 password not typed
777c478bd9Sstevel@tonic-gate  *                      6 misc error
787c478bd9Sstevel@tonic-gate  *                      7 incorrect usage
797c478bd9Sstevel@tonic-gate  *
807c478bd9Sstevel@tonic-gate  * Requires:
817c478bd9Sstevel@tonic-gate  *	Passwords cannot be more than 255 characters long.
827c478bd9Sstevel@tonic-gate  *
837c478bd9Sstevel@tonic-gate  * Effects:
847c478bd9Sstevel@tonic-gate  *
857c478bd9Sstevel@tonic-gate  * If argc is 2, the password for the principal specified in argv[1]
867c478bd9Sstevel@tonic-gate  * is changed; otherwise, the principal of the default credential
877c478bd9Sstevel@tonic-gate  * cache or username is used.  display_intro_message is called with
887c478bd9Sstevel@tonic-gate  * the arguments KPW_STR_CHANGING_PW_FOR and the principal name.
897c478bd9Sstevel@tonic-gate  * read_old_password is then called to prompt for the old password.
907c478bd9Sstevel@tonic-gate  * The admin system is then initialized, the principal's policy
917c478bd9Sstevel@tonic-gate  * retrieved and explained, if appropriate, and finally
927c478bd9Sstevel@tonic-gate  * read_new_password is called to read the new password and change the
937c478bd9Sstevel@tonic-gate  * principal's password (presumably ovsec_kadm_chpass_principal).
947c478bd9Sstevel@tonic-gate  * admin system is de-initialized before the function returns.
957c478bd9Sstevel@tonic-gate  *
967c478bd9Sstevel@tonic-gate  * Modifies:
977c478bd9Sstevel@tonic-gate  *
987c478bd9Sstevel@tonic-gate  * Changes the principal's password.
997c478bd9Sstevel@tonic-gate  *
1007c478bd9Sstevel@tonic-gate  */
1017c478bd9Sstevel@tonic-gate int
kpasswd(context,argc,argv)1027c478bd9Sstevel@tonic-gate kpasswd(context, argc, argv)
1037c478bd9Sstevel@tonic-gate    krb5_context context;
1047c478bd9Sstevel@tonic-gate    int argc;
1057c478bd9Sstevel@tonic-gate    char *argv[];
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate   kadm5_ret_t code;
1087c478bd9Sstevel@tonic-gate   krb5_ccache ccache = NULL;
1097c478bd9Sstevel@tonic-gate   krb5_principal princ = 0;
1107c478bd9Sstevel@tonic-gate   char *princ_str;
1117c478bd9Sstevel@tonic-gate   struct passwd *pw = 0;
11256a424ccSmp153739   unsigned int pwsize;
11356a424ccSmp153739   char password[255];  /* I don't really like 255 but that's what kinit uses */
1147c478bd9Sstevel@tonic-gate   char msg_ret[1024], admin_realm[1024];
1157c478bd9Sstevel@tonic-gate   kadm5_principal_ent_rec principal_entry;
1167c478bd9Sstevel@tonic-gate   kadm5_policy_ent_rec policy_entry;
1177c478bd9Sstevel@tonic-gate   void *server_handle;
1187c478bd9Sstevel@tonic-gate   kadm5_config_params params;
1197c478bd9Sstevel@tonic-gate   char *cpw_service;
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	memset((char *)&params, 0, sizeof (params));
1227c478bd9Sstevel@tonic-gate 	memset(&principal_entry, 0, sizeof (principal_entry));
1237c478bd9Sstevel@tonic-gate 	memset(&policy_entry, 0, sizeof (policy_entry));
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate   if (argc > 2) {
1267c478bd9Sstevel@tonic-gate       com_err(whoami, KPW_STR_USAGE, 0);
1277c478bd9Sstevel@tonic-gate       return(7);
1287c478bd9Sstevel@tonic-gate       /*NOTREACHED*/
1297c478bd9Sstevel@tonic-gate     }
1307c478bd9Sstevel@tonic-gate 
13156a424ccSmp153739   /************************************
13256a424ccSmp153739    *  Get principal name to change    *
13356a424ccSmp153739    ************************************/
13456a424ccSmp153739 
13556a424ccSmp153739   /* Look on the command line first, followed by the default credential
13656a424ccSmp153739      cache, followed by defaulting to the Unix user name */
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate   if (argc == 2)
1397c478bd9Sstevel@tonic-gate     princ_str = strdup(argv[1]);
1407c478bd9Sstevel@tonic-gate   else {
1417c478bd9Sstevel@tonic-gate     code = krb5_cc_default(context, &ccache);
1427c478bd9Sstevel@tonic-gate     /* If we succeed, find who is in the credential cache */
1437c478bd9Sstevel@tonic-gate     if (code == 0) {
1447c478bd9Sstevel@tonic-gate       /* Get default principal from cache if one exists */
1457c478bd9Sstevel@tonic-gate       code = krb5_cc_get_principal(context, ccache, &princ);
14656a424ccSmp153739       /* if we got a principal, unparse it, otherwise get out of the if
14756a424ccSmp153739 	 with an error code */
1487c478bd9Sstevel@tonic-gate       (void) krb5_cc_close(context, ccache);
1497c478bd9Sstevel@tonic-gate       if (code == 0) {
15056a424ccSmp153739 	code = krb5_unparse_name(context, princ, &princ_str);
1517c478bd9Sstevel@tonic-gate 	if (code != 0) {
15256a424ccSmp153739 	  com_err(whoami,  code, string_text(KPW_STR_UNPARSE_NAME));
1537c478bd9Sstevel@tonic-gate 	  return(MISC_EXIT_STATUS);
1547c478bd9Sstevel@tonic-gate 	}
1557c478bd9Sstevel@tonic-gate       }
1567c478bd9Sstevel@tonic-gate     }
15756a424ccSmp153739 
1587c478bd9Sstevel@tonic-gate     /* this is a crock.. we want to compare against */
15956a424ccSmp153739     /* "KRB5_CC_DOESNOTEXIST" but there is no such error code, and */
16056a424ccSmp153739     /* both the file and stdio types return FCC_NOFILE.  If there is */
1617c478bd9Sstevel@tonic-gate     /* ever another ccache type (or if the error codes are ever */
1627c478bd9Sstevel@tonic-gate     /* fixed), this code will have to be updated. */
1637c478bd9Sstevel@tonic-gate     if (code && code != KRB5_FCC_NOFILE) {
16456a424ccSmp153739       com_err(whoami, code, string_text(KPW_STR_WHILE_LOOKING_AT_CC));
1657c478bd9Sstevel@tonic-gate       return(MISC_EXIT_STATUS);
1667c478bd9Sstevel@tonic-gate     }
16756a424ccSmp153739 
1687c478bd9Sstevel@tonic-gate     /* if either krb5_cc failed check the passwd file */
1697c478bd9Sstevel@tonic-gate     if (code != 0) {
1707c478bd9Sstevel@tonic-gate       pw = getpwuid( getuid());
1717c478bd9Sstevel@tonic-gate       if (pw == NULL) {
17256a424ccSmp153739 	com_err(whoami, 0, string_text(KPW_STR_NOT_IN_PASSWD_FILE));
1737c478bd9Sstevel@tonic-gate 	return(MISC_EXIT_STATUS);
1747c478bd9Sstevel@tonic-gate       }
1757c478bd9Sstevel@tonic-gate       princ_str = strdup(pw->pw_name);
1767c478bd9Sstevel@tonic-gate     }
1777c478bd9Sstevel@tonic-gate   }
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate   display_intro_message(string_text(KPW_STR_CHANGING_PW_FOR), princ_str);
1807c478bd9Sstevel@tonic-gate 
18156a424ccSmp153739   /* Need to get a krb5_principal, unless we started from with one from
18256a424ccSmp153739      the credential cache */
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate   if (! princ) {
1857c478bd9Sstevel@tonic-gate       code = krb5_parse_name (context, princ_str, &princ);
1867c478bd9Sstevel@tonic-gate       if (code != 0) {
18756a424ccSmp153739 	  com_err(whoami, code, string_text(KPW_STR_PARSE_NAME), princ_str);
1887c478bd9Sstevel@tonic-gate 	  free(princ_str);
1897c478bd9Sstevel@tonic-gate 	  return(MISC_EXIT_STATUS);
1907c478bd9Sstevel@tonic-gate       }
1917c478bd9Sstevel@tonic-gate   }
19256a424ccSmp153739 
1937c478bd9Sstevel@tonic-gate   pwsize = sizeof(password);
1947c478bd9Sstevel@tonic-gate   code = read_old_password(context, password, &pwsize);
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate   if (code != 0) {
1977c478bd9Sstevel@tonic-gate     memset(password, 0, sizeof(password));
19856a424ccSmp153739     com_err(whoami, code, string_text(KPW_STR_WHILE_READING_PASSWORD));
1997c478bd9Sstevel@tonic-gate     krb5_free_principal(context, princ);
2007c478bd9Sstevel@tonic-gate     free(princ_str);
2017c478bd9Sstevel@tonic-gate     return(MISC_EXIT_STATUS);
2027c478bd9Sstevel@tonic-gate   }
2037c478bd9Sstevel@tonic-gate   if (pwsize == 0) {
2047c478bd9Sstevel@tonic-gate     memset(password, 0, sizeof(password));
2057c478bd9Sstevel@tonic-gate     com_err(whoami, 0, string_text(KPW_STR_NO_PASSWORD_READ));
2067c478bd9Sstevel@tonic-gate     krb5_free_principal(context, princ);
2077c478bd9Sstevel@tonic-gate     free(princ_str);
2087c478bd9Sstevel@tonic-gate     return(5);
2097c478bd9Sstevel@tonic-gate   }
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	snprintf(admin_realm, sizeof (admin_realm),
2127c478bd9Sstevel@tonic-gate 		krb5_princ_realm(context, princ)->data);
2137c478bd9Sstevel@tonic-gate 	params.mask |= KADM5_CONFIG_REALM;
2147c478bd9Sstevel@tonic-gate 	params.realm = admin_realm;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
2187c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("%s: unable to get host based "
2197c478bd9Sstevel@tonic-gate 					"service name for realm %s\n"),
2207c478bd9Sstevel@tonic-gate 			whoami, admin_realm);
2217c478bd9Sstevel@tonic-gate 		exit(1);
2227c478bd9Sstevel@tonic-gate 	}
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	code = kadm5_init_with_password(princ_str, password, cpw_service,
2257c478bd9Sstevel@tonic-gate 					&params, KADM5_STRUCT_VERSION,
22654925bf6Swillf 					KADM5_API_VERSION_2, NULL,
22754925bf6Swillf 					&server_handle);
2287c478bd9Sstevel@tonic-gate 	free(cpw_service);
2297c478bd9Sstevel@tonic-gate 	if (code != 0) {
2307c478bd9Sstevel@tonic-gate 		if (code == KADM5_BAD_PASSWORD)
2317c478bd9Sstevel@tonic-gate 			com_err(whoami, 0,
2327c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_OLD_PASSWORD_INCORRECT));
2337c478bd9Sstevel@tonic-gate 		else
2347c478bd9Sstevel@tonic-gate 			com_err(whoami, 0,
2357c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_CANT_OPEN_ADMIN_SERVER),
2367c478bd9Sstevel@tonic-gate 				admin_realm,
2377c478bd9Sstevel@tonic-gate 				error_message(code));
2387c478bd9Sstevel@tonic-gate 		krb5_free_principal(context, princ);
2397c478bd9Sstevel@tonic-gate 		free(princ_str);
2407c478bd9Sstevel@tonic-gate 		return ((code == KADM5_BAD_PASSWORD) ? 2 : 3);
2417c478bd9Sstevel@tonic-gate 	}
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	/*
2447c478bd9Sstevel@tonic-gate 	 * we can only check the policy if the server speaks
2457c478bd9Sstevel@tonic-gate 	 * RPCSEC_GSS
2467c478bd9Sstevel@tonic-gate 	 */
2477c478bd9Sstevel@tonic-gate 	if (_kadm5_get_kpasswd_protocol(server_handle) == KRB5_CHGPWD_RPCSEC) {
2487c478bd9Sstevel@tonic-gate 		/* Explain policy restrictions on new password if any. */
2497c478bd9Sstevel@tonic-gate 		/*
2507c478bd9Sstevel@tonic-gate 		 * Note: copy of this exists in login
2517c478bd9Sstevel@tonic-gate 		 * (kverify.c/get_verified_in_tkt).
2527c478bd9Sstevel@tonic-gate 		 */
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 		code = kadm5_get_principal(server_handle, princ,
2557c478bd9Sstevel@tonic-gate 					&principal_entry,
2567c478bd9Sstevel@tonic-gate 					KADM5_PRINCIPAL_NORMAL_MASK);
2577c478bd9Sstevel@tonic-gate 		if (code != 0) {
2587c478bd9Sstevel@tonic-gate 			com_err(whoami, 0,
2597c478bd9Sstevel@tonic-gate 				string_text((code == KADM5_UNK_PRINC)
2607c478bd9Sstevel@tonic-gate 					    ? KPW_STR_PRIN_UNKNOWN :
2617c478bd9Sstevel@tonic-gate 					    KPW_STR_CANT_GET_POLICY_INFO),
2627c478bd9Sstevel@tonic-gate 				princ_str);
2637c478bd9Sstevel@tonic-gate 			krb5_free_principal(context, princ);
2647c478bd9Sstevel@tonic-gate 			free(princ_str);
2657c478bd9Sstevel@tonic-gate 			(void) kadm5_destroy(server_handle);
2667c478bd9Sstevel@tonic-gate 			return ((code == KADM5_UNK_PRINC) ? 1 :
2677c478bd9Sstevel@tonic-gate 				MISC_EXIT_STATUS);
2687c478bd9Sstevel@tonic-gate 		}
2697c478bd9Sstevel@tonic-gate 		if ((principal_entry.aux_attributes & KADM5_POLICY) != 0) {
2707c478bd9Sstevel@tonic-gate 			code = kadm5_get_policy(server_handle,
2717c478bd9Sstevel@tonic-gate 						principal_entry.policy,
2727c478bd9Sstevel@tonic-gate 						&policy_entry);
2737c478bd9Sstevel@tonic-gate 			if (code != 0) {
2747c478bd9Sstevel@tonic-gate 				/*
2757c478bd9Sstevel@tonic-gate 				 * doesn't matter which error comes back,
2767c478bd9Sstevel@tonic-gate 				 * there's no nice recovery or need to
2777c478bd9Sstevel@tonic-gate 				 * differentiate to the user
2787c478bd9Sstevel@tonic-gate 				 */
2797c478bd9Sstevel@tonic-gate 				com_err(whoami, 0,
2807c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_CANT_GET_POLICY_INFO),
2817c478bd9Sstevel@tonic-gate 				princ_str);
2827c478bd9Sstevel@tonic-gate 				(void) kadm5_free_principal_ent(server_handle,
2837c478bd9Sstevel@tonic-gate 							&principal_entry);
2847c478bd9Sstevel@tonic-gate 				krb5_free_principal(context, princ);
2857c478bd9Sstevel@tonic-gate 				free(princ_str);
2867c478bd9Sstevel@tonic-gate 				free(princ_str);
2877c478bd9Sstevel@tonic-gate 				(void) kadm5_destroy(server_handle);
2887c478bd9Sstevel@tonic-gate 				return (MISC_EXIT_STATUS);
2897c478bd9Sstevel@tonic-gate 			}
2907c478bd9Sstevel@tonic-gate 			com_err(whoami, 0,
2917c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_POLICY_EXPLANATION),
2927c478bd9Sstevel@tonic-gate 				princ_str, principal_entry.policy,
2937c478bd9Sstevel@tonic-gate 				policy_entry.pw_min_length,
2947c478bd9Sstevel@tonic-gate 				policy_entry.pw_min_classes);
2957c478bd9Sstevel@tonic-gate 			if (code = kadm5_free_principal_ent(server_handle,
2967c478bd9Sstevel@tonic-gate 						    &principal_entry)) {
2977c478bd9Sstevel@tonic-gate 				(void) kadm5_free_policy_ent(server_handle,
2987c478bd9Sstevel@tonic-gate 							    &policy_entry);
2997c478bd9Sstevel@tonic-gate 				krb5_free_principal(context, princ);
3007c478bd9Sstevel@tonic-gate 				free(princ_str);
3017c478bd9Sstevel@tonic-gate 				com_err(whoami, code,
3027c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_WHILE_FREEING_PRINCIPAL));
3037c478bd9Sstevel@tonic-gate 				(void) kadm5_destroy(server_handle);
3047c478bd9Sstevel@tonic-gate 				return (MISC_EXIT_STATUS);
3057c478bd9Sstevel@tonic-gate 			}
3067c478bd9Sstevel@tonic-gate 			if (code = kadm5_free_policy_ent(server_handle,
3077c478bd9Sstevel@tonic-gate 							&policy_entry)) {
3087c478bd9Sstevel@tonic-gate 				krb5_free_principal(context, princ);
3097c478bd9Sstevel@tonic-gate 				free(princ_str);
3107c478bd9Sstevel@tonic-gate 				com_err(whoami, code,
3117c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_WHILE_FREEING_POLICY));
3127c478bd9Sstevel@tonic-gate 				(void) kadm5_destroy(server_handle);
3137c478bd9Sstevel@tonic-gate 				return (MISC_EXIT_STATUS);
3147c478bd9Sstevel@tonic-gate 			}
3157c478bd9Sstevel@tonic-gate 		} else {
3167c478bd9Sstevel@tonic-gate 			/*
3177c478bd9Sstevel@tonic-gate 			 * kpasswd *COULD* output something here to
3187c478bd9Sstevel@tonic-gate 			 * encourage the choice of good passwords,
3197c478bd9Sstevel@tonic-gate 			 * in the absence of an enforced policy.
3207c478bd9Sstevel@tonic-gate 			 */
3217c478bd9Sstevel@tonic-gate 			if (code = kadm5_free_principal_ent(server_handle,
3227c478bd9Sstevel@tonic-gate 						    &principal_entry)) {
3237c478bd9Sstevel@tonic-gate 				krb5_free_principal(context, princ);
3247c478bd9Sstevel@tonic-gate 				free(princ_str);
3257c478bd9Sstevel@tonic-gate 				com_err(whoami, code,
3267c478bd9Sstevel@tonic-gate 				string_text(KPW_STR_WHILE_FREEING_PRINCIPAL));
3277c478bd9Sstevel@tonic-gate 				(void) kadm5_destroy(server_handle);
3287c478bd9Sstevel@tonic-gate 				return (MISC_EXIT_STATUS);
3297c478bd9Sstevel@tonic-gate 			}
3307c478bd9Sstevel@tonic-gate 		}
3317c478bd9Sstevel@tonic-gate 	} /* if protocol == KRB5_CHGPWD_RPCSEC */
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate   pwsize = sizeof(password);
33456a424ccSmp153739   code = read_new_password(server_handle, password, &pwsize, msg_ret, sizeof (msg_ret), princ);
3357c478bd9Sstevel@tonic-gate   memset(password, 0, sizeof(password));
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate   if (code)
3387c478bd9Sstevel@tonic-gate     com_err(whoami, 0, msg_ret);
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate   krb5_free_principal(context, princ);
3417c478bd9Sstevel@tonic-gate   free(princ_str);
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate   (void) kadm5_destroy(server_handle);
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate   if (code == KRB5_LIBOS_CANTREADPWD)
3467c478bd9Sstevel@tonic-gate      return(5);
3477c478bd9Sstevel@tonic-gate   else if (code)
3487c478bd9Sstevel@tonic-gate      return(4);
3497c478bd9Sstevel@tonic-gate   else
3507c478bd9Sstevel@tonic-gate      return(0);
3517c478bd9Sstevel@tonic-gate }
352