1 /* 2 * Copyright (c) 1997 - 2007 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "kuser_locl.h" 35 36 RCSID("$Id: kgetcred.c 22276 2007-12-12 02:42:31Z lha $"); 37 38 static char *cache_str; 39 static char *out_cache_str; 40 static char *delegation_cred_str; 41 static char *etype_str; 42 static int transit_flag = 1; 43 static int forwardable_flag; 44 static char *impersonate_str; 45 static char *nametype_str; 46 static int version_flag; 47 static int help_flag; 48 49 struct getargs args[] = { 50 { "cache", 'c', arg_string, &cache_str, 51 "credential cache to use", "cache"}, 52 { "out-cache", 0, arg_string, &out_cache_str, 53 "credential cache to store credential in", "cache"}, 54 { "delegation-credential-cache",0,arg_string, &delegation_cred_str, 55 "where to find the ticket use for delegation", "cache"}, 56 { "forwardable", 0, arg_flag, &forwardable_flag, 57 "forwardable ticket requested"}, 58 { "transit-check", 0, arg_negative_flag, &transit_flag }, 59 { "enctype", 'e', arg_string, &etype_str, 60 "encryption type to use", "enctype"}, 61 { "impersonate", 0, arg_string, &impersonate_str, 62 "client to impersonate", "principal"}, 63 { "name-type", 0, arg_string, &nametype_str }, 64 { "version", 0, arg_flag, &version_flag }, 65 { "help", 0, arg_flag, &help_flag } 66 }; 67 68 static void 69 usage (int ret) 70 { 71 arg_printusage (args, 72 sizeof(args)/sizeof(*args), 73 NULL, 74 "service"); 75 exit (ret); 76 } 77 78 int 79 main(int argc, char **argv) 80 { 81 krb5_error_code ret; 82 krb5_context context; 83 krb5_ccache cache; 84 krb5_creds *out; 85 int optidx = 0; 86 krb5_get_creds_opt opt; 87 krb5_principal server; 88 krb5_principal impersonate = NULL; 89 90 setprogname (argv[0]); 91 92 ret = krb5_init_context (&context); 93 if (ret) 94 errx(1, "krb5_init_context failed: %d", ret); 95 96 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 97 usage(1); 98 99 if (help_flag) 100 usage (0); 101 102 if(version_flag) { 103 print_version(NULL); 104 exit(0); 105 } 106 107 argc -= optidx; 108 argv += optidx; 109 110 if (argc != 1) 111 usage (1); 112 113 if(cache_str) { 114 ret = krb5_cc_resolve(context, cache_str, &cache); 115 if (ret) 116 krb5_err (context, 1, ret, "%s", cache_str); 117 } else { 118 ret = krb5_cc_default (context, &cache); 119 if (ret) 120 krb5_err (context, 1, ret, "krb5_cc_resolve"); 121 } 122 123 ret = krb5_get_creds_opt_alloc(context, &opt); 124 if (ret) 125 krb5_err (context, 1, ret, "krb5_get_creds_opt_alloc"); 126 127 if (etype_str) { 128 krb5_enctype enctype; 129 130 ret = krb5_string_to_enctype(context, etype_str, &enctype); 131 if (ret) 132 krb5_errx (context, 1, "unrecognized enctype: %s", etype_str); 133 krb5_get_creds_opt_set_enctype(context, opt, enctype); 134 } 135 136 if (impersonate_str) { 137 ret = krb5_parse_name(context, impersonate_str, &impersonate); 138 if (ret) 139 krb5_err (context, 1, ret, "krb5_parse_name %s", impersonate_str); 140 krb5_get_creds_opt_set_impersonate(context, opt, impersonate); 141 krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE); 142 } 143 144 if (out_cache_str) 145 krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE); 146 147 if (forwardable_flag) 148 krb5_get_creds_opt_add_options(context, opt, KRB5_GC_FORWARDABLE); 149 if (!transit_flag) 150 krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_TRANSIT_CHECK); 151 152 if (delegation_cred_str) { 153 krb5_ccache id; 154 krb5_creds c, mc; 155 Ticket ticket; 156 157 krb5_cc_clear_mcred(&mc); 158 ret = krb5_cc_get_principal(context, cache, &mc.server); 159 if (ret) 160 krb5_err (context, 1, ret, "krb5_cc_get_principal"); 161 162 ret = krb5_cc_resolve(context, delegation_cred_str, &id); 163 if(ret) 164 krb5_err (context, 1, ret, "krb5_cc_resolve"); 165 166 ret = krb5_cc_retrieve_cred(context, id, 0, &mc, &c); 167 if(ret) 168 krb5_err (context, 1, ret, "krb5_cc_retrieve_cred"); 169 170 ret = decode_Ticket(c.ticket.data, c.ticket.length, &ticket, NULL); 171 if (ret) { 172 krb5_clear_error_string(context); 173 krb5_err (context, 1, ret, "decode_Ticket"); 174 } 175 krb5_free_cred_contents(context, &c); 176 177 ret = krb5_get_creds_opt_set_ticket(context, opt, &ticket); 178 if(ret) 179 krb5_err (context, 1, ret, "krb5_get_creds_opt_set_ticket"); 180 free_Ticket(&ticket); 181 182 krb5_cc_close (context, id); 183 krb5_free_principal(context, mc.server); 184 185 krb5_get_creds_opt_add_options(context, opt, 186 KRB5_GC_CONSTRAINED_DELEGATION); 187 } 188 189 ret = krb5_parse_name(context, argv[0], &server); 190 if (ret) 191 krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]); 192 193 if (nametype_str) { 194 ret = krb5_parse_nametype(context, nametype_str, 195 &server->name.name_type); 196 if (ret) 197 krb5_err(context, 1, ret, "krb5_parse_nametype"); 198 } 199 200 ret = krb5_get_creds(context, opt, cache, server, &out); 201 if (ret) 202 krb5_err (context, 1, ret, "krb5_get_creds"); 203 204 if (out_cache_str) { 205 krb5_ccache id; 206 207 ret = krb5_cc_resolve(context, out_cache_str, &id); 208 if(ret) 209 krb5_err (context, 1, ret, "krb5_cc_resolve"); 210 211 ret = krb5_cc_initialize(context, id, out->client); 212 if(ret) 213 krb5_err (context, 1, ret, "krb5_cc_initialize"); 214 215 ret = krb5_cc_store_cred(context, id, out); 216 if(ret) 217 krb5_err (context, 1, ret, "krb5_cc_store_cred"); 218 krb5_cc_close (context, id); 219 } 220 221 krb5_free_creds(context, out); 222 krb5_free_principal(context, server); 223 krb5_get_creds_opt_free(context, opt); 224 krb5_cc_close (context, cache); 225 krb5_free_context (context); 226 227 return 0; 228 } 229