2 * lib/krb5/krb/gc_2tgt.c
4 * Copyright 1991 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * Given two tgts, get a ticket.
28 #include "int-proto.h"
30 krb5_error_code INTERFACE
31 krb5_get_cred_via_2tgt (context, tgt, kdcoptions, sumtype, in_cred, out_cred)
34 const krb5_flags kdcoptions;
35 const krb5_cksumtype sumtype;
37 krb5_creds ** out_cred;
39 krb5_error_code retval;
41 krb5_principal tempprinc;
44 krb5_kdc_rep *dec_rep;
45 krb5_error *err_reply;
49 /* tgt->client must be equal to in_cred->client */
50 /* tgt->server must be equal to krbtgt/realmof(cred->client) */
51 if (!krb5_principal_compare(context, tgt->client, in_cred->client))
52 return KRB5_PRINC_NOMATCH;
54 if (!tgt->ticket.length)
55 return(KRB5_NO_TKT_SUPPLIED);
57 if (!in_cred->second_ticket.length)
58 return(KRB5_NO_2ND_TKT);
60 #if 0 /* What does this do? */
61 if (retval = krb5_tgtname(context, krb5_princ_realm(in_cred->server),
62 krb5_princ_realm(context, in_cred->client), &tempprinc))
65 if (!krb5_principal_compare(context, tempprinc, tgt->server)) {
66 krb5_free_principal(context, tempprinc);
67 return KRB5_PRINC_NOMATCH;
69 krb5_free_principal(context, tempprinc);
72 if (!(kdcoptions & KDC_OPT_ENC_TKT_IN_SKEY))
73 return KRB5_INVALID_FLAGS;
75 if (retval = krb5_send_tgs(context, kdcoptions, &in_cred->times, NULL,
76 sumtype, in_cred->server, tgt->addresses,
79 &in_cred->second_ticket, tgt, &tgsrep))
82 if (tgsrep.message_type != KRB5_TGS_REP)
84 if (!krb5_is_krb_error(&tgsrep.response)) {
85 free(tgsrep.response.data);
86 return KRB5KRB_AP_ERR_MSG_TYPE;
88 retval = decode_krb5_error(&tgsrep.response, &err_reply);
90 free(tgsrep.response.data);
93 retval = err_reply->error + ERROR_TABLE_BASE_krb5;
95 krb5_free_error(context, err_reply);
96 free(tgsrep.response.data);
99 etype = tgt->keyblock.etype;
100 retval = krb5_decode_kdc_rep(context, &tgsrep.response, &tgt->keyblock,
102 free(tgsrep.response.data);
106 if (dec_rep->msg_type != KRB5_TGS_REP) {
107 retval = KRB5KRB_AP_ERR_MSG_TYPE;
111 /* now it's decrypted and ready for prime time */
113 if (!krb5_principal_compare(context, dec_rep->client, tgt->client)) {
114 retval = KRB5_KDCREP_MODIFIED;
119 * get a cred structure
120 * The caller is responsible for cleaning up
122 if (((*out_cred) = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL) {
127 /* Copy the client straig from in_cred */
128 if (retval = krb5_copy_principal(context, in_cred->client,
129 &(*out_cred)->client)) {
133 /* put pieces into out_cred-> */
134 (*out_cred)->keyblock.magic = KV5M_KEYBLOCK;
135 (*out_cred)->keyblock.etype = dec_rep->ticket->enc_part.etype;
136 if (retval = krb5_copy_keyblock_contents(context,
137 dec_rep->enc_part2->session,
138 &(*out_cred)->keyblock))
141 /* Should verify that the ticket is what we asked for. */
142 (*out_cred)->times = dec_rep->enc_part2->times;
143 (*out_cred)->ticket_flags = dec_rep->enc_part2->flags;
144 (*out_cred)->is_skey = TRUE;
145 if (dec_rep->enc_part2->caddrs)
146 retval = krb5_copy_addresses(context, dec_rep->enc_part2->caddrs,
147 &(*out_cred)->addresses);
149 /* no addresses in the list means we got what we had */
150 retval = krb5_copy_addresses(context, tgt->addresses, &(*out_cred)->addresses);
154 if (retval = krb5_copy_principal(context, dec_rep->enc_part2->server,
155 &(*out_cred)->server))
158 if (retval = encode_krb5_ticket(dec_rep->ticket, &scratch))
161 (*out_cred)->ticket = *scratch;
167 if ((*out_cred)->keyblock.contents) {
168 memset((*out_cred)->keyblock.contents, 0,
169 (*out_cred)->keyblock.length);
170 krb5_xfree((*out_cred)->keyblock.contents);
171 (*out_cred)->keyblock.contents = 0;
173 if ((*out_cred)->addresses) {
174 krb5_free_addresses(context, (*out_cred)->addresses);
175 (*out_cred)->addresses = 0;
177 if ((*out_cred)->server) {
178 krb5_free_principal(context, (*out_cred)->server);
179 (*out_cred)->server = 0;
181 krb5_free_creds(context, *out_cred);
184 memset((char *)dec_rep->enc_part2->session->contents, 0,
185 dec_rep->enc_part2->session->length);
186 krb5_free_kdc_rep(context, dec_rep);
193 * eval: (make-local-variable (quote c-indent-level))
194 * eval: (make-local-variable (quote c-continued-statement-offset))
195 * eval: (setq c-indent-level 4 c-continued-statement-offset 4)