xref: /onnv-gate/usr/src/lib/krb5/kadm5/chpass_util.c (revision 7934:6aeeafc994de)
10Sstevel@tonic-gate /*
2*7934SMark.Phalan@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /*
80Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
110Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
120Sstevel@tonic-gate  *	source code before consulting with your legal department.
130Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
140Sstevel@tonic-gate  *	product before consulting with your legal department.
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  *	For further information, read the top-level Openvision
170Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
180Sstevel@tonic-gate  *	copyright.
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
210Sstevel@tonic-gate  *
220Sstevel@tonic-gate  */
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
270Sstevel@tonic-gate  */
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <stdio.h>
312881Smp153739 #ifdef HAVE_MEMORY_H
320Sstevel@tonic-gate #include <memory.h>
332881Smp153739 #endif
340Sstevel@tonic-gate #include <time.h>
350Sstevel@tonic-gate #include <locale.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include <kadm5/admin.h>
380Sstevel@tonic-gate #include "admin_internal.h"
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <krb5.h>
41*7934SMark.Phalan@Sun.COM #include <strings.h>
420Sstevel@tonic-gate 
430Sstevel@tonic-gate #define string_text error_message
440Sstevel@tonic-gate 
450Sstevel@tonic-gate const char *chpw_error_message(kadm5_ret_t code);
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * Function: kadm5_chpass_principal_util
490Sstevel@tonic-gate  *
502881Smp153739  * Purpose: Wrapper around chpass_principal. We can read new pw, change pw and return useful messages
510Sstevel@tonic-gate  *
520Sstevel@tonic-gate  * Arguments:
530Sstevel@tonic-gate  *
540Sstevel@tonic-gate  *      princ          (input) a krb5b_principal structure for the
550Sstevel@tonic-gate  *                     principal whose password we should change.
560Sstevel@tonic-gate  *
570Sstevel@tonic-gate  *      new_password   (input) NULL or a null terminated string with the
580Sstevel@tonic-gate  *                     the principal's desired new password.  If new_password
590Sstevel@tonic-gate  *                     is NULL then this routine will read a new password.
600Sstevel@tonic-gate  *
610Sstevel@tonic-gate  *	pw_ret		(output) if non-NULL, points to a static buffer
620Sstevel@tonic-gate  *			containing the new password (if password is prompted
630Sstevel@tonic-gate  *			internally), or to the new_password argument (if
640Sstevel@tonic-gate  *			that is non-NULL).  If the former, then the buffer
650Sstevel@tonic-gate  *			is only valid until the next call to the function,
660Sstevel@tonic-gate  *			and the caller should be sure to zero it when
670Sstevel@tonic-gate  *			it is no longer needed.
680Sstevel@tonic-gate  *
690Sstevel@tonic-gate  *      msg_ret         (output) a useful message is copied here.
700Sstevel@tonic-gate  *
710Sstevel@tonic-gate  *      <return value>  exit status of 0 for success, else the com err code
720Sstevel@tonic-gate  *                      for the last significant routine called.
730Sstevel@tonic-gate  *
740Sstevel@tonic-gate  * Requires:
750Sstevel@tonic-gate  *
760Sstevel@tonic-gate  *      A msg_ret should point to a buffer large enough for the messasge.
770Sstevel@tonic-gate  *
780Sstevel@tonic-gate  * Effects:
790Sstevel@tonic-gate  *
800Sstevel@tonic-gate  * Modifies:
810Sstevel@tonic-gate  *
820Sstevel@tonic-gate  *
830Sstevel@tonic-gate  */
840Sstevel@tonic-gate 
_kadm5_chpass_principal_util(void * server_handle,void * lhandle,krb5_principal princ,char * new_pw,char ** ret_pw,char * msg_ret,unsigned int msg_len)850Sstevel@tonic-gate kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
860Sstevel@tonic-gate 					 void *lhandle,
870Sstevel@tonic-gate 					 krb5_principal princ,
880Sstevel@tonic-gate 					 char *new_pw,
890Sstevel@tonic-gate 					 char **ret_pw,
900Sstevel@tonic-gate 					 char *msg_ret,
912881Smp153739 					 unsigned int msg_len)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate   int code, code2;
940Sstevel@tonic-gate   unsigned int pwsize;
950Sstevel@tonic-gate   static char buffer[255];
960Sstevel@tonic-gate   char *new_password;
970Sstevel@tonic-gate   kadm5_principal_ent_rec princ_ent;
980Sstevel@tonic-gate   kadm5_policy_ent_rec policy_ent;
992881Smp153739   krb5_chgpwd_prot passwd_protocol;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate   _KADM5_CHECK_HANDLE(server_handle);
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate   if (ret_pw)
1040Sstevel@tonic-gate     *ret_pw = NULL;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate   if (new_pw != NULL) {
1070Sstevel@tonic-gate     new_password = new_pw;
1080Sstevel@tonic-gate   } else { /* read the password */
1090Sstevel@tonic-gate     krb5_context context;
1100Sstevel@tonic-gate 
111*7934SMark.Phalan@Sun.COM     if ((code = (int) kadm5_init_krb5_context(&context)) == 0) {
1120Sstevel@tonic-gate       pwsize = sizeof(buffer);
1132881Smp153739       code = krb5_read_password(context, KADM5_PW_FIRST_PROMPT,
1140Sstevel@tonic-gate 				KADM5_PW_SECOND_PROMPT,
1150Sstevel@tonic-gate 				buffer, &pwsize);
1160Sstevel@tonic-gate       krb5_free_context(context);
1170Sstevel@tonic-gate     }
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate     if (code == 0)
1200Sstevel@tonic-gate       new_password = buffer;
1210Sstevel@tonic-gate     else {
1220Sstevel@tonic-gate #ifdef ZEROPASSWD
1230Sstevel@tonic-gate       memset(buffer, 0, sizeof(buffer));
1240Sstevel@tonic-gate #endif
1250Sstevel@tonic-gate       if (code == KRB5_LIBOS_BADPWDMATCH) {
126*7934SMark.Phalan@Sun.COM 	(void) strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
1270Sstevel@tonic-gate 		msg_len - 1);
1280Sstevel@tonic-gate 	msg_ret[msg_len - 1] = '\0';
1290Sstevel@tonic-gate 	return(code);
1300Sstevel@tonic-gate       } else {
131*7934SMark.Phalan@Sun.COM         (void) strncpy(msg_ret, error_message(code), msg_len - 1);
132*7934SMark.Phalan@Sun.COM         (void) strncat(msg_ret, " ", msg_len - 1);
133*7934SMark.Phalan@Sun.COM         (void) strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
1340Sstevel@tonic-gate 		msg_len - 1);
135*7934SMark.Phalan@Sun.COM         (void) strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
1360Sstevel@tonic-gate 		msg_len - 1);
1370Sstevel@tonic-gate 	msg_ret[msg_len - 1] = '\0';
1380Sstevel@tonic-gate 	return(code);
1390Sstevel@tonic-gate       }
1400Sstevel@tonic-gate     }
1410Sstevel@tonic-gate     if (pwsize == 0) {
1420Sstevel@tonic-gate #ifdef ZEROPASSWD
1430Sstevel@tonic-gate       memset(buffer, 0, sizeof(buffer));
1440Sstevel@tonic-gate #endif
1450Sstevel@tonic-gate       strncpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ), msg_len - 1);
1460Sstevel@tonic-gate       msg_ret[msg_len - 1] = '\0';
1470Sstevel@tonic-gate       return(KRB5_LIBOS_CANTREADPWD); /* could do better */
1480Sstevel@tonic-gate     }
1490Sstevel@tonic-gate   }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate   if (ret_pw)
1520Sstevel@tonic-gate     *ret_pw = new_password;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	passwd_protocol = _kadm5_get_kpasswd_protocol(server_handle);
1550Sstevel@tonic-gate 	if (passwd_protocol == KRB5_CHGPWD_CHANGEPW_V2) {
1560Sstevel@tonic-gate 		kadm5_ret_t srvr_rsp_code;
1570Sstevel@tonic-gate 		krb5_data   srvr_msg;
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 		srvr_msg.length = 0;
1600Sstevel@tonic-gate 		srvr_msg.data = NULL;
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 		code = kadm5_chpass_principal_v2(server_handle, princ,
1630Sstevel@tonic-gate 						new_password,
1640Sstevel@tonic-gate 						&srvr_rsp_code,
1650Sstevel@tonic-gate 						&srvr_msg);
1660Sstevel@tonic-gate 		if (srvr_rsp_code) {
1670Sstevel@tonic-gate 			sprintf(msg_ret, "%s%s%.*s\n",
1680Sstevel@tonic-gate 				chpw_error_message(srvr_rsp_code),
1690Sstevel@tonic-gate 				srvr_msg.length? ": " : "",
1700Sstevel@tonic-gate 				srvr_msg.length,
1710Sstevel@tonic-gate 				srvr_msg.data ? srvr_msg.data : "");
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate 			return (srvr_rsp_code);
1740Sstevel@tonic-gate 		}
1750Sstevel@tonic-gate 		return (code);
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate 	} else if (passwd_protocol == KRB5_CHGPWD_RPCSEC) {
1780Sstevel@tonic-gate 		code = kadm5_chpass_principal(server_handle, princ,
1790Sstevel@tonic-gate 					    new_password);
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate #ifdef ZEROPASSWD
1820Sstevel@tonic-gate   if (!ret_pw)
1832881Smp153739     memset(buffer, 0, sizeof(buffer)); /* in case we read a new password */
1840Sstevel@tonic-gate #endif
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate   if (code == KADM5_OK) {
1870Sstevel@tonic-gate     strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED), msg_len - 1);
1880Sstevel@tonic-gate     msg_ret[msg_len - 1] = '\0';
1890Sstevel@tonic-gate     return(0);
1900Sstevel@tonic-gate   }
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate   if ((code != KADM5_PASS_Q_TOOSHORT) &&
1932881Smp153739       (code != KADM5_PASS_REUSE) &&(code != KADM5_PASS_Q_CLASS) &&
1942881Smp153739       (code != KADM5_PASS_Q_DICT) && (code != KADM5_PASS_TOOSOON)) {
1950Sstevel@tonic-gate     /* Can't get more info for other errors */
1960Sstevel@tonic-gate     sprintf(buffer, "%s %s", error_message(code),
1970Sstevel@tonic-gate 	    string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
1982881Smp153739     sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
1990Sstevel@tonic-gate 	    buffer);
2000Sstevel@tonic-gate     return(code);
2010Sstevel@tonic-gate   }
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate   /* Ok, we have a password quality error. Return a good message */
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate   if (code == KADM5_PASS_REUSE) {
2060Sstevel@tonic-gate     strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE), msg_len - 1);
2070Sstevel@tonic-gate     msg_ret[msg_len - 1] = '\0';
2080Sstevel@tonic-gate     return(code);
2090Sstevel@tonic-gate   }
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate   if (code == KADM5_PASS_Q_DICT) {
2120Sstevel@tonic-gate     strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY),
2130Sstevel@tonic-gate 	    msg_len - 1);
2140Sstevel@tonic-gate     msg_ret[msg_len - 1] = '\0';
2150Sstevel@tonic-gate     return(code);
2160Sstevel@tonic-gate   }
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate   /* Look up policy for the remaining messages */
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate   code2 = kadm5_get_principal (lhandle, princ, &princ_ent,
2210Sstevel@tonic-gate 			       KADM5_PRINCIPAL_NORMAL_MASK);
2220Sstevel@tonic-gate   if (code2 != 0) {
2230Sstevel@tonic-gate     strncpy(msg_ret, error_message(code2), msg_len - 1);
2240Sstevel@tonic-gate     strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
2250Sstevel@tonic-gate     strncat(msg_ret, string_text(CHPASS_UTIL_GET_PRINC_INFO), msg_len - 1 - strlen(msg_ret));
2260Sstevel@tonic-gate     strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
2270Sstevel@tonic-gate     strncat(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
2280Sstevel@tonic-gate     strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
2290Sstevel@tonic-gate     strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
2300Sstevel@tonic-gate 	    msg_len - 1 - strlen(msg_ret));
2310Sstevel@tonic-gate     strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
2320Sstevel@tonic-gate     strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
2330Sstevel@tonic-gate 	    msg_len - 1 - strlen(msg_ret));
2340Sstevel@tonic-gate     strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret));
2350Sstevel@tonic-gate     msg_ret[msg_len - 1] = '\0';
2360Sstevel@tonic-gate     return(code);
2370Sstevel@tonic-gate   }
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate   if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) {
2400Sstevel@tonic-gate     strncpy(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret));
2410Sstevel@tonic-gate     strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret));
2420Sstevel@tonic-gate     strncpy(msg_ret, string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR),
2430Sstevel@tonic-gate 	    msg_len - 1 - strlen(msg_ret));
2440Sstevel@tonic-gate     strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret));
2450Sstevel@tonic-gate     strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
2460Sstevel@tonic-gate 	    msg_len - 1 - strlen(msg_ret));
2470Sstevel@tonic-gate     msg_ret[msg_len - 1] = '\0';
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
2500Sstevel@tonic-gate     return(code);
2510Sstevel@tonic-gate   }
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate   code2 = kadm5_get_policy(lhandle, princ_ent.policy,
2540Sstevel@tonic-gate 			   &policy_ent);
2550Sstevel@tonic-gate   if (code2 != 0) {
2562881Smp153739     sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2),
2570Sstevel@tonic-gate 	    string_text(CHPASS_UTIL_GET_POLICY_INFO),
2580Sstevel@tonic-gate 	    error_message(code),
2590Sstevel@tonic-gate 	    string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
2600Sstevel@tonic-gate 	    string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
2610Sstevel@tonic-gate     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
2620Sstevel@tonic-gate     return(code);
2630Sstevel@tonic-gate   }
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate   if (code == KADM5_PASS_Q_TOOSHORT) {
2662881Smp153739     sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SHORT),
2670Sstevel@tonic-gate 	    policy_ent.pw_min_length);
2680Sstevel@tonic-gate     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
2690Sstevel@tonic-gate     (void) kadm5_free_policy_ent(lhandle, &policy_ent);
2700Sstevel@tonic-gate     return(code);
2710Sstevel@tonic-gate   }
2720Sstevel@tonic-gate 
2732881Smp153739 
2740Sstevel@tonic-gate   if (code == KADM5_PASS_Q_CLASS) {
2752881Smp153739     sprintf(msg_ret, string_text(CHPASS_UTIL_TOO_FEW_CLASSES),
2760Sstevel@tonic-gate 	    policy_ent.pw_min_classes);
2770Sstevel@tonic-gate     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
2780Sstevel@tonic-gate     (void) kadm5_free_policy_ent(lhandle, &policy_ent);
2790Sstevel@tonic-gate     return(code);
2800Sstevel@tonic-gate   }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate   if (code == KADM5_PASS_TOOSOON) {
2830Sstevel@tonic-gate     time_t until;
2840Sstevel@tonic-gate     char *time_string, *ptr;
2850Sstevel@tonic-gate 
2862881Smp153739     until = princ_ent.last_pwd_change + policy_ent.pw_min_life;
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate     time_string = ctime(&until);
2892881Smp153739     if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
2900Sstevel@tonic-gate       *ptr = '\0';
2910Sstevel@tonic-gate 
2922881Smp153739     sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SOON),
2930Sstevel@tonic-gate 	    time_string);
2940Sstevel@tonic-gate     (void) kadm5_free_principal_ent(lhandle, &princ_ent);
2950Sstevel@tonic-gate     (void) kadm5_free_policy_ent(lhandle, &policy_ent);
2960Sstevel@tonic-gate     return(code);
297*7934SMark.Phalan@Sun.COM   } else {
2982881Smp153739 
2990Sstevel@tonic-gate   /* We should never get here, but just in case ... */
3000Sstevel@tonic-gate   sprintf(buffer, "%s %s", error_message(code),
3010Sstevel@tonic-gate 	  string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
3022881Smp153739   sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
3030Sstevel@tonic-gate 	  buffer);
3040Sstevel@tonic-gate   (void) kadm5_free_principal_ent(lhandle, &princ_ent);
3050Sstevel@tonic-gate   (void) kadm5_free_policy_ent(lhandle, &policy_ent);
3060Sstevel@tonic-gate   return(code);
3070Sstevel@tonic-gate 		}
3080Sstevel@tonic-gate 	} else {
3090Sstevel@tonic-gate 		sprintf(msg_ret, "%s\n%s\n",
3100Sstevel@tonic-gate 			string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
3110Sstevel@tonic-gate 			"Password protocol in krb5.conf is not supported\n");
3120Sstevel@tonic-gate 		return (-1);
3130Sstevel@tonic-gate 	}
3140Sstevel@tonic-gate }
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate /*
3170Sstevel@tonic-gate  * krb5_chpw_result_code_string
3180Sstevel@tonic-gate  *
3190Sstevel@tonic-gate  * convert the return code received from the password server
3200Sstevel@tonic-gate  * to a human-readable string.
3210Sstevel@tonic-gate  */
3220Sstevel@tonic-gate const char *
chpw_error_message(kadm5_ret_t result_code)3230Sstevel@tonic-gate chpw_error_message(kadm5_ret_t result_code)
3240Sstevel@tonic-gate {
3250Sstevel@tonic-gate 	switch (result_code) {
3260Sstevel@tonic-gate 	case KRB5_KPASSWD_MALFORMED:
3270Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Malformed request error"));
3280Sstevel@tonic-gate 	case KRB5_KPASSWD_HARDERROR:
3290Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Server error"));
3300Sstevel@tonic-gate 	case KRB5_KPASSWD_AUTHERROR:
3310Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Authentication error"));
3320Sstevel@tonic-gate 	case KRB5_KPASSWD_SOFTERROR:
3330Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Password change rejected"));
3340Sstevel@tonic-gate 	case KRB5_KPASSWD_ACCESSDENIED:
3350Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN,
3360Sstevel@tonic-gate 				"Not authorized to change password"));
3370Sstevel@tonic-gate 	case KRB5_KPASSWD_BAD_VERSION:
3380Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Protocol version unsupported"));
3390Sstevel@tonic-gate 	case KRB5_KPASSWD_INITIAL_FLAG_NEEDED:
3400Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN,
3410Sstevel@tonic-gate 				"initial flag required in changepw request"));
3420Sstevel@tonic-gate 	case KRB5_KPASSWD_POLICY_REJECT:
3430Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "new password fails policy"));
3440Sstevel@tonic-gate 	case KRB5_KPASSWD_BAD_PRINCIPAL:
3450Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN,
3460Sstevel@tonic-gate 		    "target principal does not exist for "
3470Sstevel@tonic-gate 		    "changepw request"));
3480Sstevel@tonic-gate 	case KRB5_KPASSWD_ETYPE_NOSUPP:
3490Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN,
3500Sstevel@tonic-gate 		    "changepw request key sequence has an "
3510Sstevel@tonic-gate 		    "unsupported Etype"));
3520Sstevel@tonic-gate 	default:
3530Sstevel@tonic-gate 		return (dgettext(TEXT_DOMAIN, "Password change failed"));
3540Sstevel@tonic-gate 	}
3550Sstevel@tonic-gate }
356