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 *)¶ms, 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 ¶ms, 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