1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <krb5.h> 7 #include "k5-platform.h" 8 9 static char *prog; 10 static int quiet = 0; 11 12 static void 13 xusage() 14 { 15 fprintf(stderr, "xusage: %s [-c ccache] [-e etype] [-f flags] service1 " 16 "service2 ...\n", prog); 17 exit(1); 18 } 19 20 static void 21 do_kdeltkt(int argc, char *argv[], char *ccachestr, char *etypestr, int flags); 22 23 int 24 main(int argc, char *argv[]) 25 { 26 int option; 27 char *etypestr = NULL, *ccachestr = NULL; 28 int flags = 0; 29 30 prog = strrchr(argv[0], '/'); 31 prog = (prog != NULL) ? prog + 1 : argv[0]; 32 33 while ((option = getopt(argc, argv, "c:e:f:hq")) != -1) { 34 switch (option) { 35 case 'c': 36 ccachestr = optarg; 37 break; 38 case 'e': 39 etypestr = optarg; 40 break; 41 case 'f': 42 flags = atoi(optarg); 43 break; 44 case 'q': 45 quiet = 1; 46 break; 47 case 'h': 48 default: 49 xusage(); 50 break; 51 } 52 } 53 54 if (argc - optind < 1) 55 xusage(); 56 57 do_kdeltkt(argc - optind, argv + optind, ccachestr, etypestr, flags); 58 return 0; 59 } 60 61 static void 62 do_kdeltkt(int count, char *names[], const char *ccachestr, char *etypestr, 63 int flags) 64 { 65 krb5_context context; 66 krb5_error_code ret; 67 int i, errors; 68 krb5_enctype etype; 69 krb5_ccache ccache; 70 krb5_principal me; 71 krb5_creds in_creds, out_creds; 72 int retflags; 73 char *princ; 74 75 ret = krb5_init_context(&context); 76 if (ret) { 77 com_err(prog, ret, "while initializing krb5 library"); 78 exit(1); 79 } 80 81 if (etypestr != NULL) { 82 ret = krb5_string_to_enctype(etypestr, &etype); 83 if (ret) { 84 com_err(prog, ret, "while converting etype"); 85 exit(1); 86 } 87 retflags = KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES; 88 } else { 89 etype = 0; 90 retflags = KRB5_TC_MATCH_SRV_NAMEONLY; 91 } 92 93 if (ccachestr) 94 ret = krb5_cc_resolve(context, ccachestr, &ccache); 95 else 96 ret = krb5_cc_default(context, &ccache); 97 if (ret) { 98 com_err(prog, ret, "while opening ccache"); 99 exit(1); 100 } 101 102 ret = krb5_cc_get_principal(context, ccache, &me); 103 if (ret) { 104 com_err(prog, ret, "while getting client principal name"); 105 exit(1); 106 } 107 108 errors = 0; 109 110 for (i = 0; i < count; i++) { 111 memset(&in_creds, 0, sizeof(in_creds)); 112 113 in_creds.client = me; 114 115 ret = krb5_parse_name(context, names[i], &in_creds.server); 116 if (ret) { 117 if (!quiet) { 118 fprintf(stderr, "%s: %s while parsing principal name\n", 119 names[i], error_message(ret)); 120 } 121 errors++; 122 continue; 123 } 124 125 ret = krb5_unparse_name(context, in_creds.server, &princ); 126 if (ret) { 127 fprintf(stderr, "%s: %s while printing principal name\n", 128 names[i], error_message(ret)); 129 errors++; 130 continue; 131 } 132 133 in_creds.keyblock.enctype = etype; 134 135 ret = krb5_cc_retrieve_cred(context, ccache, retflags, 136 &in_creds, &out_creds); 137 if (ret) { 138 fprintf(stderr, "%s: %s while retrieving credentials\n", 139 princ, error_message(ret)); 140 krb5_free_unparsed_name(context, princ); 141 errors++; 142 continue; 143 } 144 145 ret = krb5_cc_remove_cred(context, ccache, flags, &out_creds); 146 147 krb5_free_principal(context, in_creds.server); 148 149 if (ret) { 150 fprintf(stderr, "%s: %s while removing credentials\n", 151 princ, error_message(ret)); 152 krb5_free_cred_contents(context, &out_creds); 153 krb5_free_unparsed_name(context, princ); 154 errors++; 155 continue; 156 } 157 krb5_free_unparsed_name(context, princ); 158 krb5_free_cred_contents(context, &out_creds); 159 } 160 161 krb5_free_principal(context, me); 162 krb5_cc_close(context, ccache); 163 krb5_free_context(context); 164 165 if (errors) 166 exit(1); 167 168 exit(0); 169 } 170