Path: blob/main/crypto/heimdal/kuser/copy_cred_cache.c
34860 views
/*1* Copyright (c) 2004 Kungliga Tekniska Högskolan2* (Royal Institute of Technology, Stockholm, Sweden).3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8*9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* 3. Neither the name of the Institute nor the names of its contributors17* may be used to endorse or promote products derived from this software18* without specific prior written permission.19*20* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND21* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE23* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE24* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL25* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS26* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)27* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT28* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY29* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF30* SUCH DAMAGE.31*/3233#include "kuser_locl.h"34#include <config.h>35#include <parse_units.h>36#include <parse_time.h>37#include "kcc-commands.h"3839static int32_t40bitswap32(int32_t b)41{42int32_t r = 0;43int i;44for (i = 0; i < 32; i++) {45r = r << 1 | (b & 1);46b = b >> 1;47}48return r;49}5051static void52parse_ticket_flags(krb5_context context,53const char *string, krb5_ticket_flags *ret_flags)54{55TicketFlags ff;56int flags = parse_flags(string, asn1_TicketFlags_units(), 0);57if (flags == -1) /* XXX */58krb5_errx(context, 1, "bad flags specified: \"%s\"", string);5960memset(&ff, 0, sizeof(ff));61ff.proxy = 1;62if ((size_t)parse_flags("proxy", asn1_TicketFlags_units(), 0) == TicketFlags2int(ff))63ret_flags->i = flags;64else65ret_flags->i = bitswap32(flags);66}6768struct ctx {69krb5_flags whichfields;70krb5_creds mcreds;71};7273static krb5_boolean74matchfunc(krb5_context context, void *ptr, const krb5_creds *creds)75{76struct ctx *ctx = ptr;77if (krb5_compare_creds(context, ctx->whichfields, &ctx->mcreds, creds))78return TRUE;79return FALSE;80}8182int83copy_cred_cache(struct copy_cred_cache_options *opt, int argc, char **argv)84{85krb5_error_code ret;86const char *from_name, *to_name;87krb5_ccache from_ccache, to_ccache;88unsigned int matched;89struct ctx ctx;9091memset(&ctx, 0, sizeof(ctx));9293if (opt->service_string) {94ret = krb5_parse_name(kcc_context, opt->service_string, &ctx.mcreds.server);95if (ret)96krb5_err(kcc_context, 1, ret, "%s", opt->service_string);97}98if (opt->enctype_string) {99krb5_enctype enctype;100ret = krb5_string_to_enctype(kcc_context, opt->enctype_string, &enctype);101if (ret)102krb5_err(kcc_context, 1, ret, "%s", opt->enctype_string);103ctx.whichfields |= KRB5_TC_MATCH_KEYTYPE;104ctx.mcreds.session.keytype = enctype;105}106if (opt->flags_string) {107parse_ticket_flags(kcc_context, opt->flags_string, &ctx.mcreds.flags);108ctx.whichfields |= KRB5_TC_MATCH_FLAGS;109}110if (opt->valid_for_string) {111time_t t = parse_time(opt->valid_for_string, "s");112if(t < 0)113errx(1, "unknown time \"%s\"", opt->valid_for_string);114ctx.mcreds.times.endtime = time(NULL) + t;115ctx.whichfields |= KRB5_TC_MATCH_TIMES;116}117if (opt->fcache_version_integer)118krb5_set_fcache_version(kcc_context, opt->fcache_version_integer);119120if (argc == 1) {121from_name = krb5_cc_default_name(kcc_context);122to_name = argv[0];123} else {124from_name = argv[0];125to_name = argv[1];126}127128ret = krb5_cc_resolve(kcc_context, from_name, &from_ccache);129if (ret)130krb5_err(kcc_context, 1, ret, "%s", from_name);131132if (opt->krbtgt_only_flag) {133krb5_principal client;134ret = krb5_cc_get_principal(kcc_context, from_ccache, &client);135if (ret)136krb5_err(kcc_context, 1, ret, "getting default principal");137ret = krb5_make_principal(kcc_context, &ctx.mcreds.server,138krb5_principal_get_realm(kcc_context, client),139KRB5_TGS_NAME,140krb5_principal_get_realm(kcc_context, client),141NULL);142if (ret)143krb5_err(kcc_context, 1, ret, "constructing krbtgt principal");144krb5_free_principal(kcc_context, client);145}146ret = krb5_cc_resolve(kcc_context, to_name, &to_ccache);147if (ret)148krb5_err(kcc_context, 1, ret, "%s", to_name);149150ret = krb5_cc_copy_match_f(kcc_context, from_ccache, to_ccache,151matchfunc, &ctx, &matched);152if (ret)153krb5_err(kcc_context, 1, ret, "copying cred cache");154155krb5_cc_close(kcc_context, from_ccache);156if(matched == 0)157krb5_cc_destroy(kcc_context, to_ccache);158else159krb5_cc_close(kcc_context, to_ccache);160161return matched == 0;162}163164165