--- /dev/null
+/*
+ * lib/krb5/krb/get_in_tkt.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include "k5-int.h"
+#include <memory.h>
+#include <netdb.h>
+
+/* helper function: convert flags to necessary KDC options */
+#define flags2options(flags) (flags & KDC_TKT_COMMON_MASK)
+
+/* Get a TGT for use at the remote host */
+krb5_error_code
+krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
+ forwardable, outbuf)
+ krb5_context context;
+ krb5_auth_context auth_context;
+ char *rhost;
+ krb5_principal client;
+ krb5_principal server;
+ krb5_ccache cc;
+ int forwardable; /* Should forwarded TGT also be forwardable? */
+ krb5_data *outbuf;
+{
+ krb5_replay_data replaydata;
+ krb5_data * scratch;
+ krb5_address **addrs;
+ krb5_error_code retval;
+ krb5_creds creds, tgt;
+ krb5_creds *pcreds;
+ krb5_flags kdcoptions;
+ int close_cc = 0;
+ int free_rhost = 0;
+
+ memset((char *)&creds, 0, sizeof(creds));
+ memset((char *)&tgt, 0, sizeof(creds));
+
+ if (rhost == NULL) {
+ if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST)
+ return(KRB5_FWD_BAD_PRINCIPAL);
+
+ if (krb5_princ_size(context, server) < 2)
+ return (KRB5_CC_BADNAME);
+
+ rhost = malloc(server->data[1].length+1);
+ if (!rhost)
+ return ENOMEM;
+ free_rhost = 1;
+ memcpy(rhost, server->data[1].data, server->data[1].length);
+ rhost[server->data[1].length] = '\0';
+ }
+
+ retval = krb5_os_hostaddr(context, rhost, &addrs);
+ if (retval)
+ goto errout;
+
+ if ((retval = krb5_copy_principal(context, client, &creds.client)))
+ goto errout;
+
+ if ((retval = krb5_build_principal_ext(context, &creds.server,
+ server->realm.length,
+ server->realm.data,
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME,
+ client->realm.length,
+ client->realm.data,
+ 0)))
+ goto errout;
+
+ if (cc == 0) {
+ if ((retval = krb5_cc_default(context, &cc)))
+ goto errout;
+ close_cc = 1;
+ }
+
+ /* fetch tgt directly from cache */
+ retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_MATCH_SRV_NAMEONLY,
+ &creds, &tgt);
+ if (retval)
+ goto errout;
+
+ /* tgt->client must be equal to creds.client */
+ if (!krb5_principal_compare(context, tgt.client, creds.client)) {
+ retval = KRB5_PRINC_NOMATCH;
+ goto errout;
+ }
+
+ if (!tgt.ticket.length) {
+ retval = KRB5_NO_TKT_SUPPLIED;
+ goto errout;
+ }
+
+ creds.times = tgt.times;
+ creds.times.starttime = 0;
+ kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED;
+
+ if (!forwardable) /* Reset KDC_OPT_FORWARDABLE */
+ kdcoptions &= ~(KDC_OPT_FORWARDABLE);
+
+ if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
+ addrs, &creds, &pcreds)))
+ goto errout;
+
+ retval = krb5_mk_1cred(context, auth_context, pcreds,
+ &scratch, &replaydata);
+ krb5_free_creds(context, pcreds);
+
+ if (retval) {
+ krb5_free_data(context, scratch);
+ } else {
+ *outbuf = *scratch;
+ krb5_xfree(scratch);
+ }
+
+errout:
+ if (addrs)
+ krb5_free_addresses(context, addrs);
+ if (close_cc)
+ krb5_cc_close(context, cc);
+ if (free_rhost)
+ free(rhost);
+ krb5_free_cred_contents(context, &creds);
+ krb5_free_cred_contents(context, &tgt);
+ return retval;
+}
+
+
+
{
krb5_cred_enc_part credenc;
krb5_error_code retval;
- char * tmp;
int i;
credenc.magic = KV5M_CRED_ENC_PART;
malloc((size_t) (sizeof(krb5_cred_info *) * (nppcreds + 1)))) == NULL) {
return ENOMEM;
}
- if ((tmp = (char *)malloc((size_t) (sizeof(krb5_cred_info) * nppcreds))) == NULL) {
- retval = ENOMEM;
- goto cleanup_info;
- }
- memset(tmp, 0, (size_t) (sizeof(krb5_cred_info) * nppcreds));
-
+ memset(credenc.ticket_info, 0, sizeof(krb5_cred_info *) * (nppcreds + 1));
+
/*
* For each credential in the list, initialize a cred info
* structure and copy the ticket into the ticket list.
*/
for (i = 0; i < nppcreds; i++) {
- credenc.ticket_info[i] = (krb5_cred_info *)tmp + i;
-
+ credenc.ticket_info[i] = malloc(sizeof(krb5_cred_info));
+ if (credenc.ticket_info[i] == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ credenc.ticket_info[i+1] = NULL;
+
credenc.ticket_info[i]->magic = KV5M_CRED_INFO;
credenc.ticket_info[i]->times = ppcreds[i]->times;
credenc.ticket_info[i]->flags = ppcreds[i]->ticket_flags;
if ((retval = decode_krb5_ticket(&ppcreds[i]->ticket,
&pcred->tickets[i])))
- goto cleanup_info_ptrs;
+ goto cleanup;
if ((retval = krb5_copy_keyblock(context, &ppcreds[i]->keyblock,
&credenc.ticket_info[i]->session)))
- goto cleanup_info_ptrs;
+ goto cleanup;
if ((retval = krb5_copy_principal(context, ppcreds[i]->client,
&credenc.ticket_info[i]->client)))
- goto cleanup_info_ptrs;
+ goto cleanup;
if ((retval = krb5_copy_principal(context, ppcreds[i]->server,
&credenc.ticket_info[i]->server)))
- goto cleanup_info_ptrs;
+ goto cleanup;
if ((retval = krb5_copy_addresses(context, ppcreds[i]->addresses,
&credenc.ticket_info[i]->caddrs)))
- goto cleanup_info_ptrs;
+ goto cleanup;
}
/*
* NULL terminate the lists.
*/
- credenc.ticket_info[i] = NULL;
pcred->tickets[i] = NULL;
/* encrypt the credential encrypted part */
retval = encrypt_credencpart(context, &credenc, keyblock,
&pcred->enc_part);
-cleanup_info_ptrs:
- free(tmp);
-
-cleanup_info:
- free(credenc.ticket_info);
+cleanup:
+ krb5_free_cred_enc_part(context, &credenc);
return retval;
}
krb5_data ** ppdata;
krb5_replay_data * outdata;
{
+ krb5_address * premote_fulladdr = NULL;
+ krb5_address * plocal_fulladdr = NULL;
+ krb5_address remote_fulladdr;
+ krb5_address local_fulladdr;
krb5_error_code retval;
krb5_keyblock * keyblock;
krb5_replay_data replaydata;
krb5_cred * pcred;
int ncred;
+ local_fulladdr.contents = 0;
+ remote_fulladdr.contents = 0;
+ memset(&replaydata, 0, sizeof(krb5_replay_data));
+
if (ppcreds == NULL) {
return KRB5KRB_AP_ERR_BADADDR;
}
if ((pcred = (krb5_cred *)malloc(sizeof(krb5_cred))) == NULL)
return ENOMEM;
+ memset(pcred, 0, sizeof(krb5_cred));
if ((pcred->tickets
= (krb5_ticket **)malloc(sizeof(krb5_ticket *) * (ncred + 1))) == NULL) {
retval = ENOMEM;
free(pcred);
}
+ memset(pcred->tickets, 0, sizeof(krb5_ticket *) * (ncred +1));
/* Get keyblock */
if ((keyblock = auth_context->local_subkey) == NULL)
/* Need a better error */
return KRB5_RC_REQUIRED;
- if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) ||
- (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) {
- if ((retval = krb5_us_timeofday(context, &replaydata.timestamp,
- &replaydata.usec)))
- return retval;
- if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
- outdata->timestamp = replaydata.timestamp;
- outdata->usec = replaydata.usec;
- }
- if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
- outdata->timestamp = replaydata.timestamp;
- outdata->usec = replaydata.usec;
- }
+ if ((retval = krb5_us_timeofday(context, &replaydata.timestamp,
+ &replaydata.usec)))
+ return retval;
+ if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
+ outdata->timestamp = replaydata.timestamp;
+ outdata->usec = replaydata.usec;
}
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
(auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) {
}
}
-{
- krb5_address * premote_fulladdr = NULL;
- krb5_address * plocal_fulladdr = NULL;
- krb5_address remote_fulladdr;
- krb5_address local_fulladdr;
- CLEANUP_INIT(2);
-
if (auth_context->local_addr) {
if (auth_context->local_port) {
- if (!(retval = krb5_make_fulladdr(context, auth_context->local_addr,
- auth_context->local_port,
- &local_fulladdr))) {
- CLEANUP_PUSH(local_fulladdr.contents, free);
- plocal_fulladdr = &local_fulladdr;
- } else {
- goto error;
- }
+ if ((retval = krb5_make_fulladdr(context, auth_context->local_addr,
+ auth_context->local_port,
+ &local_fulladdr)))
+ goto error;
+ plocal_fulladdr = &local_fulladdr;
} else {
plocal_fulladdr = auth_context->local_addr;
}
if (auth_context->remote_addr) {
if (auth_context->remote_port) {
- if (!(retval = krb5_make_fulladdr(context,auth_context->remote_addr,
+ if ((retval = krb5_make_fulladdr(context,auth_context->remote_addr,
auth_context->remote_port,
- &remote_fulladdr))){
- CLEANUP_PUSH(remote_fulladdr.contents, free);
- premote_fulladdr = &remote_fulladdr;
- } else {
- CLEANUP_DONE();
- goto error;
- }
+ &remote_fulladdr)))
+ goto error;
+ premote_fulladdr = &remote_fulladdr;
} else {
premote_fulladdr = auth_context->remote_addr;
}
if ((retval = krb5_mk_ncred_basic(context, ppcreds, ncred, keyblock,
&replaydata, plocal_fulladdr,
premote_fulladdr, pcred))) {
- CLEANUP_DONE();
goto error;
}
- CLEANUP_DONE();
-}
-
if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
krb5_donot_replay replay;
retval = encode_krb5_cred(pcred, ppdata);
error:
+ if (local_fulladdr.contents)
+ free(local_fulladdr.contents);
+ if (remote_fulladdr.contents)
+ free(remote_fulladdr.contents);
+ krb5_free_cred(context, pcred);
+
if (retval) {
if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
|| (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
auth_context->local_seq_number--;
- free(pcred->tickets);
- free(pcred);
}
return retval;
}
ppcreds[0] = pcreds;
ppcreds[1] = NULL;
- if ((retval = krb5_mk_ncred(context, auth_context, ppcreds,
- ppdata, outdata)))
- free(ppcreds);
+ retval = krb5_mk_ncred(context, auth_context, ppcreds,
+ ppdata, outdata);
+
+ free(ppcreds);
return retval;
}