17c478bd9Sstevel@tonic-gate /*
2d71c749dSMark Phalan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/krb5/krb/get_creds.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1990 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
17*55fea89dSDan Cross *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
31*55fea89dSDan Cross *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * krb5_get_credentials()
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate Attempts to use the credentials cache or TGS exchange to get an additional
407c478bd9Sstevel@tonic-gate ticket for the
417c478bd9Sstevel@tonic-gate client identified by in_creds->client, the server identified by
427c478bd9Sstevel@tonic-gate in_creds->server, with options options, expiration date specified in
437c478bd9Sstevel@tonic-gate in_creds->times.endtime (0 means as long as possible), session key type
447c478bd9Sstevel@tonic-gate specified in in_creds->keyblock.enctype (if non-zero)
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate Any returned ticket and intermediate ticket-granting tickets are
477c478bd9Sstevel@tonic-gate stored in ccache.
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate returns errors from encryption routines, system errors
507c478bd9Sstevel@tonic-gate */
517c478bd9Sstevel@tonic-gate
52159d09a2SMark Phalan #include "k5-int.h"
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate /*ARGSUSED*/
557c478bd9Sstevel@tonic-gate static krb5_error_code
krb5_get_credentials_core(krb5_context context,krb5_flags options,krb5_creds * in_creds,krb5_creds * mcreds,krb5_flags * fields)56505d05c7Sgtb krb5_get_credentials_core(krb5_context context, krb5_flags options,
57505d05c7Sgtb krb5_creds *in_creds, krb5_creds *mcreds,
58505d05c7Sgtb krb5_flags *fields)
597c478bd9Sstevel@tonic-gate {
60159d09a2SMark Phalan /* Solaris Kerberos */
617c478bd9Sstevel@tonic-gate krb5_error_code ret = 0;
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate if (!in_creds || !in_creds->server || !in_creds->client)
647c478bd9Sstevel@tonic-gate return EINVAL;
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate memset((char *)mcreds, 0, sizeof(krb5_creds));
677c478bd9Sstevel@tonic-gate mcreds->magic = KV5M_CREDS;
687c478bd9Sstevel@tonic-gate /*
69159d09a2SMark Phalan * Solaris Kerberos:
707c478bd9Sstevel@tonic-gate * Set endtime appropriately to make sure we do not rope in
717c478bd9Sstevel@tonic-gate * expired creds. If endtime is set to 0 (which it almost always
727c478bd9Sstevel@tonic-gate * is, courtesy memset/calloc) the krb5_cc_retrieve_cred() call in
737c478bd9Sstevel@tonic-gate * krb5_get_credentials() with KRB5_TC_MATCH_TIMES will
747c478bd9Sstevel@tonic-gate * succeed and return the expired cred.
757c478bd9Sstevel@tonic-gate *
767c478bd9Sstevel@tonic-gate * Hence, endtime below is set to "now" if in_creds->times.endtime
777c478bd9Sstevel@tonic-gate * is 0, so that krb5_cc_retrieve_cred fails and we get fresh creds,
787c478bd9Sstevel@tonic-gate * if necessary. But, if in_creds has a non-zero endtime, we honor it.
797c478bd9Sstevel@tonic-gate */
807c478bd9Sstevel@tonic-gate if (in_creds->times.endtime != 0)
817c478bd9Sstevel@tonic-gate mcreds->times.endtime = in_creds->times.endtime;
827c478bd9Sstevel@tonic-gate else
837c478bd9Sstevel@tonic-gate if ((ret = krb5_timeofday(context, &mcreds->times.endtime)) != 0)
847c478bd9Sstevel@tonic-gate return (ret);
857c478bd9Sstevel@tonic-gate
86d71c749dSMark Phalan ret = krb5_copy_keyblock_contents(context, &in_creds->keyblock,
877c478bd9Sstevel@tonic-gate &mcreds->keyblock);
887c478bd9Sstevel@tonic-gate if (ret)
897c478bd9Sstevel@tonic-gate return (ret);
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate mcreds->authdata = in_creds->authdata;
927c478bd9Sstevel@tonic-gate mcreds->server = in_creds->server;
937c478bd9Sstevel@tonic-gate mcreds->client = in_creds->client;
94*55fea89dSDan Cross
957c478bd9Sstevel@tonic-gate *fields = KRB5_TC_MATCH_TIMES /*XXX |KRB5_TC_MATCH_SKEY_TYPE */
967c478bd9Sstevel@tonic-gate | KRB5_TC_MATCH_AUTHDATA
977c478bd9Sstevel@tonic-gate | KRB5_TC_SUPPORTED_KTYPES;
987c478bd9Sstevel@tonic-gate if (mcreds->keyblock.enctype) {
997c478bd9Sstevel@tonic-gate krb5_enctype *ktypes;
1007c478bd9Sstevel@tonic-gate int i;
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate *fields |= KRB5_TC_MATCH_KTYPE;
1037c478bd9Sstevel@tonic-gate ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes);
1047c478bd9Sstevel@tonic-gate for (i = 0; ktypes[i]; i++)
105159d09a2SMark Phalan if (ktypes[i] == mcreds->keyblock.enctype)
1067c478bd9Sstevel@tonic-gate break;
1077c478bd9Sstevel@tonic-gate if (ktypes[i] == 0)
108159d09a2SMark Phalan ret = KRB5_CC_NOT_KTYPE;
1097c478bd9Sstevel@tonic-gate free (ktypes);
110d71c749dSMark Phalan if (ret) {
111d71c749dSMark Phalan krb5_free_keyblock_contents(context, &mcreds->keyblock);
112159d09a2SMark Phalan return ret;
113d71c749dSMark Phalan }
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate if (options & KRB5_GC_USER_USER) {
1167c478bd9Sstevel@tonic-gate /* also match on identical 2nd tkt and tkt encrypted in a
1177c478bd9Sstevel@tonic-gate session key */
1187c478bd9Sstevel@tonic-gate *fields |= KRB5_TC_MATCH_2ND_TKT|KRB5_TC_MATCH_IS_SKEY;
1197c478bd9Sstevel@tonic-gate mcreds->is_skey = TRUE;
1207c478bd9Sstevel@tonic-gate mcreds->second_ticket = in_creds->second_ticket;
121d71c749dSMark Phalan if (!in_creds->second_ticket.length) {
122d71c749dSMark Phalan krb5_free_keyblock_contents(context, &mcreds->keyblock);
1237c478bd9Sstevel@tonic-gate return KRB5_NO_2ND_TKT;
124d71c749dSMark Phalan }
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate return 0;
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
130505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_credentials(krb5_context context,krb5_flags options,krb5_ccache ccache,krb5_creds * in_creds,krb5_creds ** out_creds)131505d05c7Sgtb krb5_get_credentials(krb5_context context, krb5_flags options,
132505d05c7Sgtb krb5_ccache ccache, krb5_creds *in_creds,
133505d05c7Sgtb krb5_creds **out_creds)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate krb5_error_code retval;
1367c478bd9Sstevel@tonic-gate krb5_creds mcreds;
1377c478bd9Sstevel@tonic-gate krb5_creds *ncreds;
1387c478bd9Sstevel@tonic-gate krb5_creds **tgts;
1397c478bd9Sstevel@tonic-gate krb5_flags fields;
1407c478bd9Sstevel@tonic-gate int not_ktype;
1417c478bd9Sstevel@tonic-gate
142505d05c7Sgtb retval = krb5_get_credentials_core(context, options,
143505d05c7Sgtb in_creds,
1447c478bd9Sstevel@tonic-gate &mcreds, &fields);
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate if (retval) return retval;
1477c478bd9Sstevel@tonic-gate
148d71c749dSMark Phalan if ((ncreds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) {
149d71c749dSMark Phalan krb5_free_keyblock_contents(context, &mcreds.keyblock);
1507c478bd9Sstevel@tonic-gate return ENOMEM;
151d71c749dSMark Phalan }
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate memset((char *)ncreds, 0, sizeof(krb5_creds));
1547c478bd9Sstevel@tonic-gate ncreds->magic = KV5M_CREDS;
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate /* The caller is now responsible for cleaning up in_creds */
157159d09a2SMark Phalan /* Solaris Kerberos */
1587c478bd9Sstevel@tonic-gate if ((retval = krb5_cc_retrieve_cred(context, ccache, fields, &mcreds,
1597c478bd9Sstevel@tonic-gate ncreds)) !=0) {
1607c478bd9Sstevel@tonic-gate krb5_xfree(ncreds);
1617c478bd9Sstevel@tonic-gate ncreds = in_creds;
1627c478bd9Sstevel@tonic-gate } else {
1637c478bd9Sstevel@tonic-gate *out_creds = ncreds;
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate if ((retval != KRB5_CC_NOTFOUND && retval != KRB5_CC_NOT_KTYPE)
167d71c749dSMark Phalan || options & KRB5_GC_CACHED) {
168d71c749dSMark Phalan krb5_free_keyblock_contents(context, &mcreds.keyblock);
1697c478bd9Sstevel@tonic-gate return retval;
170d71c749dSMark Phalan }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate if (retval == KRB5_CC_NOT_KTYPE)
1737c478bd9Sstevel@tonic-gate not_ktype = 1;
1747c478bd9Sstevel@tonic-gate else
1757c478bd9Sstevel@tonic-gate not_ktype = 0;
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts);
1787c478bd9Sstevel@tonic-gate if (tgts) {
1797c478bd9Sstevel@tonic-gate register int i = 0;
1807c478bd9Sstevel@tonic-gate krb5_error_code rv2;
1817c478bd9Sstevel@tonic-gate while (tgts[i]) {
182159d09a2SMark Phalan /* Solaris Kerberos */
1837c478bd9Sstevel@tonic-gate if ((rv2 = krb5_cc_store_cred(context, ccache, tgts[i])) != 0) {
1847c478bd9Sstevel@tonic-gate retval = rv2;
1857c478bd9Sstevel@tonic-gate break;
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate i++;
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate krb5_free_tgt_creds(context, tgts);
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate /*
1927c478bd9Sstevel@tonic-gate * Translate KRB5_CC_NOTFOUND if we previously got
1937c478bd9Sstevel@tonic-gate * KRB5_CC_NOT_KTYPE from krb5_cc_retrieve_cred(), in order to
1947c478bd9Sstevel@tonic-gate * handle the case where there is no TGT in the ccache and the
1957c478bd9Sstevel@tonic-gate * input enctype didn't match. This handling is necessary because
1967c478bd9Sstevel@tonic-gate * some callers, such as GSSAPI, iterate through enctypes and
1977c478bd9Sstevel@tonic-gate * KRB5_CC_NOTFOUND passed through from the
1987c478bd9Sstevel@tonic-gate * krb5_get_cred_from_kdc() is semantically incorrect, since the
1997c478bd9Sstevel@tonic-gate * actual failure was the non-existence of a ticket of the correct
2007c478bd9Sstevel@tonic-gate * enctype rather than the missing TGT.
2017c478bd9Sstevel@tonic-gate */
2027c478bd9Sstevel@tonic-gate if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE)
2037c478bd9Sstevel@tonic-gate && not_ktype)
2047c478bd9Sstevel@tonic-gate retval = KRB5_CC_NOT_KTYPE;
2057c478bd9Sstevel@tonic-gate
206159d09a2SMark Phalan if (!retval) {
207*55fea89dSDan Cross /* the purpose of the krb5_get_credentials call is to
208*55fea89dSDan Cross * obtain a set of credentials for the caller. the
209159d09a2SMark Phalan * krb5_cc_store_cred() call is to optimize performance
210159d09a2SMark Phalan * for future calls. Ignore any errors, since the credentials
211159d09a2SMark Phalan * are still valid even if we fail to store them in the cache.
212159d09a2SMark Phalan */
213159d09a2SMark Phalan /* Solaris Kerberos */
2147c478bd9Sstevel@tonic-gate retval = krb5_cc_store_cred(context, ccache, *out_creds);
215159d09a2SMark Phalan }
216d71c749dSMark Phalan
217d71c749dSMark Phalan krb5_free_keyblock_contents(context, &mcreds.keyblock);
2187c478bd9Sstevel@tonic-gate return retval;
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate #define INT_GC_VALIDATE 1
2227c478bd9Sstevel@tonic-gate #define INT_GC_RENEW 2
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate /*ARGSUSED*/
225*55fea89dSDan Cross static krb5_error_code
krb5_get_credentials_val_renew_core(krb5_context context,krb5_flags options,krb5_ccache ccache,krb5_creds * in_creds,krb5_creds ** out_creds,int which)226505d05c7Sgtb krb5_get_credentials_val_renew_core(krb5_context context, krb5_flags options,
227505d05c7Sgtb krb5_ccache ccache, krb5_creds *in_creds,
228505d05c7Sgtb krb5_creds **out_creds, int which)
2297c478bd9Sstevel@tonic-gate {
2307c478bd9Sstevel@tonic-gate krb5_error_code retval;
2317c478bd9Sstevel@tonic-gate krb5_principal tmp;
2327c478bd9Sstevel@tonic-gate krb5_creds **tgts = 0;
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate switch(which) {
2357c478bd9Sstevel@tonic-gate case INT_GC_VALIDATE:
236*55fea89dSDan Cross retval = krb5_get_cred_from_kdc_validate(context, ccache,
2377c478bd9Sstevel@tonic-gate in_creds, out_creds, &tgts);
2387c478bd9Sstevel@tonic-gate break;
2397c478bd9Sstevel@tonic-gate case INT_GC_RENEW:
240*55fea89dSDan Cross retval = krb5_get_cred_from_kdc_renew(context, ccache,
2417c478bd9Sstevel@tonic-gate in_creds, out_creds, &tgts);
2427c478bd9Sstevel@tonic-gate break;
2437c478bd9Sstevel@tonic-gate default:
2447c478bd9Sstevel@tonic-gate /* Should never happen */
2457c478bd9Sstevel@tonic-gate retval = 255;
2467c478bd9Sstevel@tonic-gate break;
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate if (retval) return retval;
2497c478bd9Sstevel@tonic-gate if (tgts) krb5_free_tgt_creds(context, tgts);
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate retval = krb5_cc_get_principal(context, ccache, &tmp);
2527c478bd9Sstevel@tonic-gate if (retval) return retval;
253*55fea89dSDan Cross
2547c478bd9Sstevel@tonic-gate retval = krb5_cc_initialize(context, ccache, tmp);
255159d09a2SMark Phalan /* Solaris Kerberos */
2567c478bd9Sstevel@tonic-gate if (retval) {
2577c478bd9Sstevel@tonic-gate krb5_free_principal(context, tmp);
2587c478bd9Sstevel@tonic-gate return retval;
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate retval = krb5_cc_store_cred(context, ccache, *out_creds);
2627c478bd9Sstevel@tonic-gate krb5_free_principal(context, tmp);
2637c478bd9Sstevel@tonic-gate return retval;
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate
266505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_credentials_validate(krb5_context context,krb5_flags options,krb5_ccache ccache,krb5_creds * in_creds,krb5_creds ** out_creds)267505d05c7Sgtb krb5_get_credentials_validate(krb5_context context, krb5_flags options,
268505d05c7Sgtb krb5_ccache ccache, krb5_creds *in_creds,
269505d05c7Sgtb krb5_creds **out_creds)
2707c478bd9Sstevel@tonic-gate {
271*55fea89dSDan Cross return(krb5_get_credentials_val_renew_core(context, options, ccache,
272*55fea89dSDan Cross in_creds, out_creds,
2737c478bd9Sstevel@tonic-gate INT_GC_VALIDATE));
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
276505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_credentials_renew(krb5_context context,krb5_flags options,krb5_ccache ccache,krb5_creds * in_creds,krb5_creds ** out_creds)277505d05c7Sgtb krb5_get_credentials_renew(krb5_context context, krb5_flags options,
278505d05c7Sgtb krb5_ccache ccache, krb5_creds *in_creds,
279505d05c7Sgtb krb5_creds **out_creds)
2807c478bd9Sstevel@tonic-gate {
2817c478bd9Sstevel@tonic-gate
282*55fea89dSDan Cross return(krb5_get_credentials_val_renew_core(context, options, ccache,
283*55fea89dSDan Cross in_creds, out_creds,
2847c478bd9Sstevel@tonic-gate INT_GC_RENEW));
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate static krb5_error_code
krb5_validate_or_renew_creds(krb5_context context,krb5_creds * creds,krb5_principal client,krb5_ccache ccache,char * in_tkt_service,int validate)288505d05c7Sgtb krb5_validate_or_renew_creds(krb5_context context, krb5_creds *creds,
289505d05c7Sgtb krb5_principal client, krb5_ccache ccache,
290505d05c7Sgtb char *in_tkt_service, int validate)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate krb5_error_code ret;
2937c478bd9Sstevel@tonic-gate krb5_creds in_creds; /* only client and server need to be filled in */
2947c478bd9Sstevel@tonic-gate krb5_creds *out_creds = 0; /* for check before dereferencing below */
2957c478bd9Sstevel@tonic-gate krb5_creds **tgts;
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate memset((char *)&in_creds, 0, sizeof(krb5_creds));
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate in_creds.server = NULL;
3007c478bd9Sstevel@tonic-gate tgts = NULL;
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate in_creds.client = client;
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate if (in_tkt_service) {
3057c478bd9Sstevel@tonic-gate /* this is ugly, because so are the data structures involved. I'm
3067c478bd9Sstevel@tonic-gate in the library, so I'm going to manipulate the data structures
3077c478bd9Sstevel@tonic-gate directly, otherwise, it will be worse. */
3087c478bd9Sstevel@tonic-gate
309505d05c7Sgtb if ((ret = krb5_parse_name(context, in_tkt_service, &in_creds.server)))
3107c478bd9Sstevel@tonic-gate goto cleanup;
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate /* stuff the client realm into the server principal.
3137c478bd9Sstevel@tonic-gate realloc if necessary */
3147c478bd9Sstevel@tonic-gate if (in_creds.server->realm.length < in_creds.client->realm.length)
3157c478bd9Sstevel@tonic-gate if ((in_creds.server->realm.data =
3167c478bd9Sstevel@tonic-gate (char *) realloc(in_creds.server->realm.data,
3177c478bd9Sstevel@tonic-gate in_creds.client->realm.length)) == NULL) {
3187c478bd9Sstevel@tonic-gate ret = ENOMEM;
3197c478bd9Sstevel@tonic-gate goto cleanup;
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate in_creds.server->realm.length = in_creds.client->realm.length;
3237c478bd9Sstevel@tonic-gate memcpy(in_creds.server->realm.data, in_creds.client->realm.data,
3247c478bd9Sstevel@tonic-gate in_creds.client->realm.length);
3257c478bd9Sstevel@tonic-gate } else {
326505d05c7Sgtb if ((ret = krb5_build_principal_ext(context, &in_creds.server,
3277c478bd9Sstevel@tonic-gate in_creds.client->realm.length,
3287c478bd9Sstevel@tonic-gate in_creds.client->realm.data,
3297c478bd9Sstevel@tonic-gate KRB5_TGS_NAME_SIZE,
3307c478bd9Sstevel@tonic-gate KRB5_TGS_NAME,
3317c478bd9Sstevel@tonic-gate in_creds.client->realm.length,
3327c478bd9Sstevel@tonic-gate in_creds.client->realm.data,
333505d05c7Sgtb 0)))
3347c478bd9Sstevel@tonic-gate goto cleanup;
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate if (validate)
338*55fea89dSDan Cross ret = krb5_get_cred_from_kdc_validate(context, ccache,
3397c478bd9Sstevel@tonic-gate &in_creds, &out_creds, &tgts);
3407c478bd9Sstevel@tonic-gate else
341*55fea89dSDan Cross ret = krb5_get_cred_from_kdc_renew(context, ccache,
3427c478bd9Sstevel@tonic-gate &in_creds, &out_creds, &tgts);
343*55fea89dSDan Cross
3447c478bd9Sstevel@tonic-gate /* ick. copy the struct contents, free the container */
3457c478bd9Sstevel@tonic-gate if (out_creds) {
3467c478bd9Sstevel@tonic-gate *creds = *out_creds;
3477c478bd9Sstevel@tonic-gate krb5_xfree(out_creds);
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate cleanup:
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate if (in_creds.server)
3537c478bd9Sstevel@tonic-gate krb5_free_principal(context, in_creds.server);
3547c478bd9Sstevel@tonic-gate if (tgts)
3557c478bd9Sstevel@tonic-gate krb5_free_tgt_creds(context, tgts);
3567c478bd9Sstevel@tonic-gate
3577c478bd9Sstevel@tonic-gate return(ret);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
360505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_validated_creds(krb5_context context,krb5_creds * creds,krb5_principal client,krb5_ccache ccache,char * in_tkt_service)361505d05c7Sgtb krb5_get_validated_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, char *in_tkt_service)
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate return(krb5_validate_or_renew_creds(context, creds, client, ccache,
3647c478bd9Sstevel@tonic-gate in_tkt_service, 1));
3657c478bd9Sstevel@tonic-gate }
3667c478bd9Sstevel@tonic-gate
367505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_get_renewed_creds(krb5_context context,krb5_creds * creds,krb5_principal client,krb5_ccache ccache,char * in_tkt_service)368505d05c7Sgtb krb5_get_renewed_creds(krb5_context context, krb5_creds *creds, krb5_principal client, krb5_ccache ccache, char *in_tkt_service)
3697c478bd9Sstevel@tonic-gate {
3707c478bd9Sstevel@tonic-gate return(krb5_validate_or_renew_creds(context, creds, client, ccache,
3717c478bd9Sstevel@tonic-gate in_tkt_service, 0));
3727c478bd9Sstevel@tonic-gate }
373