gc_frm_kdc.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 1994 by the Massachusetts Institute of Technology.
* Copyright (c) 1994 CyberSAFE Corporation
* Copyright (c) 1993 Open Computing Security Group
* Copyright (c) 1990,1991 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. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* Neither M.I.T., the Open Computing Security Group, nor
* CyberSAFE Corporation make any representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
* krb5_get_cred_from_kdc()
* Get credentials from some KDC somewhere, possibly accumulating tgts
* along the way.
*/
#include <k5-int.h>
#include <stdio.h>
#include "int-proto.h"
/*
* Retrieve credentials for principal in_cred->client,
* server in_cred->server, ticket flags creds->ticket_flags, possibly
* second_ticket if needed by ticket_flags.
*
* Credentials are requested from the KDC for the server's realm. Any
* TGT credentials obtained in the process of contacting the KDC are
* returned in an array of credentials; tgts is filled in to point to an
* array of pointers to credential structures (if no TGT's were used, the
* pointer is zeroed). TGT's may be returned even if no useful end ticket
* was obtained.
*
* The returned credentials are NOT cached.
*
* This routine should not be called if the credentials are already in
* the cache.
*
* If credentials are obtained, creds is filled in with the results;
* creds->ticket and creds->keyblock->key are set to allocated storage,
* which should be freed by the caller when finished.
*
* returns errors, system errors.
*/
/* helper macro: convert flags to necessary KDC options */
static krb5_error_code
krb5_creds ***tgts;
int kdcopt;
{
int ntgts = 0;
int nservers = 0;
/* in case we never get a TGT, zero the return */
/*
* we know that the desired credentials aren't in the cache yet.
*
* To get them, we first need a tgt for the realm of the server.
* first, we see if we have such a TGT in cache. if not, then
* we ask the kdc to give us one. if that doesn't work, then
* we try to get a tgt for a realm that is closest to the target.
* once we have that, then we ask that realm if it can give us
* tgt for the target. if not, we do the process over with this
* new tgt.
*/
/*
* (the ticket may be issued by some other intermediate
* realm's KDC; so we use KRB5_TC_MATCH_SRV_NAMEONLY)
*/
goto cleanup;
/* get target tgt from cache */
&int_server))) {
goto cleanup;
}
goto cleanup;
}
/* set endtime to now so krb5_cc_retrieve_cred won't return an expired tik */
goto cleanup;
}
goto cleanup;
}
/*
* Note that we want to request a TGT from our local KDC, even
* if we already have a TGT for some intermediate realm. The
* reason is that our local KDC may have a shortcut to the
* destination realm, and if it does we want to use the
* shortcut because it will provide greater security. - bcn
*/
/*
* didn't find it in the cache so it is time to get a local
* tgt and walk the realms tree.
*/
int_server = NULL;
&int_server))) {
goto cleanup;
}
goto cleanup;
goto cleanup;
goto cleanup;
}
goto cleanup;
}
/* get a list of realms to consult */
&tgs_list,
goto cleanup;
}
;
/* allocate storage for TGT pointers. */
goto cleanup;
}
/*
* step one is to take the current tgt and see if there is a tgt for
* the tgt.
*
* if we don't get a tgt for the target, then try to find a tgt as
* close to the target realm as possible. at each step if there isn't
* a tgt in the cache we have to try and get one with our latest tgt.
* once we have a tgt for a closer realm, we go back to step one.
*
* once we have a tgt for the target, we go try and get credentials.
*/
for (top_server = tgs_list;
top_server = next_server) {
/* look in cache for a tgt for the destination */
goto cleanup;
int_server = NULL;
&int_server))) {
goto cleanup;
}
goto cleanup;
goto cleanup;
}
goto cleanup;
}
/* didn't find it in the cache so try and get one */
/* with current tgt. */
goto cleanup;
}
#ifdef HAVE_C_STRUCTURE_ASSIGNMENT
#else
#endif
goto cleanup;
goto cleanup;
/*
* couldn't get one so now loop backwards through the realms
* list and try and get a tgt for a realm as close to the
* target as possible. the kdc should give us a tgt for the
* closest one it knows about, but not all kdc's do this yet.
*/
next_server--) {
goto cleanup;
int_server = NULL;
&int_server))) {
goto cleanup;
}
goto cleanup;
goto cleanup;
}
if (retval != KRB5_CC_NOTFOUND) {
goto cleanup;
}
/* not in the cache so try and get one with our current tgt. */
goto cleanup;
}
goto cleanup;
goto cleanup;
continue;
}
/* save tgt in return array */
goto cleanup;
}
}
/* got one as close as possible, now start all over */
break;
}
if (next_server == top_server) {
goto cleanup;
}
continue;
}
/*
* Got a tgt. If it is for the target realm we can go try for the
* credentials. If it is not for the target realm, then make sure it
* is in the realms hierarchy and if so, save it and start the loop
* over from there. Note that we only need to compare the instance
* names since that is the target realm of the tgt.
*/
break;
}
}
if (!next_server) {
goto cleanup;
}
goto cleanup;
}
/* we're done if it is the target */
if (!*next_server++) break;
}
}
}
goto cleanup;
}
kdcopt |
KDC_OPT_ENC_TKT_IN_SKEY : 0),
/* cleanup and return */
if (ntgts == 0) {
}
return(retval);
}
krb5_creds ***tgts;
{
0);
}
krb5_creds ***tgts;
{
}
krb5_creds ***tgts;
{
}