1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * clients/kdestroy/kdestroy.c 9 * 10 * Copyright 1990 by the Massachusetts Institute of Technology. 11 * All Rights Reserved. 12 * 13 * Export of this software from the United States of America may 14 * require a specific license from the United States Government. 15 * It is the responsibility of any person or organization contemplating 16 * export to obtain such a license before exporting. 17 * 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of M.I.T. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. Furthermore if you modify this software you must label 26 * your software as modified software and not distribute it in such a 27 * fashion that it might be confused with the original M.I.T. software. 28 * M.I.T. makes no representations about the suitability of 29 * this software for any purpose. It is provided "as is" without express 30 * or implied warranty. 31 * 32 * 33 * Destroy the contents of your credential cache. 34 */ 35 36 #include <krb5.h> 37 #include <com_err.h> 38 #include <string.h> 39 #include <stdio.h> 40 #ifdef HAVE_UNISTD_H 41 #include <unistd.h> 42 #endif 43 #include <locale.h> 44 #include <rpc/types.h> 45 #include <rpc/rpcsys.h> 46 #include <rpc/rpcsec_gss.h> 47 #include <syslog.h> 48 #include <libintl.h> 49 50 #ifdef KRB5_KRB4_COMPAT 51 #include <kerberosIV/krb.h> 52 #endif 53 54 #ifdef __STDC__ 55 #define BELL_CHAR '\a' 56 #else 57 #define BELL_CHAR '\007' 58 #endif 59 60 extern int optind; 61 extern char *optarg; 62 63 #ifndef _WIN32 64 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x)) 65 #else 66 #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) 67 #endif 68 69 char *progname; 70 71 int got_k5 = 0; 72 int got_k4 = 0; 73 74 int default_k5 = 1; 75 #ifdef KRB5_KRB4_COMPAT 76 int default_k4 = 1; 77 #else 78 int default_k4 = 0; 79 #endif 80 81 82 static void usage() 83 { 84 #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available")) 85 86 fprintf(stderr, gettext("Usage"), ": %s [-5] [-4] [-q] [-c cache_name]\n", 87 progname); 88 fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5)); 89 fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4)); 90 fprintf(stderr, gettext("\t (Default is %s%s%s%s)\n"), 91 default_k5?"Kerberos 5":"", 92 (default_k5 && default_k4)?gettext(" and "):"", 93 default_k4?"Kerberos 4":"", 94 (!default_k5 && !default_k4)?gettext("neither"):""); 95 fprintf(stderr, gettext("\t-q quiet mode\n")); 96 fprintf(stderr, gettext("\t-c specify name of credentials cache\n")); 97 exit(2); 98 } 99 100 int 101 main(argc, argv) 102 int argc; 103 char **argv; 104 { 105 krb5_context kcontext; 106 krb5_error_code retval; 107 int c; 108 krb5_ccache cache = NULL; 109 char *cache_name = NULL; 110 char *client_name = NULL; 111 krb5_principal me; 112 int code = 0; 113 #ifdef KRB5_KRB4_COMPAT 114 int v4code = 0; 115 int v4 = 1; 116 #endif 117 int errflg = 0; 118 int quiet = 0; 119 struct krpc_revauth desarg; 120 static rpc_gss_OID_desc oid= 121 {9, "\052\206\110\206\367\022\001\002\002"}; 122 123 static rpc_gss_OID krb5_mech_type = &oid; 124 125 int use_k5 = 0; 126 int use_k4 = 0; 127 128 progname = GET_PROGNAME(argv[0]); 129 /* set locale and domain for internationalization */ 130 (void) setlocale(LC_ALL, ""); 131 132 #if !defined(TEXT_DOMAIN) 133 #define TEXT_DOMAIN "SYS_TEST" 134 #endif /* !TEXT_DOMAIN */ 135 136 (void) textdomain(TEXT_DOMAIN); 137 138 got_k5 = 1; 139 #ifdef KRB5_KRB4_COMPAT 140 got_k4 = 1; 141 #endif 142 143 while ((c = getopt(argc, argv, "54qc:")) != -1) { 144 switch (c) { 145 case 'q': 146 quiet = 1; 147 break; 148 case 'c': 149 if (cache_name) { 150 fprintf(stderr, gettext("Only one -c option allowed\n")); 151 errflg++; 152 } else { 153 cache_name = optarg; 154 } 155 break; 156 case '4': 157 if (!got_k4) 158 { 159 #ifdef KRB5_KRB4_COMPAT 160 fprintf(stderr, "Kerberos 4 support could not be loaded\n"); 161 #else 162 fprintf(stderr, gettext("This was not built with Kerberos 4 support\n")); 163 #endif 164 exit(3); 165 } 166 use_k4 = 1; 167 break; 168 case '5': 169 if (!got_k5) 170 { 171 fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n")); 172 exit(3); 173 } 174 use_k5 = 1; 175 break; 176 case '?': 177 default: 178 errflg++; 179 break; 180 } 181 } 182 183 if (optind != argc) 184 errflg++; 185 186 if (errflg) { 187 usage(); 188 } 189 190 if (!use_k5 && !use_k4) 191 { 192 use_k5 = default_k5; 193 use_k4 = default_k4; 194 } 195 196 if (!use_k5) 197 got_k5 = 0; 198 if (!use_k4) 199 got_k4 = 0; 200 201 if (got_k5) { 202 retval = krb5_init_context(&kcontext); 203 if (retval) { 204 com_err(progname, retval, gettext("while initializing krb5")); 205 exit(1); 206 } 207 208 /* 209 * Solaris Kerberos 210 * Let us destroy the kernel cache first 211 */ 212 desarg.version = 1; 213 desarg.uid_1 = geteuid(); 214 desarg.rpcsec_flavor_1 = RPCSEC_GSS; 215 desarg.flavor_data_1 = (void *) krb5_mech_type; 216 code = krpc_sys(KRPC_REVAUTH, (void *)&desarg); 217 218 if (code != 0) { 219 fprintf(stderr, 220 gettext("%s: kernel creds cache error %d \n"), 221 progname, code); 222 } 223 224 if (cache == NULL) { 225 if (code = krb5_cc_default(kcontext, &cache)) { 226 com_err(progname, code, 227 gettext("while getting default ccache")); 228 exit(1); 229 } 230 } 231 232 if (cache_name) { 233 #ifdef KRB5_KRB4_COMPAT 234 v4 = 0; /* Don't do v4 if doing v5 and cache name given. */ 235 #endif 236 code = krb5_cc_resolve (kcontext, cache_name, &cache); 237 if (code != 0) { 238 com_err (progname, code, gettext("while resolving %s"), cache_name); 239 exit(1); 240 } 241 } else { 242 code = krb5_cc_default(kcontext, &cache); 243 if (code) { 244 com_err(progname, code, gettext("while getting default ccache")); 245 exit(1); 246 } 247 } 248 249 /* 250 * Solaris Kerberos 251 * Get client name for kwarn_del_warning. 252 */ 253 code = krb5_cc_get_principal(kcontext, cache, &me); 254 if (code != 0) 255 fprintf(stderr, gettext 256 ("%s: Could not obtain principal name from cache\n"), progname); 257 else 258 if ((code = krb5_unparse_name(kcontext, me, &client_name))) 259 fprintf(stderr, gettext 260 ("%s: Could not unparse principal name found in cache\n"), progname); 261 262 code = krb5_cc_destroy (kcontext, cache); 263 if (code != 0) { 264 com_err (progname, code, gettext("while destroying cache")); 265 if (code != KRB5_FCC_NOFILE) { 266 if (quiet) 267 fprintf(stderr, gettext("Ticket cache NOT destroyed!\n")); 268 else { 269 fprintf(stderr, gettext("Ticket cache %cNOT%c destroyed!\n"), 270 BELL_CHAR, BELL_CHAR); 271 } 272 errflg = 1; 273 } 274 } 275 } 276 #ifdef KRB5_KRB4_COMPAT 277 if (got_k4 && v4) { 278 v4code = dest_tkt(); 279 if (v4code == KSUCCESS && code != 0) 280 fprintf(stderr, "Kerberos 4 ticket cache destroyed.\n"); 281 if (v4code != KSUCCESS && v4code != RET_TKFIL) { 282 if (quiet) 283 fprintf(stderr, "Kerberos 4 ticket cache NOT destroyed!\n"); 284 else 285 fprintf(stderr, "Kerberos 4 ticket cache %cNOT%c destroyed!\n", 286 BELL_CHAR, BELL_CHAR); 287 errflg = 1; 288 } 289 } 290 #endif 291 292 /* Solaris Kerberos */ 293 if (!errflg && client_name) 294 kwarn_del_warning(client_name); 295 else 296 fprintf(stderr, gettext 297 ("%s: TGT expire warning NOT deleted\n"), progname); 298 299 return errflg; 300 } 301