1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 10*0Sstevel@tonic-gate * 11*0Sstevel@tonic-gate * Openvision retains the copyright to derivative works of 12*0Sstevel@tonic-gate * this source code. Do *NOT* create a derivative of this 13*0Sstevel@tonic-gate * source code before consulting with your legal department. 14*0Sstevel@tonic-gate * Do *NOT* integrate *ANY* of this source code into another 15*0Sstevel@tonic-gate * product before consulting with your legal department. 16*0Sstevel@tonic-gate * 17*0Sstevel@tonic-gate * For further information, read the top-level Openvision 18*0Sstevel@tonic-gate * copyright which is contained in the top-level MIT Kerberos 19*0Sstevel@tonic-gate * copyright. 20*0Sstevel@tonic-gate * 21*0Sstevel@tonic-gate * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate */ 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate /* 27*0Sstevel@tonic-gate * kadmin/ktutil/ktutil.c 28*0Sstevel@tonic-gate * 29*0Sstevel@tonic-gate * Copyright 1995, 1996 by the Massachusetts Institute of Technology. 30*0Sstevel@tonic-gate * All Rights Reserved. 31*0Sstevel@tonic-gate * 32*0Sstevel@tonic-gate * Export of this software from the United States of America may 33*0Sstevel@tonic-gate * require a specific license from the United States Government. 34*0Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 35*0Sstevel@tonic-gate * export to obtain such a license before exporting. 36*0Sstevel@tonic-gate * 37*0Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 38*0Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 39*0Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 40*0Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 41*0Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 42*0Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 43*0Sstevel@tonic-gate * to distribution of the software without specific, written prior 44*0Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 45*0Sstevel@tonic-gate * your software as modified software and not distribute it in such a 46*0Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 47*0Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 48*0Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 49*0Sstevel@tonic-gate * or implied warranty. 50*0Sstevel@tonic-gate * 51*0Sstevel@tonic-gate * SS user interface for ktutil. 52*0Sstevel@tonic-gate */ 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate #include "k5-int.h" 55*0Sstevel@tonic-gate #include "ktutil.h" 56*0Sstevel@tonic-gate #include <com_err.h> 57*0Sstevel@tonic-gate #include <ss/ss.h> 58*0Sstevel@tonic-gate #include <stdio.h> 59*0Sstevel@tonic-gate #ifdef HAVE_STDLIB_H 60*0Sstevel@tonic-gate #include <stdlib.h> 61*0Sstevel@tonic-gate #endif 62*0Sstevel@tonic-gate #include <libintl.h> 63*0Sstevel@tonic-gate #include <locale.h> 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate extern ss_request_table ktutil_cmds; 66*0Sstevel@tonic-gate krb5_context kcontext; 67*0Sstevel@tonic-gate krb5_kt_list ktlist = NULL; 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate int 70*0Sstevel@tonic-gate main(argc, argv) 71*0Sstevel@tonic-gate int argc; 72*0Sstevel@tonic-gate char *argv[]; 73*0Sstevel@tonic-gate { 74*0Sstevel@tonic-gate krb5_error_code retval; 75*0Sstevel@tonic-gate extern krb5_kt_ops krb5_ktf_writable_ops; 76*0Sstevel@tonic-gate int sci_idx; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 81*0Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 82*0Sstevel@tonic-gate #endif 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate retval = krb5_init_context(&kcontext); 87*0Sstevel@tonic-gate if (retval) { 88*0Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing krb5")); 89*0Sstevel@tonic-gate exit(1); 90*0Sstevel@tonic-gate } 91*0Sstevel@tonic-gate retval = krb5_kt_register(kcontext, &krb5_ktf_writable_ops); 92*0Sstevel@tonic-gate if (retval) { 93*0Sstevel@tonic-gate com_err(argv[0], retval, 94*0Sstevel@tonic-gate gettext("while registering writable key table functions")); 95*0Sstevel@tonic-gate exit(1); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate retval = ktutil_initialize_cmds_table (&ktutil_cmds); 98*0Sstevel@tonic-gate if (retval) { 99*0Sstevel@tonic-gate com_err(argv[0], retval, 100*0Sstevel@tonic-gate gettext("while localizing command description messages")); 101*0Sstevel@tonic-gate exit(1); 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate sci_idx = ss_create_invocation("ktutil", "5.0", (char *) NULL, 104*0Sstevel@tonic-gate &ktutil_cmds, &retval); 105*0Sstevel@tonic-gate if (retval) { 106*0Sstevel@tonic-gate ss_perror(sci_idx, retval, gettext("creating invocation")); 107*0Sstevel@tonic-gate exit(1); 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate ss_listen(sci_idx, &retval); 110*0Sstevel@tonic-gate ktutil_free_kt_list(kcontext, ktlist); 111*0Sstevel@tonic-gate exit(0); 112*0Sstevel@tonic-gate } 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate void 115*0Sstevel@tonic-gate ktutil_clear_list(argc, argv) 116*0Sstevel@tonic-gate int argc; 117*0Sstevel@tonic-gate char *argv[]; 118*0Sstevel@tonic-gate { 119*0Sstevel@tonic-gate krb5_error_code retval; 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate if (argc != 1) { 122*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: invalid arguments\n"), argv[0]); 123*0Sstevel@tonic-gate return; 124*0Sstevel@tonic-gate } 125*0Sstevel@tonic-gate retval = ktutil_free_kt_list(kcontext, ktlist); 126*0Sstevel@tonic-gate if (retval) 127*0Sstevel@tonic-gate com_err(argv[0], retval, gettext("while freeing ktlist")); 128*0Sstevel@tonic-gate ktlist = NULL; 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate void 132*0Sstevel@tonic-gate ktutil_read_v5(argc, argv) 133*0Sstevel@tonic-gate int argc; 134*0Sstevel@tonic-gate char *argv[]; 135*0Sstevel@tonic-gate { 136*0Sstevel@tonic-gate krb5_error_code retval; 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate if (argc != 2) { 139*0Sstevel@tonic-gate fprintf(stderr, 140*0Sstevel@tonic-gate gettext("%s: must specify keytab to read\n"), argv[0]); 141*0Sstevel@tonic-gate return; 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate retval = ktutil_read_keytab(kcontext, argv[1], &ktlist); 144*0Sstevel@tonic-gate if (retval) 145*0Sstevel@tonic-gate com_err(argv[0], retval, 146*0Sstevel@tonic-gate gettext("while reading keytab \"%s\""), argv[1]); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate void 150*0Sstevel@tonic-gate ktutil_read_v4(argc, argv) 151*0Sstevel@tonic-gate int argc; 152*0Sstevel@tonic-gate char *argv[]; 153*0Sstevel@tonic-gate { 154*0Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 155*0Sstevel@tonic-gate krb5_error_code retval; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate if (argc != 2) { 158*0Sstevel@tonic-gate fprintf(stderr, 159*0Sstevel@tonic-gate gettext("%s: must specify the srvtab to read\n"), argv[0]); 160*0Sstevel@tonic-gate return; 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate retval = ktutil_read_srvtab(kcontext, argv[1], &ktlist); 163*0Sstevel@tonic-gate if (retval) 164*0Sstevel@tonic-gate com_err(argv[0], retval, 165*0Sstevel@tonic-gate gettext("while reading srvtab \"%s\""), argv[1]); 166*0Sstevel@tonic-gate #else 167*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]); 168*0Sstevel@tonic-gate #endif 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate void 172*0Sstevel@tonic-gate ktutil_write_v5(argc, argv) 173*0Sstevel@tonic-gate int argc; 174*0Sstevel@tonic-gate char *argv[]; 175*0Sstevel@tonic-gate { 176*0Sstevel@tonic-gate krb5_error_code retval; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate if (argc != 2) { 179*0Sstevel@tonic-gate fprintf(stderr, 180*0Sstevel@tonic-gate gettext("%s: must specify keytab to write\n"), argv[0]); 181*0Sstevel@tonic-gate return; 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate retval = ktutil_write_keytab(kcontext, ktlist, argv[1]); 184*0Sstevel@tonic-gate if (retval) 185*0Sstevel@tonic-gate com_err(argv[0], retval, 186*0Sstevel@tonic-gate gettext("while writing keytab \"%s\""), argv[1]); 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate void 190*0Sstevel@tonic-gate ktutil_write_v4(argc, argv) 191*0Sstevel@tonic-gate int argc; 192*0Sstevel@tonic-gate char *argv[]; 193*0Sstevel@tonic-gate { 194*0Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 195*0Sstevel@tonic-gate krb5_error_code retval; 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate if (argc != 2) { 198*0Sstevel@tonic-gate fprintf(stderr, 199*0Sstevel@tonic-gate gettext("%s: must specify srvtab to write\n"), argv[0]); 200*0Sstevel@tonic-gate return; 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate retval = ktutil_write_srvtab(kcontext, ktlist, argv[1]); 203*0Sstevel@tonic-gate if (retval) 204*0Sstevel@tonic-gate com_err(argv[0], retval, 205*0Sstevel@tonic-gate gettext("while writing srvtab \"%s\""), argv[1]); 206*0Sstevel@tonic-gate #else 207*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]); 208*0Sstevel@tonic-gate #endif 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate void ktutil_add_entry(argc, argv) 212*0Sstevel@tonic-gate int argc; 213*0Sstevel@tonic-gate char *argv[]; 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate krb5_error_code retval; 216*0Sstevel@tonic-gate char *princ = NULL; 217*0Sstevel@tonic-gate char *enctype = NULL; 218*0Sstevel@tonic-gate krb5_kvno kvno = 0; 219*0Sstevel@tonic-gate int use_pass = 0, use_key = 0, i; 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate for (i = 1; i < argc; i++) { 222*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { 223*0Sstevel@tonic-gate princ = argv[++i]; 224*0Sstevel@tonic-gate continue; 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { 227*0Sstevel@tonic-gate kvno = (krb5_kvno) atoi(argv[++i]); 228*0Sstevel@tonic-gate continue; 229*0Sstevel@tonic-gate } 230*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 231*0Sstevel@tonic-gate enctype = argv[++i]; 232*0Sstevel@tonic-gate continue; 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) { 235*0Sstevel@tonic-gate use_pass++; 236*0Sstevel@tonic-gate continue; 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) { 239*0Sstevel@tonic-gate use_key++; 240*0Sstevel@tonic-gate continue; 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate } 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { 245*0Sstevel@tonic-gate fprintf(stderr, "%s: %s (-key | -password) -p principal " 246*0Sstevel@tonic-gate "-k kvno -e enctype\n", gettext("usage"), argv[0]); 247*0Sstevel@tonic-gate return; 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass); 251*0Sstevel@tonic-gate if (retval) 252*0Sstevel@tonic-gate com_err(argv[0], retval, gettext("while adding new entry")); 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate void 256*0Sstevel@tonic-gate ktutil_delete_entry(argc, argv) 257*0Sstevel@tonic-gate int argc; 258*0Sstevel@tonic-gate char *argv[]; 259*0Sstevel@tonic-gate { 260*0Sstevel@tonic-gate krb5_error_code retval; 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (argc != 2) { 263*0Sstevel@tonic-gate fprintf(stderr, 264*0Sstevel@tonic-gate gettext("%s: must specify entry to delete\n"), argv[0]); 265*0Sstevel@tonic-gate return; 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate retval = ktutil_delete(kcontext, &ktlist, atoi(argv[1])); 268*0Sstevel@tonic-gate if (retval) 269*0Sstevel@tonic-gate com_err(argv[0], retval, 270*0Sstevel@tonic-gate gettext("while deleting entry %d"), atoi(argv[1])); 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate void 274*0Sstevel@tonic-gate ktutil_list(argc, argv) 275*0Sstevel@tonic-gate int argc; 276*0Sstevel@tonic-gate char *argv[]; 277*0Sstevel@tonic-gate { 278*0Sstevel@tonic-gate krb5_error_code retval; 279*0Sstevel@tonic-gate krb5_kt_list lp; 280*0Sstevel@tonic-gate struct tm *stime; 281*0Sstevel@tonic-gate int show_time = 0, show_keys = 0, show_enctype = 0; 282*0Sstevel@tonic-gate int i, j; 283*0Sstevel@tonic-gate char *pname; 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate for (i = 1; i < argc; i++) { 286*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && strncmp(argv[i], "-t", 2) == 0) { 287*0Sstevel@tonic-gate show_time++; 288*0Sstevel@tonic-gate continue; 289*0Sstevel@tonic-gate } 290*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && strncmp(argv[i], "-k", 2) == 0) { 291*0Sstevel@tonic-gate show_keys++; 292*0Sstevel@tonic-gate continue; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 295*0Sstevel@tonic-gate show_enctype++; 296*0Sstevel@tonic-gate continue; 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate if ((strlen(argv[i]) == 2) && 299*0Sstevel@tonic-gate (strncmp(argv[i], "-e", 2) == 0)) { 300*0Sstevel@tonic-gate show_enctype = 1; 301*0Sstevel@tonic-gate continue; 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: illegal arguments\n"), argv[0]); 304*0Sstevel@tonic-gate return; 305*0Sstevel@tonic-gate } 306*0Sstevel@tonic-gate if (show_time) { 307*0Sstevel@tonic-gate printf(gettext("slot KVNO Timestamp Principal\n")); 308*0Sstevel@tonic-gate printf("---- ---- ----------------- ---------------------------------------------------\n"); 309*0Sstevel@tonic-gate } else { 310*0Sstevel@tonic-gate printf(gettext("slot KVNO Principal\n")); 311*0Sstevel@tonic-gate printf("---- ---- ---------------------------------------------------------------------\n"); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate for (i = 1, lp = ktlist; lp; i++, lp = lp->next) { 314*0Sstevel@tonic-gate retval = krb5_unparse_name(kcontext, 315*0Sstevel@tonic-gate lp->entry->principal, &pname); 316*0Sstevel@tonic-gate if (retval) { 317*0Sstevel@tonic-gate com_err(argv[0], retval, 318*0Sstevel@tonic-gate gettext("while unparsing principal name")); 319*0Sstevel@tonic-gate return; 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate printf("%4d %4d ", i, lp->entry->vno); 322*0Sstevel@tonic-gate if (show_time) { 323*0Sstevel@tonic-gate char fmtbuf[18]; 324*0Sstevel@tonic-gate char fill; 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate stime = localtime((time_t *) & lp->entry->timestamp); 327*0Sstevel@tonic-gate fill = ' '; 328*0Sstevel@tonic-gate if (!krb5_timestamp_to_sfstring( 329*0Sstevel@tonic-gate (krb5_timestamp) lp->entry->timestamp, 330*0Sstevel@tonic-gate fmtbuf, 331*0Sstevel@tonic-gate sizeof (fmtbuf), 332*0Sstevel@tonic-gate &fill)) 333*0Sstevel@tonic-gate printf("%s ", fmtbuf); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate printf("%40s", pname); 336*0Sstevel@tonic-gate if (show_enctype) { 337*0Sstevel@tonic-gate static char buf[256]; 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate if ((retval = krb5_enctype_to_string( 340*0Sstevel@tonic-gate lp->entry->key.enctype, buf, 256))) { 341*0Sstevel@tonic-gate com_err(argv[0], retval, 342*0Sstevel@tonic-gate gettext("While converting " 343*0Sstevel@tonic-gate "enctype to string")); 344*0Sstevel@tonic-gate return; 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate printf(" (%s) ", buf); 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate if (show_keys) { 349*0Sstevel@tonic-gate printf(" (0x"); 350*0Sstevel@tonic-gate for (j = 0; j < lp->entry->key.length; j++) 351*0Sstevel@tonic-gate printf("%02x", lp->entry->key.contents[j]); 352*0Sstevel@tonic-gate printf(")"); 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate printf("\n"); 355*0Sstevel@tonic-gate krb5_xfree(pname); 356*0Sstevel@tonic-gate } 357*0Sstevel@tonic-gate } 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate 368