1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* kadmin/ktutil/ktutil.c - SS user interface for ktutil */ 3 /* 4 * Copyright 1995, 1996, 2008 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include "k5-int.h" 28 #include "ktutil.h" 29 #include <com_err.h> 30 #include <locale.h> 31 #include "adm_proto.h" 32 #include <ss/ss.h> 33 #include <stdio.h> 34 #ifdef HAVE_STDLIB_H 35 #include <stdlib.h> 36 #endif 37 38 extern ss_request_table ktutil_cmds; 39 krb5_context kcontext; 40 krb5_kt_list ktlist = NULL; 41 42 int 43 main(int argc, char *argv[]) 44 { 45 krb5_error_code retval; 46 int sci_idx; 47 48 setlocale(LC_ALL, ""); 49 retval = krb5_init_context(&kcontext); 50 if (retval) { 51 com_err(argv[0], retval, _("while initializing krb5")); 52 exit(1); 53 } 54 sci_idx = ss_create_invocation("ktutil", "5.0", (char *)NULL, 55 &ktutil_cmds, &retval); 56 if (retval) { 57 ss_perror(sci_idx, retval, _("creating invocation")); 58 exit(1); 59 } 60 retval = ss_listen(sci_idx); 61 ktutil_free_kt_list(kcontext, ktlist); 62 exit(0); 63 } 64 65 void 66 ktutil_clear_list(int argc, char *argv[], int sci_idx, void *info_ptr) 67 { 68 krb5_error_code retval; 69 70 if (argc != 1) { 71 fprintf(stderr, _("%s: invalid arguments\n"), argv[0]); 72 return; 73 } 74 retval = ktutil_free_kt_list(kcontext, ktlist); 75 if (retval) 76 com_err(argv[0], retval, _("while freeing ktlist")); 77 ktlist = NULL; 78 } 79 80 void 81 ktutil_read_v5(int argc, char *argv[], int sci_idx, void *info_ptr) 82 { 83 krb5_error_code retval; 84 85 if (argc != 2) { 86 fprintf(stderr, _("%s: must specify keytab to read\n"), argv[0]); 87 return; 88 } 89 retval = ktutil_read_keytab(kcontext, argv[1], &ktlist); 90 if (retval) 91 com_err(argv[0], retval, _("while reading keytab \"%s\""), argv[1]); 92 } 93 94 void 95 ktutil_read_v4(int argc, char *argv[], int sci_idx, void *info_ptr) 96 { 97 fprintf(stderr, _("%s: reading srvtabs is no longer supported\n"), 98 argv[0]); 99 } 100 101 void 102 ktutil_write_v5(int argc, char *argv[], int sci_idx, void *info_ptr) 103 { 104 krb5_error_code retval; 105 106 if (argc != 2) { 107 fprintf(stderr, _("%s: must specify keytab to write\n"), argv[0]); 108 return; 109 } 110 retval = ktutil_write_keytab(kcontext, ktlist, argv[1]); 111 if (retval) 112 com_err(argv[0], retval, _("while writing keytab \"%s\""), argv[1]); 113 } 114 115 void 116 ktutil_write_v4(int argc, char *argv[], int sci_idx, void *info_ptr) 117 { 118 fprintf(stderr, _("%s: writing srvtabs is no longer supported\n"), 119 argv[0]); 120 } 121 122 void 123 ktutil_add_entry(int argc, char *argv[], int sci_idx, void *info_ptr) 124 { 125 krb5_error_code retval; 126 char *princ = NULL; 127 char *enctype = NULL; 128 krb5_kvno kvno = 0; 129 int use_pass = 0, use_key = 0, use_kvno = 0, fetch = 0, i; 130 char *salt = NULL; 131 132 for (i = 1; i < argc; i++) { 133 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { 134 princ = argv[++i]; 135 continue; 136 } 137 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { 138 kvno = (krb5_kvno) atoi(argv[++i]); 139 use_kvno++; 140 continue; 141 } 142 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 143 enctype = argv[++i]; 144 continue; 145 } 146 if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) { 147 use_pass++; 148 continue; 149 } 150 if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) { 151 use_key++; 152 continue; 153 } 154 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-s", 2)) { 155 salt = argv[++i]; 156 continue; 157 } 158 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-f", 2)) 159 fetch++; 160 } 161 162 if (princ == NULL || use_pass + use_key != 1 || !use_kvno || 163 (fetch && salt != NULL)) { 164 fprintf(stderr, _("usage: %s (-key | -password) -p principal " 165 "-k kvno [-e enctype] [-f|-s salt]\n"), argv[0]); 166 return; 167 } 168 if (!fetch && enctype == NULL) { 169 fprintf(stderr, _("enctype must be specified if not using -f\n")); 170 return; 171 } 172 173 retval = ktutil_add(kcontext, &ktlist, princ, fetch, kvno, enctype, 174 use_pass, salt); 175 if (retval) 176 com_err(argv[0], retval, _("while adding new entry")); 177 } 178 179 void 180 ktutil_delete_entry(int argc, char *argv[], int sci_idx, void *info_ptr) 181 { 182 krb5_error_code retval; 183 184 if (argc != 2) { 185 fprintf(stderr, _("%s: must specify entry to delete\n"), argv[0]); 186 return; 187 } 188 retval = ktutil_delete(kcontext, &ktlist, atoi(argv[1])); 189 if (retval) 190 com_err(argv[0], retval, _("while deleting entry %d"), atoi(argv[1])); 191 } 192 193 void 194 ktutil_list(int argc, char *argv[], int sci_idx, void *info_ptr) 195 { 196 krb5_error_code retval; 197 krb5_kt_list lp; 198 int show_time = 0, show_keys = 0, show_enctype = 0; 199 int i; 200 unsigned int j; 201 char *pname; 202 203 for (i = 1; i < argc; i++) { 204 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-t", 2)) { 205 show_time++; 206 continue; 207 } 208 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { 209 show_keys++; 210 continue; 211 } 212 if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { 213 show_enctype++; 214 continue; 215 } 216 217 fprintf(stderr, _("%s: usage: %s [-t] [-k] [-e]\n"), argv[0], argv[0]); 218 return; 219 } 220 /* XXX Translating would disturb table alignment; skip for now. */ 221 if (show_time) { 222 printf("slot KVNO Timestamp Principal\n"); 223 printf("---- ---- ----------------- ---------------------------------------------------\n"); 224 } else { 225 printf("slot KVNO Principal\n"); 226 printf("---- ---- ---------------------------------------------------------------------\n"); 227 } 228 for (i = 1, lp = ktlist; lp; i++, lp = lp->next) { 229 retval = krb5_unparse_name(kcontext, lp->entry->principal, &pname); 230 if (retval) { 231 com_err(argv[0], retval, "while unparsing principal name"); 232 return; 233 } 234 printf("%4d %4d ", i, lp->entry->vno); 235 if (show_time) { 236 char fmtbuf[18]; 237 char fill; 238 time_t tstamp; 239 240 tstamp = lp->entry->timestamp; 241 lp->entry->timestamp = tstamp; 242 fill = ' '; 243 if (!krb5_timestamp_to_sfstring((krb5_timestamp)lp->entry-> 244 timestamp, 245 fmtbuf, 246 sizeof(fmtbuf), 247 &fill)) 248 printf("%s ", fmtbuf); 249 } 250 printf("%40s", pname); 251 if (show_enctype) { 252 static char buf[256]; 253 if ((retval = krb5_enctype_to_name(lp->entry->key.enctype, FALSE, 254 buf, sizeof(buf)))) { 255 com_err(argv[0], retval, 256 _("While converting enctype to string")); 257 free(pname); 258 return; 259 } 260 printf(" (%s) ", buf); 261 } 262 263 if (show_keys) { 264 printf(" (0x"); 265 for (j = 0; j < lp->entry->key.length; j++) 266 printf("%02x", lp->entry->key.contents[j]); 267 printf(")"); 268 } 269 printf("\n"); 270 free(pname); 271 } 272 } 273