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 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 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 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 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 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 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 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 */ 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 */ 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