1 1.1 elric /* $NetBSD: copy_cred_cache.c,v 1.2 2017/01/28 21:31:45 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 2004 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "kuser_locl.h" 37 1.1 elric #include <config.h> 38 1.1 elric #include <krb5/parse_units.h> 39 1.1 elric #include <krb5/parse_time.h> 40 1.2 christos #include "heimtools-commands.h" 41 1.1 elric 42 1.1 elric static int32_t 43 1.1 elric bitswap32(int32_t b) 44 1.1 elric { 45 1.1 elric int32_t r = 0; 46 1.1 elric int i; 47 1.1 elric for (i = 0; i < 32; i++) { 48 1.1 elric r = r << 1 | (b & 1); 49 1.1 elric b = b >> 1; 50 1.1 elric } 51 1.1 elric return r; 52 1.1 elric } 53 1.1 elric 54 1.1 elric static void 55 1.1 elric parse_ticket_flags(krb5_context context, 56 1.1 elric const char *string, krb5_ticket_flags *ret_flags) 57 1.1 elric { 58 1.1 elric TicketFlags ff; 59 1.1 elric int flags = parse_flags(string, asn1_TicketFlags_units(), 0); 60 1.1 elric if (flags == -1) /* XXX */ 61 1.1 elric krb5_errx(context, 1, "bad flags specified: \"%s\"", string); 62 1.1 elric 63 1.1 elric memset(&ff, 0, sizeof(ff)); 64 1.1 elric ff.proxy = 1; 65 1.2 christos if ((size_t)parse_flags("proxy", asn1_TicketFlags_units(), 0) == TicketFlags2int(ff)) 66 1.1 elric ret_flags->i = flags; 67 1.1 elric else 68 1.1 elric ret_flags->i = bitswap32(flags); 69 1.1 elric } 70 1.1 elric 71 1.1 elric struct ctx { 72 1.1 elric krb5_flags whichfields; 73 1.1 elric krb5_creds mcreds; 74 1.1 elric }; 75 1.1 elric 76 1.1 elric static krb5_boolean 77 1.1 elric matchfunc(krb5_context context, void *ptr, const krb5_creds *creds) 78 1.1 elric { 79 1.1 elric struct ctx *ctx = ptr; 80 1.1 elric if (krb5_compare_creds(context, ctx->whichfields, &ctx->mcreds, creds)) 81 1.1 elric return TRUE; 82 1.1 elric return FALSE; 83 1.1 elric } 84 1.1 elric 85 1.1 elric int 86 1.1 elric copy_cred_cache(struct copy_cred_cache_options *opt, int argc, char **argv) 87 1.1 elric { 88 1.1 elric krb5_error_code ret; 89 1.1 elric const char *from_name, *to_name; 90 1.1 elric krb5_ccache from_ccache, to_ccache; 91 1.1 elric unsigned int matched; 92 1.1 elric struct ctx ctx; 93 1.1 elric 94 1.1 elric memset(&ctx, 0, sizeof(ctx)); 95 1.1 elric 96 1.1 elric if (opt->service_string) { 97 1.2 christos ret = krb5_parse_name(heimtools_context, opt->service_string, &ctx.mcreds.server); 98 1.1 elric if (ret) 99 1.2 christos krb5_err(heimtools_context, 1, ret, "%s", opt->service_string); 100 1.1 elric } 101 1.1 elric if (opt->enctype_string) { 102 1.1 elric krb5_enctype enctype; 103 1.2 christos ret = krb5_string_to_enctype(heimtools_context, opt->enctype_string, &enctype); 104 1.1 elric if (ret) 105 1.2 christos krb5_err(heimtools_context, 1, ret, "%s", opt->enctype_string); 106 1.1 elric ctx.whichfields |= KRB5_TC_MATCH_KEYTYPE; 107 1.1 elric ctx.mcreds.session.keytype = enctype; 108 1.1 elric } 109 1.1 elric if (opt->flags_string) { 110 1.2 christos parse_ticket_flags(heimtools_context, opt->flags_string, &ctx.mcreds.flags); 111 1.1 elric ctx.whichfields |= KRB5_TC_MATCH_FLAGS; 112 1.1 elric } 113 1.1 elric if (opt->valid_for_string) { 114 1.1 elric time_t t = parse_time(opt->valid_for_string, "s"); 115 1.1 elric if(t < 0) 116 1.1 elric errx(1, "unknown time \"%s\"", opt->valid_for_string); 117 1.2 christos krb5_timeofday(heimtools_context, &ctx.mcreds.times.endtime); 118 1.2 christos ctx.mcreds.times.endtime += t; 119 1.1 elric ctx.whichfields |= KRB5_TC_MATCH_TIMES; 120 1.1 elric } 121 1.1 elric if (opt->fcache_version_integer) 122 1.2 christos krb5_set_fcache_version(heimtools_context, opt->fcache_version_integer); 123 1.1 elric 124 1.1 elric if (argc == 1) { 125 1.2 christos from_name = krb5_cc_default_name(heimtools_context); 126 1.1 elric to_name = argv[0]; 127 1.1 elric } else { 128 1.1 elric from_name = argv[0]; 129 1.1 elric to_name = argv[1]; 130 1.1 elric } 131 1.1 elric 132 1.2 christos ret = krb5_cc_resolve(heimtools_context, from_name, &from_ccache); 133 1.1 elric if (ret) 134 1.2 christos krb5_err(heimtools_context, 1, ret, "%s", from_name); 135 1.1 elric 136 1.1 elric if (opt->krbtgt_only_flag) { 137 1.1 elric krb5_principal client; 138 1.2 christos ret = krb5_cc_get_principal(heimtools_context, from_ccache, &client); 139 1.1 elric if (ret) 140 1.2 christos krb5_err(heimtools_context, 1, ret, "getting default principal"); 141 1.2 christos ret = krb5_make_principal(heimtools_context, &ctx.mcreds.server, 142 1.2 christos krb5_principal_get_realm(heimtools_context, client), 143 1.1 elric KRB5_TGS_NAME, 144 1.2 christos krb5_principal_get_realm(heimtools_context, client), 145 1.1 elric NULL); 146 1.1 elric if (ret) 147 1.2 christos krb5_err(heimtools_context, 1, ret, "constructing krbtgt principal"); 148 1.2 christos krb5_free_principal(heimtools_context, client); 149 1.1 elric } 150 1.2 christos ret = krb5_cc_resolve(heimtools_context, to_name, &to_ccache); 151 1.1 elric if (ret) 152 1.2 christos krb5_err(heimtools_context, 1, ret, "%s", to_name); 153 1.1 elric 154 1.2 christos ret = krb5_cc_copy_match_f(heimtools_context, from_ccache, to_ccache, 155 1.1 elric matchfunc, &ctx, &matched); 156 1.1 elric if (ret) 157 1.2 christos krb5_err(heimtools_context, 1, ret, "copying cred cache"); 158 1.1 elric 159 1.2 christos krb5_cc_close(heimtools_context, from_ccache); 160 1.1 elric if(matched == 0) 161 1.2 christos krb5_cc_destroy(heimtools_context, to_ccache); 162 1.1 elric else 163 1.2 christos krb5_cc_close(heimtools_context, to_ccache); 164 1.1 elric 165 1.1 elric return matched == 0; 166 1.1 elric } 167