1/* 2 * Copyright (C) 1998 by the FundsXpress, INC. 3 * 4 * All rights reserved. 5 * 6 * Export of this software from the United States of America may require 7 * a specific license from the United States Government. It is the 8 * responsibility of any person or organization contemplating export to 9 * obtain such a license before exporting. 10 * 11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 12 * distribute this software and its documentation for any purpose and 13 * without fee is hereby granted, provided that the above copyright 14 * notice appear in all copies and that both that copyright notice and 15 * this permission notice appear in supporting documentation, and that 16 * the name of FundsXpress. not be used in advertising or publicity pertaining 17 * to distribution of the software without specific, written prior 18 * permission. FundsXpress makes no representations about the suitability of 19 * this software for any purpose. It is provided "as is" without express 20 * or implied warranty. 21 * 22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 24 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 25 */ 26 27#include "kuser_locl.h" 28 29static char *etype_str = NULL; 30static char *ccache_name = NULL; 31static char *keytab_name = NULL; 32static char *sname = NULL; 33 34static int version_flag = 0; 35static int help_flag = 0; 36static int quiet_flag = 0; 37 38static void do_v5_kvno (int argc, char *argv[], 39 char *ccache_name, char *etype_str, char *keytab_name, 40 char *sname); 41 42struct getargs args[] = { 43 { "enctype", 'e', arg_string, &etype_str, 44 NP_("Encryption type to use", ""), "enctype" }, 45 { "cache", 'c', arg_string, &ccache_name, 46 NP_("Credentials cache", ""), "cachename" }, 47 { "keytab", 'k', arg_string, &keytab_name, 48 NP_("Keytab to use", ""), "keytabname" }, 49 { "server", 'S', arg_string, &sname, 50 NP_("Server to get ticket for", ""), "principal" }, 51 { "quiet", 'q', arg_flag, &quiet_flag, 52 NP_("Quiet", "") }, 53 { "version", 0, arg_flag, &version_flag }, 54 { "help", 0, arg_flag, &help_flag } 55}; 56 57static void 58usage(int ret) 59{ 60 arg_printusage_i18n (args, sizeof(args)/sizeof(*args), 61 N_("Usage: ", ""), NULL, 62 "principal1 [principal2 ...]", 63 getarg_i18n); 64 exit (ret); 65} 66 67int main(int argc, char *argv[]) 68{ 69 int optidx = 0; 70 71 setprogname (argv[0]); 72 73 setlocale(LC_ALL, ""); 74 bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); 75 textdomain("heimdal_kuser"); 76 77 if (getarg(args, sizeof(args)/sizeof(args[0]), argc, argv, &optidx)) 78 usage(1); 79 80 if (help_flag) 81 usage (0); 82 83 if (version_flag) { 84 print_version(NULL); 85 exit (0); 86 } 87 88 argc -= optidx; 89 argv += optidx; 90 91 do_v5_kvno(argc, argv, ccache_name, etype_str, keytab_name, sname); 92 93 return 0; 94} 95 96static void do_v5_kvno (int count, char *names[], 97 char * ccache_name, char *etype_str, char *keytab_name, 98 char *sname) 99{ 100 krb5_error_code ret; 101 krb5_context context = 0; 102 int i, errors; 103 krb5_enctype etype; 104 krb5_ccache ccache; 105 krb5_principal me; 106 krb5_creds in_creds, *out_creds = NULL; 107 Ticket ticket; 108 size_t len; 109 char *princ = NULL; 110 krb5_keytab keytab = NULL; 111 112 ret = krb5_init_context(&context); 113 if (ret) 114 errx(1, "krb5_init_context failed: %d", ret); 115 116 if (etype_str) { 117 ret = krb5_string_to_enctype(context, etype_str, &etype); 118 if (ret) 119 krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str); 120 } else { 121 etype = 0; 122 } 123 124 if (ccache_name) 125 ret = krb5_cc_resolve(context, ccache_name, &ccache); 126 else 127 ret = krb5_cc_default(context, &ccache); 128 if (ret) 129 krb5_err(context, 1, ret, "Failed to open credentials cache %s", 130 (ccache_name) ? ccache_name : "(Default)"); 131 132 if (keytab_name) { 133 ret = krb5_kt_resolve(context, keytab_name, &keytab); 134 if (ret) 135 krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name); 136 } 137 138 ret = krb5_cc_get_principal(context, ccache, &me); 139 if (ret) 140 krb5_err(context, 1, ret, "krb5_cc_get_principal"); 141 142 errors = 0; 143 144 for (i = 0; i < count; i++) { 145 memset(&in_creds, 0, sizeof(in_creds)); 146 memset(&ticket, 0, sizeof(ticket)); 147 148 in_creds.client = me; 149 150 if (sname != NULL) { 151 ret = krb5_sname_to_principal(context, names[i], 152 sname, KRB5_NT_SRV_HST, 153 &in_creds.server); 154 } else { 155 ret = krb5_parse_name(context, names[i], &in_creds.server); 156 } 157 if (ret) { 158 if (!quiet_flag) 159 krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]); 160 errors++; 161 continue; 162 } 163 164 ret = krb5_unparse_name(context, in_creds.server, &princ); 165 if (ret) { 166 krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'", 167 names[i]); 168 errors++; 169 goto next; 170 } 171 172 in_creds.session.keytype = etype; 173 174 ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds); 175 176 if (ret) { 177 krb5_warn(context, ret, "Couldn't get credentials for %s", princ); 178 errors++; 179 goto next; 180 } 181 182 ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length, 183 &ticket, &len); 184 if (ret) { 185 krb5_err(context, 1, ret, "Can't decode ticket for %s", princ); 186 errors++; 187 goto next; 188 continue; 189 } 190 191 if (keytab) { 192 krb5_keytab_entry kte; 193 krb5_crypto crypto; 194 krb5_data dec_data; 195 EncTicketPart decr_part; 196 197 ret = krb5_kt_get_entry(context, keytab, in_creds.server, 198 (ticket.enc_part.kvno != NULL)? 199 *ticket.enc_part.kvno : 0, 200 ticket.enc_part.etype, 201 &kte); 202 if (ret) { 203 krb5_warn(context, ret, "Can't decrypt ticket for %s", princ); 204 if (!quiet_flag) 205 printf("%s: kvno = %d, keytab entry invalid", princ, 206 (ticket.enc_part.kvno != NULL)? 207 *ticket.enc_part.kvno : 0); 208 errors ++; 209 goto next; 210 } 211 212 ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto); 213 if (ret) { 214 krb5_warn(context, ret, "krb5_crypto_init"); 215 errors ++; 216 krb5_kt_free_entry(context, &kte); 217 goto next; 218 } 219 220 ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET, 221 &ticket.enc_part, &dec_data); 222 krb5_crypto_destroy(context, crypto); 223 krb5_kt_free_entry(context, &kte); 224 225 if (ret) { 226 krb5_warn(context, ret, "krb5_decrypt_EncryptedData"); 227 errors ++; 228 goto next; 229 } 230 231 ret = decode_EncTicketPart(dec_data.data, dec_data.length, 232 &decr_part, &len); 233 krb5_data_free(&dec_data); 234 if (ret) { 235 krb5_warn(context, ret, "decode_EncTicketPart"); 236 errors ++; 237 goto next; 238 } 239 240 if (!quiet_flag) 241 printf("%s: kvno = %d, keytab entry valid\n", princ, 242 (ticket.enc_part.kvno != NULL)? 243 *ticket.enc_part.kvno : 0); 244 245 free_EncTicketPart(&decr_part); 246 } else { 247 if (!quiet_flag) 248 printf("%s: kvno = %d\n", princ, 249 (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0); 250 } 251 252 next: 253 if (out_creds) { 254 krb5_free_creds(context, out_creds); 255 out_creds = NULL; 256 } 257 258 if (princ) { 259 krb5_free_unparsed_name(context, princ); 260 princ = NULL; 261 } 262 263 krb5_free_principal(context, in_creds.server); 264 265 free_Ticket(&ticket); 266 } 267 268 if (keytab) 269 krb5_kt_close(context, keytab); 270 krb5_free_principal(context, me); 271 krb5_cc_close(context, ccache); 272 krb5_free_context(context); 273 274 if (errors) 275 exit(1); 276 277 exit(0); 278} 279