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