17c478bd9Sstevel@tonic-gate /*
27c64d375Smp153739 * 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 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
97c478bd9Sstevel@tonic-gate *
1056a424ccSmp153739 * $Id: keytab.c,v 1.28 2004/05/31 12:39:16 epeisach Exp $
117c478bd9Sstevel@tonic-gate * $Source: /cvs/krbdev/krb5/src/kadmin/cli/keytab.c,v $
127c478bd9Sstevel@tonic-gate */
137c478bd9Sstevel@tonic-gate
147c478bd9Sstevel@tonic-gate /*
157c478bd9Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC.
167c478bd9Sstevel@tonic-gate *
177c478bd9Sstevel@tonic-gate * All rights reserved.
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may require
207c478bd9Sstevel@tonic-gate * a specific license from the United States Government. It is the
217c478bd9Sstevel@tonic-gate * responsibility of any person or organization contemplating export to
227c478bd9Sstevel@tonic-gate * obtain such a license before exporting.
237c478bd9Sstevel@tonic-gate *
247c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
257c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
267c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
277c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
287c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
297c478bd9Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining
307c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
317c478bd9Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of
327c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
337c478bd9Sstevel@tonic-gate * or implied warranty.
347c478bd9Sstevel@tonic-gate *
357c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
367c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
377c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
387c478bd9Sstevel@tonic-gate */
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(__CODECENTER__)
4156a424ccSmp153739 static char *rcsid = "$Header: /cvs/krbdev/krb5/src/kadmin/cli/keytab.c,v 1.28 2004/05/31 12:39:16 epeisach Exp $";
427c478bd9Sstevel@tonic-gate #endif
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate #include <stdio.h>
457c478bd9Sstevel@tonic-gate #include <stdlib.h>
467c478bd9Sstevel@tonic-gate #include <string.h>
477c478bd9Sstevel@tonic-gate #include <libintl.h>
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate #include <kadm5/admin.h>
5056a424ccSmp153739 #include <krb5/adm_proto.h>
5156a424ccSmp153739 #include "kadmin.h"
52*159d09a2SMark Phalan #include <krb5.h>
537c478bd9Sstevel@tonic-gate
5456a424ccSmp153739 static int add_principal(void *lhandle, char *keytab_str, krb5_keytab keytab,
5556a424ccSmp153739 krb5_boolean keepold,
567c478bd9Sstevel@tonic-gate int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
577c478bd9Sstevel@tonic-gate char *princ_str);
587c478bd9Sstevel@tonic-gate static int remove_principal(char *keytab_str, krb5_keytab keytab, char
597c478bd9Sstevel@tonic-gate *princ_str, char *kvno_str);
607c478bd9Sstevel@tonic-gate static char *etype_string(krb5_enctype enctype);
617c64d375Smp153739 static char *etype_istring(krb5_enctype enctype);
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate static int quiet;
647c478bd9Sstevel@tonic-gate
add_usage()6556a424ccSmp153739 static void add_usage()
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", gettext("Usage"),
687c478bd9Sstevel@tonic-gate "ktadd [-k[eytab] keytab] [-q] [-e keysaltlist] "
697c478bd9Sstevel@tonic-gate "[principal | -glob princ-exp] [...]\n");
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate
rem_usage()7256a424ccSmp153739 static void rem_usage()
737c478bd9Sstevel@tonic-gate {
747c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n",
757c478bd9Sstevel@tonic-gate gettext("Usage"),
767c478bd9Sstevel@tonic-gate "ktremove [-k[eytab] keytab] [-q] principal "
777c478bd9Sstevel@tonic-gate "[kvno|\"all\"|\"old\"]\n");
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate
process_keytab(krb5_context my_context,char ** keytab_str,krb5_keytab * keytab)8056a424ccSmp153739 static int process_keytab(krb5_context my_context, char **keytab_str,
817c478bd9Sstevel@tonic-gate krb5_keytab *keytab)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate int code;
847c478bd9Sstevel@tonic-gate char buf[BUFSIZ];
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate if (*keytab_str == NULL) {
8756a424ccSmp153739 if (code = krb5_kt_default(my_context, keytab)) {
887c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while opening default keytab"));
8956a424ccSmp153739 return 1;
907c478bd9Sstevel@tonic-gate }
9156a424ccSmp153739 if (code = krb5_kt_get_name(my_context, *keytab, buf, BUFSIZ)) {
927c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while retrieving keytab name"));
9356a424ccSmp153739 return 1;
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate if (!(*keytab_str = strdup(buf))) {
967c478bd9Sstevel@tonic-gate com_err(whoami, ENOMEM, gettext("while creating keytab name"));
9756a424ccSmp153739 return 1;
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate } else {
1007c478bd9Sstevel@tonic-gate if (strchr(*keytab_str, ':') != NULL) {
1017c478bd9Sstevel@tonic-gate *keytab_str = strdup(*keytab_str);
1027c478bd9Sstevel@tonic-gate if (*keytab_str == NULL) {
1037c478bd9Sstevel@tonic-gate com_err(whoami, ENOMEM,
1047c478bd9Sstevel@tonic-gate gettext("while creating keytab name"));
10556a424ccSmp153739 return 1;
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate } else {
1087c478bd9Sstevel@tonic-gate char *tmp = *keytab_str;
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate *keytab_str = (char *)
1117c478bd9Sstevel@tonic-gate malloc(strlen("WRFILE:")+strlen(tmp)+1);
1127c478bd9Sstevel@tonic-gate if (*keytab_str == NULL) {
1137c478bd9Sstevel@tonic-gate com_err(whoami, ENOMEM,
1147c478bd9Sstevel@tonic-gate gettext("while creating keytab name"));
11556a424ccSmp153739 return 1;
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate sprintf(*keytab_str, "WRFILE:%s", tmp);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate
12056a424ccSmp153739 code = krb5_kt_resolve(my_context, *keytab_str, keytab);
1217c478bd9Sstevel@tonic-gate if (code != 0) {
1227c478bd9Sstevel@tonic-gate com_err(whoami, code,
1237c478bd9Sstevel@tonic-gate gettext("while resolving keytab %s"), *keytab_str);
1247c478bd9Sstevel@tonic-gate free(keytab_str);
12556a424ccSmp153739 return 1;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate
12956a424ccSmp153739 return 0;
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate
kadmin_keytab_add(int argc,char ** argv)13356a424ccSmp153739 void kadmin_keytab_add(int argc, char **argv)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate krb5_keytab keytab = 0;
13656a424ccSmp153739 char *keytab_str = NULL, **princs;
1377c478bd9Sstevel@tonic-gate int code, num, i;
1387c478bd9Sstevel@tonic-gate krb5_error_code retval;
13956a424ccSmp153739 int n_ks_tuple = 0;
14056a424ccSmp153739 krb5_boolean keepold = FALSE;
1417c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ks_tuple = NULL;
1427c478bd9Sstevel@tonic-gate
14356a424ccSmp153739 argc--; argv++;
1447c478bd9Sstevel@tonic-gate quiet = 0;
1457c478bd9Sstevel@tonic-gate while (argc) {
1467c478bd9Sstevel@tonic-gate if (strncmp(*argv, "-k", 2) == 0) {
14756a424ccSmp153739 argc--; argv++;
1487c478bd9Sstevel@tonic-gate if (!argc || keytab_str) {
1497c478bd9Sstevel@tonic-gate add_usage();
1507c478bd9Sstevel@tonic-gate return;
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate keytab_str = *argv;
1537c478bd9Sstevel@tonic-gate } else if (strcmp(*argv, "-q") == 0) {
1547c478bd9Sstevel@tonic-gate quiet++;
1557c478bd9Sstevel@tonic-gate } else if (strcmp(*argv, "-e") == 0) {
1567c478bd9Sstevel@tonic-gate argc--;
1577c478bd9Sstevel@tonic-gate if (argc < 1) {
1587c478bd9Sstevel@tonic-gate add_usage();
1597c478bd9Sstevel@tonic-gate return;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate retval = krb5_string_to_keysalts(*++argv, ", \t", ":.-", 0,
1627c478bd9Sstevel@tonic-gate &ks_tuple, &n_ks_tuple);
1637c478bd9Sstevel@tonic-gate if (retval) {
1647c478bd9Sstevel@tonic-gate com_err("ktadd", retval,
1657c478bd9Sstevel@tonic-gate gettext("while parsing keysalts %s"),
1667c478bd9Sstevel@tonic-gate *argv);
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate return;
1697c478bd9Sstevel@tonic-gate }
1707c478bd9Sstevel@tonic-gate } else
1717c478bd9Sstevel@tonic-gate break;
17256a424ccSmp153739 argc--; argv++;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate if (argc == 0) {
1767c478bd9Sstevel@tonic-gate add_usage();
1777c478bd9Sstevel@tonic-gate return;
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate if (process_keytab(context, &keytab_str, &keytab))
1817c478bd9Sstevel@tonic-gate return;
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate while (*argv) {
1847c478bd9Sstevel@tonic-gate if (strcmp(*argv, "-glob") == 0) {
1857c478bd9Sstevel@tonic-gate if (*++argv == NULL) {
1867c478bd9Sstevel@tonic-gate add_usage();
1877c478bd9Sstevel@tonic-gate break;
1887c478bd9Sstevel@tonic-gate }
18956a424ccSmp153739
19056a424ccSmp153739 code = kadm5_get_principals(handle, *argv, &princs, &num);
19156a424ccSmp153739 if (code) {
1927c478bd9Sstevel@tonic-gate com_err(whoami, code,
1937c478bd9Sstevel@tonic-gate gettext("while expanding expression "
1947c478bd9Sstevel@tonic-gate "\"%s\"."),
1957c478bd9Sstevel@tonic-gate *argv);
1967c478bd9Sstevel@tonic-gate argv++;
1977c478bd9Sstevel@tonic-gate continue;
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate
2007c478bd9Sstevel@tonic-gate for (i = 0; i < num; i++)
2017c478bd9Sstevel@tonic-gate (void) add_principal(handle, keytab_str, keytab,
2027c478bd9Sstevel@tonic-gate keepold, n_ks_tuple, ks_tuple,
2037c478bd9Sstevel@tonic-gate princs[i]);
2047c478bd9Sstevel@tonic-gate kadm5_free_name_list(handle, princs, num);
2057c478bd9Sstevel@tonic-gate } else
2067c478bd9Sstevel@tonic-gate (void) add_principal(handle, keytab_str, keytab,
2077c478bd9Sstevel@tonic-gate keepold, n_ks_tuple, ks_tuple,
2087c478bd9Sstevel@tonic-gate *argv);
2097c478bd9Sstevel@tonic-gate argv++;
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate code = krb5_kt_close(context, keytab);
2137c478bd9Sstevel@tonic-gate if (code != 0)
2147c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while closing keytab"));
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate free(keytab_str);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
kadmin_keytab_remove(int argc,char ** argv)21956a424ccSmp153739 void kadmin_keytab_remove(int argc, char **argv)
2207c478bd9Sstevel@tonic-gate {
2217c478bd9Sstevel@tonic-gate krb5_keytab keytab = 0;
22256a424ccSmp153739 char *keytab_str = NULL;
2237c478bd9Sstevel@tonic-gate int code;
2247c478bd9Sstevel@tonic-gate
22556a424ccSmp153739 argc--; argv++;
2267c478bd9Sstevel@tonic-gate quiet = 0;
2277c478bd9Sstevel@tonic-gate while (argc) {
2287c478bd9Sstevel@tonic-gate if (strncmp(*argv, "-k", 2) == 0) {
22956a424ccSmp153739 argc--; argv++;
2307c478bd9Sstevel@tonic-gate if (!argc || keytab_str) {
2317c478bd9Sstevel@tonic-gate rem_usage();
2327c478bd9Sstevel@tonic-gate return;
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate keytab_str = *argv;
2357c478bd9Sstevel@tonic-gate } else if (strcmp(*argv, "-q") == 0) {
2367c478bd9Sstevel@tonic-gate quiet++;
2377c478bd9Sstevel@tonic-gate } else
2387c478bd9Sstevel@tonic-gate break;
23956a424ccSmp153739 argc--; argv++;
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate if (argc != 1 && argc != 2) {
2437c478bd9Sstevel@tonic-gate rem_usage();
2447c478bd9Sstevel@tonic-gate return;
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate if (process_keytab(context, &keytab_str, &keytab))
2477c478bd9Sstevel@tonic-gate return;
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate (void) remove_principal(keytab_str, keytab, argv[0], argv[1]);
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate code = krb5_kt_close(context, keytab);
2527c478bd9Sstevel@tonic-gate if (code != 0)
2537c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while closing keytab"));
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate free(keytab_str);
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate
25856a424ccSmp153739 static
add_principal(void * lhandle,char * keytab_str,krb5_keytab keytab,krb5_boolean keepold,int n_ks_tuple,krb5_key_salt_tuple * ks_tuple,char * princ_str)25956a424ccSmp153739 int add_principal(void *lhandle, char *keytab_str, krb5_keytab keytab,
26056a424ccSmp153739 krb5_boolean keepold, int n_ks_tuple,
2617c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *ks_tuple,
2627c478bd9Sstevel@tonic-gate char *princ_str)
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate kadm5_principal_ent_rec princ_rec;
2657c478bd9Sstevel@tonic-gate krb5_principal princ;
2667c478bd9Sstevel@tonic-gate krb5_keytab_entry new_entry;
2677c478bd9Sstevel@tonic-gate krb5_keyblock *keys;
26856a424ccSmp153739 int code, nkeys, i;
2697c478bd9Sstevel@tonic-gate int nktypes = 0;
2707c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *permitted_etypes = NULL;
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate (void) memset((char *)&princ_rec, 0, sizeof(princ_rec));
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate princ = NULL;
2757c478bd9Sstevel@tonic-gate keys = NULL;
2767c478bd9Sstevel@tonic-gate nkeys = 0;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate code = krb5_parse_name(context, princ_str, &princ);
2797c478bd9Sstevel@tonic-gate if (code != 0) {
2807c478bd9Sstevel@tonic-gate com_err(whoami, code,
2817c478bd9Sstevel@tonic-gate gettext("while parsing -add principal name %s"),
2827c478bd9Sstevel@tonic-gate princ_str);
2837c478bd9Sstevel@tonic-gate goto cleanup;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate if (ks_tuple == NULL) {
2877c478bd9Sstevel@tonic-gate krb5_enctype *ptr, *ktypes = NULL;
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate code = krb5_get_permitted_enctypes(context, &ktypes);
2907c478bd9Sstevel@tonic-gate if (!code && ktypes && *ktypes) {
2917c478bd9Sstevel@tonic-gate krb5_int32 salttype;
2927c478bd9Sstevel@tonic-gate /*
2937c478bd9Sstevel@tonic-gate * Count the results. This is stupid, the API above
2947c478bd9Sstevel@tonic-gate * should have included an output param to indicate
2957c478bd9Sstevel@tonic-gate * the size of the list that is returned.
2967c478bd9Sstevel@tonic-gate */
2977c478bd9Sstevel@tonic-gate for (ptr = ktypes; *ptr; ptr++) nktypes++;
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate /* Allocate a new key-salt tuple set */
3007c478bd9Sstevel@tonic-gate permitted_etypes = (krb5_key_salt_tuple *)malloc (
3017c478bd9Sstevel@tonic-gate sizeof (krb5_key_salt_tuple) * nktypes);
3027c478bd9Sstevel@tonic-gate if (permitted_etypes == NULL) {
3037c478bd9Sstevel@tonic-gate free(ktypes);
3047c478bd9Sstevel@tonic-gate return (ENOMEM);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate * Because the keysalt parameter doesn't matter for
3097c478bd9Sstevel@tonic-gate * keys stored in the keytab, use the default "normal"
3107c478bd9Sstevel@tonic-gate * salt for all keys
3117c478bd9Sstevel@tonic-gate */
3127c478bd9Sstevel@tonic-gate (void) krb5_string_to_salttype("normal", &salttype);
3137c478bd9Sstevel@tonic-gate for (i = 0; i < nktypes; i++) {
3147c478bd9Sstevel@tonic-gate permitted_etypes[i].ks_enctype = ktypes[i];
3157c478bd9Sstevel@tonic-gate permitted_etypes[i].ks_salttype = salttype;
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate free(ktypes);
3187c478bd9Sstevel@tonic-gate } else {
3197c478bd9Sstevel@tonic-gate if (ktypes)
3207c478bd9Sstevel@tonic-gate free(ktypes);
3217c478bd9Sstevel@tonic-gate goto cleanup;
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate } else {
3247c478bd9Sstevel@tonic-gate permitted_etypes = ks_tuple;
3257c478bd9Sstevel@tonic-gate nktypes = n_ks_tuple;
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate
32856a424ccSmp153739 code = kadm5_randkey_principal_3(lhandle, princ,
3297c478bd9Sstevel@tonic-gate keepold, nktypes, permitted_etypes,
3307c478bd9Sstevel@tonic-gate &keys, &nkeys);
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate #ifndef _KADMIN_LOCAL_
3337c478bd9Sstevel@tonic-gate /* this block is not needed in the kadmin.local client */
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate * If the above call failed, we may be talking to an older
3377c478bd9Sstevel@tonic-gate * admin server, so try the older API.
3387c478bd9Sstevel@tonic-gate */
3397c478bd9Sstevel@tonic-gate if (code == KADM5_RPC_ERROR) {
3407c478bd9Sstevel@tonic-gate code = kadm5_randkey_principal_old(handle, princ, &keys, &nkeys);
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate #endif /* !KADMIN_LOCAL */
3437c478bd9Sstevel@tonic-gate if (code != 0) {
3447c478bd9Sstevel@tonic-gate if (code == KADM5_UNK_PRINC) {
3457c478bd9Sstevel@tonic-gate fprintf(stderr,
3467c478bd9Sstevel@tonic-gate gettext("%s: Principal %s does not exist.\n"),
3477c478bd9Sstevel@tonic-gate whoami, princ_str);
3487c64d375Smp153739 /* Solaris Kerberos: Better error messages */
3497c64d375Smp153739 } else if (code == KRB5_BAD_ENCTYPE) {
3507c64d375Smp153739 int i, et;
3517c64d375Smp153739 fprintf(stderr, gettext("%s: Error from the remote system: "
3527c64d375Smp153739 "%s while changing %s's key\n"), whoami,
3537c64d375Smp153739 error_message(code), princ_str);
3547c64d375Smp153739 if (nktypes) {
3557c64d375Smp153739 et = permitted_etypes[0].ks_enctype;
3567c64d375Smp153739 fprintf(stderr, gettext("%s: Encryption types "
3577c64d375Smp153739 "requested: %s (%d)"), whoami,
3587c64d375Smp153739 etype_istring(et), et);
3597c64d375Smp153739
3607c64d375Smp153739 for (i = 1; i < nktypes; i++) {
3617c64d375Smp153739 et = permitted_etypes[i].ks_enctype;
3627c64d375Smp153739 fprintf(stderr, ", %s (%d)",
3637c64d375Smp153739 etype_istring(et), et);
3647c64d375Smp153739 }
3657c64d375Smp153739 fprintf(stderr, "\n");
3667c64d375Smp153739 }
3677c64d375Smp153739 } else {
3687c478bd9Sstevel@tonic-gate com_err(whoami, code,
3697c478bd9Sstevel@tonic-gate gettext("while changing %s's key"),
3707c478bd9Sstevel@tonic-gate princ_str);
3717c64d375Smp153739 }
3727c478bd9Sstevel@tonic-gate goto cleanup;
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate
37556a424ccSmp153739 code = kadm5_get_principal(lhandle, princ, &princ_rec,
3767c478bd9Sstevel@tonic-gate KADM5_PRINCIPAL_NORMAL_MASK);
3777c478bd9Sstevel@tonic-gate if (code != 0) {
3787c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while retrieving principal"));
3797c478bd9Sstevel@tonic-gate goto cleanup;
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate for (i = 0; i < nkeys; i++) {
3837c478bd9Sstevel@tonic-gate memset((char *) &new_entry, 0, sizeof(new_entry));
3847c478bd9Sstevel@tonic-gate new_entry.principal = princ;
3857c478bd9Sstevel@tonic-gate new_entry.key = keys[i];
3867c478bd9Sstevel@tonic-gate new_entry.vno = princ_rec.kvno;
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate code = krb5_kt_add_entry(context, keytab, &new_entry);
3897c478bd9Sstevel@tonic-gate if (code != 0) {
3907c478bd9Sstevel@tonic-gate com_err(whoami, code,
3917c478bd9Sstevel@tonic-gate gettext("while adding key to keytab"));
39256a424ccSmp153739 (void) kadm5_free_principal_ent(lhandle, &princ_rec);
3937c478bd9Sstevel@tonic-gate goto cleanup;
3947c478bd9Sstevel@tonic-gate }
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate if (!quiet)
3977c478bd9Sstevel@tonic-gate printf(gettext("Entry for principal %s with kvno %d, "
3987c478bd9Sstevel@tonic-gate "encryption type %s added to keytab %s.\n"),
3997c478bd9Sstevel@tonic-gate princ_str, princ_rec.kvno,
4007c478bd9Sstevel@tonic-gate etype_string(keys[i].enctype), keytab_str);
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate
40356a424ccSmp153739 code = kadm5_free_principal_ent(lhandle, &princ_rec);
4047c478bd9Sstevel@tonic-gate if (code != 0) {
4057c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while freeing principal entry"));
4067c478bd9Sstevel@tonic-gate goto cleanup;
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate cleanup:
4107c478bd9Sstevel@tonic-gate if (nkeys) {
4117c478bd9Sstevel@tonic-gate for (i = 0; i < nkeys; i++)
4127c478bd9Sstevel@tonic-gate krb5_free_keyblock_contents(context, &keys[i]);
4137c478bd9Sstevel@tonic-gate free(keys);
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate if (princ)
4167c478bd9Sstevel@tonic-gate krb5_free_principal(context, princ);
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate if (permitted_etypes != NULL && ks_tuple == NULL)
4197c478bd9Sstevel@tonic-gate free(permitted_etypes);
4207c478bd9Sstevel@tonic-gate
42156a424ccSmp153739 return code;
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate
remove_principal(char * keytab_str,krb5_keytab keytab,char * princ_str,char * kvno_str)42456a424ccSmp153739 int remove_principal(char *keytab_str, krb5_keytab keytab, char
4257c478bd9Sstevel@tonic-gate *princ_str, char *kvno_str)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate krb5_principal princ;
4287c478bd9Sstevel@tonic-gate krb5_keytab_entry entry;
4297c478bd9Sstevel@tonic-gate krb5_kt_cursor cursor;
43056a424ccSmp153739 enum { UNDEF, SPEC, HIGH, ALL, OLD } mode;
43156a424ccSmp153739 int code, did_something;
43256a424ccSmp153739 krb5_kvno kvno;
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate code = krb5_parse_name(context, princ_str, &princ);
4357c478bd9Sstevel@tonic-gate if (code != 0) {
4367c478bd9Sstevel@tonic-gate com_err(whoami, code,
4377c478bd9Sstevel@tonic-gate gettext("while parsing principal name %s"),
4387c478bd9Sstevel@tonic-gate princ_str);
43956a424ccSmp153739 return code;
4407c478bd9Sstevel@tonic-gate }
44156a424ccSmp153739
4427c478bd9Sstevel@tonic-gate mode = UNDEF;
4437c478bd9Sstevel@tonic-gate if (kvno_str == NULL) {
4447c478bd9Sstevel@tonic-gate mode = HIGH;
4457c478bd9Sstevel@tonic-gate kvno = 0;
4467c478bd9Sstevel@tonic-gate } else if (strcmp(kvno_str, "all") == 0) {
4477c478bd9Sstevel@tonic-gate mode = ALL;
4487c478bd9Sstevel@tonic-gate kvno = 0;
4497c478bd9Sstevel@tonic-gate } else if (strcmp(kvno_str, "old") == 0) {
4507c478bd9Sstevel@tonic-gate mode = OLD;
4517c478bd9Sstevel@tonic-gate kvno = 0;
4527c478bd9Sstevel@tonic-gate } else {
4537c478bd9Sstevel@tonic-gate mode = SPEC;
4547c478bd9Sstevel@tonic-gate kvno = atoi(kvno_str);
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate /* kvno is set to specified value for SPEC, 0 otherwise */
4587c478bd9Sstevel@tonic-gate code = krb5_kt_get_entry(context, keytab, princ, kvno, 0, &entry);
4597c478bd9Sstevel@tonic-gate if (code != 0) {
4607c478bd9Sstevel@tonic-gate if (code == ENOENT) {
4617c478bd9Sstevel@tonic-gate fprintf(stderr,
4627c478bd9Sstevel@tonic-gate gettext("%s: Keytab %s does not exist.\n"),
4637c478bd9Sstevel@tonic-gate whoami, keytab_str);
4647c478bd9Sstevel@tonic-gate } else if (code == KRB5_KT_NOTFOUND) {
4657c478bd9Sstevel@tonic-gate if (mode != SPEC)
4667c478bd9Sstevel@tonic-gate fprintf(stderr,
4677c478bd9Sstevel@tonic-gate gettext("%s: No entry for principal "
4687c478bd9Sstevel@tonic-gate "%s exists in keytab %s\n"),
4697c478bd9Sstevel@tonic-gate whoami, princ_str, keytab_str);
4707c478bd9Sstevel@tonic-gate else
4717c478bd9Sstevel@tonic-gate fprintf(stderr,
4727c478bd9Sstevel@tonic-gate gettext("%s: No entry for principal "
4737c478bd9Sstevel@tonic-gate "%s with kvno %d exists in "
4747c478bd9Sstevel@tonic-gate "keytab %s.\n"),
4757c478bd9Sstevel@tonic-gate whoami, princ_str, kvno, keytab_str);
4767c478bd9Sstevel@tonic-gate } else {
4777c478bd9Sstevel@tonic-gate com_err(whoami, code,
4787c478bd9Sstevel@tonic-gate gettext("while retrieving highest "
4797c478bd9Sstevel@tonic-gate "kvno from keytab"));
4807c478bd9Sstevel@tonic-gate }
48156a424ccSmp153739 return code;
4827c478bd9Sstevel@tonic-gate }
48356a424ccSmp153739
4847c478bd9Sstevel@tonic-gate /* set kvno to spec'ed value for SPEC, highest kvno otherwise */
4857c478bd9Sstevel@tonic-gate kvno = entry.vno;
4867c478bd9Sstevel@tonic-gate krb5_kt_free_entry(context, &entry);
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate code = krb5_kt_start_seq_get(context, keytab, &cursor);
4897c478bd9Sstevel@tonic-gate if (code != 0) {
4907c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while starting keytab scan"));
49156a424ccSmp153739 return code;
4927c478bd9Sstevel@tonic-gate }
49356a424ccSmp153739
4947c478bd9Sstevel@tonic-gate did_something = 0;
49556a424ccSmp153739 while ((code = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) {
4967c478bd9Sstevel@tonic-gate if (krb5_principal_compare(context, princ, entry.principal) &&
4977c478bd9Sstevel@tonic-gate ((mode == ALL) ||
4987c478bd9Sstevel@tonic-gate (mode == SPEC && entry.vno == kvno) ||
4997c478bd9Sstevel@tonic-gate (mode == OLD && entry.vno != kvno) ||
5007c478bd9Sstevel@tonic-gate (mode == HIGH && entry.vno == kvno))) {
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate /*
50356a424ccSmp153739 * Ack! What a kludge... the scanning functions lock
50456a424ccSmp153739 * the keytab so entries cannot be removed while they
50556a424ccSmp153739 * are operating.
5067c478bd9Sstevel@tonic-gate */
5077c478bd9Sstevel@tonic-gate code = krb5_kt_end_seq_get(context, keytab, &cursor);
5087c478bd9Sstevel@tonic-gate if (code != 0) {
5097c478bd9Sstevel@tonic-gate com_err(whoami, code,
5107c478bd9Sstevel@tonic-gate gettext("while temporarily "
5117c478bd9Sstevel@tonic-gate "ending keytab scan"));
51256a424ccSmp153739 return code;
5137c478bd9Sstevel@tonic-gate }
5147c478bd9Sstevel@tonic-gate code = krb5_kt_remove_entry(context, keytab, &entry);
5157c478bd9Sstevel@tonic-gate if (code != 0) {
5167c478bd9Sstevel@tonic-gate com_err(whoami, code,
5177c478bd9Sstevel@tonic-gate gettext("while deleting entry "
5187c478bd9Sstevel@tonic-gate "from keytab"));
51956a424ccSmp153739 return code;
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate code = krb5_kt_start_seq_get(context, keytab, &cursor);
5227c478bd9Sstevel@tonic-gate if (code != 0) {
5237c478bd9Sstevel@tonic-gate com_err(whoami, code,
5247c478bd9Sstevel@tonic-gate gettext("while restarting keytab scan"));
52556a424ccSmp153739 return code;
5267c478bd9Sstevel@tonic-gate }
52756a424ccSmp153739
5287c478bd9Sstevel@tonic-gate did_something++;
5297c478bd9Sstevel@tonic-gate if (!quiet)
5307c478bd9Sstevel@tonic-gate printf(gettext("Entry for principal "
5317c478bd9Sstevel@tonic-gate "%s with kvno %d "
5327c478bd9Sstevel@tonic-gate "removed from keytab %s.\n"),
5337c478bd9Sstevel@tonic-gate princ_str, entry.vno, keytab_str);
5347c478bd9Sstevel@tonic-gate }
5357c478bd9Sstevel@tonic-gate krb5_kt_free_entry(context, &entry);
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate if (code && code != KRB5_KT_END) {
5387c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while scanning keytab"));
53956a424ccSmp153739 return code;
5407c478bd9Sstevel@tonic-gate }
54156a424ccSmp153739 if ((code = krb5_kt_end_seq_get(context, keytab, &cursor))) {
5427c478bd9Sstevel@tonic-gate com_err(whoami, code, gettext("while ending keytab scan"));
54356a424ccSmp153739 return code;
5447c478bd9Sstevel@tonic-gate }
54556a424ccSmp153739
5467c478bd9Sstevel@tonic-gate /*
54756a424ccSmp153739 * If !did_someting then mode must be OLD or we would have
54856a424ccSmp153739 * already returned with an error. But check it anyway just to
54956a424ccSmp153739 * prevent unexpected error messages...
5507c478bd9Sstevel@tonic-gate */
5517c478bd9Sstevel@tonic-gate if (!did_something && mode == OLD) {
5527c478bd9Sstevel@tonic-gate fprintf(stderr,
5537c478bd9Sstevel@tonic-gate gettext("%s: There is only one entry for principal "
5547c478bd9Sstevel@tonic-gate "%s in keytab %s\n"),
5557c478bd9Sstevel@tonic-gate whoami, princ_str, keytab_str);
55656a424ccSmp153739 return 1;
5577c478bd9Sstevel@tonic-gate }
55856a424ccSmp153739
55956a424ccSmp153739 return 0;
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate /*
5637c478bd9Sstevel@tonic-gate * etype_string(enctype): return a string representation of the
5647c478bd9Sstevel@tonic-gate * encryption type. XXX copied from klist.c; this should be a
5657c478bd9Sstevel@tonic-gate * library function, or perhaps just #defines
5667c478bd9Sstevel@tonic-gate */
etype_string(enctype)56756a424ccSmp153739 static char *etype_string(enctype)
5687c478bd9Sstevel@tonic-gate krb5_enctype enctype;
5697c478bd9Sstevel@tonic-gate {
5707c478bd9Sstevel@tonic-gate static char buf[100];
5717c478bd9Sstevel@tonic-gate krb5_error_code ret;
5727c478bd9Sstevel@tonic-gate
57356a424ccSmp153739 if ((ret = krb5_enctype_to_string(enctype, buf, sizeof(buf))))
5747c478bd9Sstevel@tonic-gate sprintf(buf, "etype %d", enctype);
5757c478bd9Sstevel@tonic-gate
57656a424ccSmp153739 return buf;
5777c478bd9Sstevel@tonic-gate }
5787c64d375Smp153739
5797c64d375Smp153739 /* Solaris Kerberos */
etype_istring(krb5_enctype enctype)5807c64d375Smp153739 static char *etype_istring(krb5_enctype enctype) {
5817c64d375Smp153739 static char buf[100];
5827c64d375Smp153739 krb5_error_code ret;
5837c64d375Smp153739
5847c64d375Smp153739 if ((ret = krb5_enctype_to_istring(enctype, buf, sizeof(buf))))
5857c64d375Smp153739 sprintf(buf, "unknown", enctype);
5867c64d375Smp153739
5877c64d375Smp153739 return (buf);
5887c64d375Smp153739 }
5897c64d375Smp153739
590