1*13132SGlenn.Barry@oracle.com /*
2*13132SGlenn.Barry@oracle.com * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3*13132SGlenn.Barry@oracle.com */
40Sstevel@tonic-gate /*
50Sstevel@tonic-gate * Copyright 2000 by the Massachusetts Institute of Technology.
60Sstevel@tonic-gate * All Rights Reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Export of this software from the United States of America may
90Sstevel@tonic-gate * require a specific license from the United States Government.
100Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
110Sstevel@tonic-gate * export to obtain such a license before exporting.
125053Sgtb *
130Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
140Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
150Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
160Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
170Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
180Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
190Sstevel@tonic-gate * to distribution of the software without specific, written prior
200Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
210Sstevel@tonic-gate * your software as modified software and not distribute it in such a
220Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
230Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
240Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
250Sstevel@tonic-gate * or implied warranty.
265053Sgtb *
270Sstevel@tonic-gate */
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC.
305053Sgtb *
310Sstevel@tonic-gate * All rights reserved.
325053Sgtb *
330Sstevel@tonic-gate * Export of this software from the United States of America may require
340Sstevel@tonic-gate * a specific license from the United States Government. It is the
350Sstevel@tonic-gate * responsibility of any person or organization contemplating export to
360Sstevel@tonic-gate * obtain such a license before exporting.
375053Sgtb *
380Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
390Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
400Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
410Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
420Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
430Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining
440Sstevel@tonic-gate * to distribution of the software without specific, written prior
450Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of
460Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
470Sstevel@tonic-gate * or implied warranty.
485053Sgtb *
490Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
500Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
510Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
520Sstevel@tonic-gate */
530Sstevel@tonic-gate
545053Sgtb #include "gssapiP_krb5.h"
550Sstevel@tonic-gate #ifdef HAVE_STRING_H
560Sstevel@tonic-gate #include <string.h>
570Sstevel@tonic-gate #else
580Sstevel@tonic-gate #include <strings.h>
590Sstevel@tonic-gate #endif
60*13132SGlenn.Barry@oracle.com #include <locale.h> /* Solaris Kerberos */
610Sstevel@tonic-gate
620Sstevel@tonic-gate /*
637934SMark.Phalan@Sun.COM * $Id: add_cred.c 18396 2006-07-25 20:29:43Z lxs $
640Sstevel@tonic-gate */
650Sstevel@tonic-gate
660Sstevel@tonic-gate /* V2 interface */
670Sstevel@tonic-gate OM_uint32
krb5_gss_add_cred(minor_status,input_cred_handle,desired_name,desired_mech,cred_usage,initiator_time_req,acceptor_time_req,output_cred_handle,actual_mechs,initiator_time_rec,acceptor_time_rec)685053Sgtb krb5_gss_add_cred(minor_status, input_cred_handle,
690Sstevel@tonic-gate desired_name, desired_mech, cred_usage,
700Sstevel@tonic-gate initiator_time_req, acceptor_time_req,
715053Sgtb output_cred_handle, actual_mechs,
720Sstevel@tonic-gate initiator_time_rec, acceptor_time_rec)
730Sstevel@tonic-gate OM_uint32 *minor_status;
740Sstevel@tonic-gate gss_cred_id_t input_cred_handle;
750Sstevel@tonic-gate gss_name_t desired_name;
760Sstevel@tonic-gate gss_OID desired_mech;
770Sstevel@tonic-gate gss_cred_usage_t cred_usage;
780Sstevel@tonic-gate OM_uint32 initiator_time_req;
790Sstevel@tonic-gate OM_uint32 acceptor_time_req;
800Sstevel@tonic-gate gss_cred_id_t *output_cred_handle;
810Sstevel@tonic-gate gss_OID_set *actual_mechs;
820Sstevel@tonic-gate OM_uint32 *initiator_time_rec;
830Sstevel@tonic-gate OM_uint32 *acceptor_time_rec;
840Sstevel@tonic-gate {
855053Sgtb krb5_context context;
865053Sgtb OM_uint32 major_status, lifetime;
870Sstevel@tonic-gate krb5_gss_cred_id_t cred;
880Sstevel@tonic-gate krb5_error_code code;
890Sstevel@tonic-gate
900Sstevel@tonic-gate /* this is pretty simple, since there's not really any difference
910Sstevel@tonic-gate between the underlying mechanisms. The main hair is in copying
920Sstevel@tonic-gate a mechanism if requested. */
930Sstevel@tonic-gate
940Sstevel@tonic-gate /* check if the desired_mech is bogus */
950Sstevel@tonic-gate
965053Sgtb if (!g_OID_equal(desired_mech, gss_mech_krb5) &&
970Sstevel@tonic-gate !g_OID_equal(desired_mech, gss_mech_krb5_old)) {
980Sstevel@tonic-gate *minor_status = 0;
990Sstevel@tonic-gate return(GSS_S_BAD_MECH);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate /* check if the desired_mech is bogus */
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate if ((cred_usage != GSS_C_INITIATE) &&
1050Sstevel@tonic-gate (cred_usage != GSS_C_ACCEPT) &&
1060Sstevel@tonic-gate (cred_usage != GSS_C_BOTH)) {
1070Sstevel@tonic-gate *minor_status = (OM_uint32) G_BAD_USAGE;
1080Sstevel@tonic-gate return(GSS_S_FAILURE);
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate /* since the default credential includes all the mechanisms,
1120Sstevel@tonic-gate return an error for that case. */
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate /*SUPPRESS 29*/
1150Sstevel@tonic-gate if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
1160Sstevel@tonic-gate *minor_status = 0;
1170Sstevel@tonic-gate return(GSS_S_DUPLICATE_ELEMENT);
1180Sstevel@tonic-gate }
1190Sstevel@tonic-gate
1205053Sgtb code = krb5_gss_init_context(&context);
1215053Sgtb if (code) {
1225053Sgtb *minor_status = code;
1235053Sgtb return GSS_S_FAILURE;
1245053Sgtb }
1250Sstevel@tonic-gate
1265053Sgtb major_status = krb5_gss_validate_cred_1(minor_status, input_cred_handle,
1275053Sgtb context);
1285053Sgtb if (GSS_ERROR(major_status)) {
129*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
1305053Sgtb krb5_free_context(context);
1315053Sgtb return major_status;
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate cred = (krb5_gss_cred_id_t) input_cred_handle;
1355053Sgtb k5_mutex_assert_locked(&cred->lock);
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate /* check if the cred_usage is equal or "less" than the passed-in cred
1380Sstevel@tonic-gate if copying */
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate if (!((cred->usage == cred_usage) ||
1410Sstevel@tonic-gate ((cred->usage == GSS_C_BOTH) &&
1420Sstevel@tonic-gate (output_cred_handle != NULL)))) {
1435053Sgtb *minor_status = (OM_uint32) G_BAD_USAGE;
1445053Sgtb krb5_free_context(context);
1455053Sgtb return(GSS_S_FAILURE);
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate /* check that desired_mech isn't already in the credential */
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) ||
1510Sstevel@tonic-gate (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
1520Sstevel@tonic-gate *minor_status = 0;
1535053Sgtb krb5_free_context(context);
1545053Sgtb return(GSS_S_DUPLICATE_ELEMENT);
1555053Sgtb }
1565053Sgtb
1575053Sgtb if (GSS_ERROR(kg_sync_ccache_name(context, minor_status))) {
158*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
1595053Sgtb krb5_free_context(context);
1605053Sgtb return GSS_S_FAILURE;
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate /* verify the desired_name */
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate /*SUPPRESS 29*/
1660Sstevel@tonic-gate if ((desired_name != (gss_name_t) NULL) &&
1670Sstevel@tonic-gate (! kg_validate_name(desired_name))) {
168*13132SGlenn.Barry@oracle.com *minor_status = (OM_uint32) G_VALIDATE_FAILED;
1695053Sgtb krb5_free_context(context);
1705053Sgtb return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate /* make sure the desired_name is the same as the existing one */
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate if (desired_name &&
1760Sstevel@tonic-gate !krb5_principal_compare(context, (krb5_principal) desired_name,
1770Sstevel@tonic-gate cred->princ)) {
178*13132SGlenn.Barry@oracle.com /* Solaris Kerberos: spruce-up the err msg */
179*13132SGlenn.Barry@oracle.com krb5_principal dname = (krb5_principal) desired_name;
180*13132SGlenn.Barry@oracle.com char *s_name = NULL, *s_princ= NULL;
181*13132SGlenn.Barry@oracle.com int kret = krb5_unparse_name(context, dname, &s_name);
182*13132SGlenn.Barry@oracle.com int kret1 = krb5_unparse_name(context, cred->princ, &s_princ);
183*13132SGlenn.Barry@oracle.com *minor_status = (OM_uint32) G_BAD_USAGE;
184*13132SGlenn.Barry@oracle.com if (kret == 0 && kret1 == 0) {
185*13132SGlenn.Barry@oracle.com krb5_set_error_message(context, *minor_status,
186*13132SGlenn.Barry@oracle.com dgettext(TEXT_DOMAIN,
187*13132SGlenn.Barry@oracle.com "Desired name principal '%s' does not match '%s'"),
188*13132SGlenn.Barry@oracle.com s_name, s_princ);
189*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
190*13132SGlenn.Barry@oracle.com }
191*13132SGlenn.Barry@oracle.com if (s_name)
192*13132SGlenn.Barry@oracle.com krb5_free_unparsed_name(context, s_name);
193*13132SGlenn.Barry@oracle.com if (s_princ)
194*13132SGlenn.Barry@oracle.com krb5_free_unparsed_name(context, s_princ);
195*13132SGlenn.Barry@oracle.com
1965053Sgtb krb5_free_context(context);
1975053Sgtb return(GSS_S_BAD_NAME);
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate /* copy the cred if necessary */
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate if (output_cred_handle) {
2030Sstevel@tonic-gate /* make a copy */
2040Sstevel@tonic-gate krb5_gss_cred_id_t new_cred;
2050Sstevel@tonic-gate char *kttype, ktboth[1024];
206781Sgtb const char *cctype, *ccname;
207781Sgtb char ccboth[1024];
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate if ((new_cred =
2100Sstevel@tonic-gate (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))
2110Sstevel@tonic-gate == NULL) {
2120Sstevel@tonic-gate *minor_status = ENOMEM;
2135053Sgtb krb5_free_context(context);
2145053Sgtb return(GSS_S_FAILURE);
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate memset(new_cred, 0, sizeof(krb5_gss_cred_id_rec));
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate new_cred->usage = cred_usage;
2190Sstevel@tonic-gate new_cred->prerfc_mech = cred->prerfc_mech;
2200Sstevel@tonic-gate new_cred->rfc_mech = cred->rfc_mech;
2210Sstevel@tonic-gate new_cred->tgt_expire = cred->tgt_expire;
2220Sstevel@tonic-gate
2235053Sgtb if (cred->princ)
2245053Sgtb code = krb5_copy_principal(context, cred->princ, &new_cred->princ);
2255053Sgtb if (code) {
2265053Sgtb xfree(new_cred);
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate *minor_status = code;
229*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
2305053Sgtb krb5_free_context(context);
2315053Sgtb return(GSS_S_FAILURE);
2320Sstevel@tonic-gate }
2335053Sgtb
2340Sstevel@tonic-gate if (cred->keytab) {
2350Sstevel@tonic-gate kttype = krb5_kt_get_type(context, cred->keytab);
2360Sstevel@tonic-gate if ((strlen(kttype)+2) > sizeof(ktboth)) {
2375053Sgtb if (new_cred->princ)
2385053Sgtb krb5_free_principal(context, new_cred->princ);
2395053Sgtb xfree(new_cred);
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate *minor_status = ENOMEM;
2425053Sgtb krb5_free_context(context);
2435053Sgtb return(GSS_S_FAILURE);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate strncpy(ktboth, kttype, sizeof(ktboth) - 1);
2470Sstevel@tonic-gate ktboth[sizeof(ktboth) - 1] = '\0';
2480Sstevel@tonic-gate strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
2490Sstevel@tonic-gate
2505053Sgtb code = krb5_kt_get_name(context, cred->keytab,
2515053Sgtb ktboth+strlen(ktboth),
2525053Sgtb sizeof(ktboth)-strlen(ktboth));
2530Sstevel@tonic-gate if (code) {
2545053Sgtb if(new_cred->princ)
2555053Sgtb krb5_free_principal(context, new_cred->princ);
2565053Sgtb xfree(new_cred);
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate *minor_status = code;
259*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
2605053Sgtb krb5_free_context(context);
2615053Sgtb return(GSS_S_FAILURE);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
2645053Sgtb code = krb5_kt_resolve(context, ktboth, &new_cred->keytab);
2655053Sgtb if (code) {
2665053Sgtb if (new_cred->princ)
2670Sstevel@tonic-gate krb5_free_principal(context, new_cred->princ);
2685053Sgtb xfree(new_cred);
2690Sstevel@tonic-gate
2700Sstevel@tonic-gate *minor_status = code;
271*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
2725053Sgtb krb5_free_context(context);
2735053Sgtb return(GSS_S_FAILURE);
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate } else {
2760Sstevel@tonic-gate new_cred->keytab = NULL;
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate
2790Sstevel@tonic-gate if (cred->rcache) {
2800Sstevel@tonic-gate /* Open the replay cache for this principal. */
2810Sstevel@tonic-gate if ((code = krb5_get_server_rcache(context,
2820Sstevel@tonic-gate krb5_princ_component(context, cred->princ, 0),
2830Sstevel@tonic-gate &new_cred->rcache))) {
2840Sstevel@tonic-gate if (new_cred->keytab)
2850Sstevel@tonic-gate krb5_kt_close(context, new_cred->keytab);
2865053Sgtb if (new_cred->princ)
2875053Sgtb krb5_free_principal(context, new_cred->princ);
2885053Sgtb xfree(new_cred);
2890Sstevel@tonic-gate
290*13132SGlenn.Barry@oracle.com *minor_status = code;
291*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
2925053Sgtb krb5_free_context(context);
2935053Sgtb return(GSS_S_FAILURE);
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate } else {
2960Sstevel@tonic-gate new_cred->rcache = NULL;
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
2990Sstevel@tonic-gate if (cred->ccache) {
3000Sstevel@tonic-gate cctype = krb5_cc_get_type(context, cred->ccache);
3010Sstevel@tonic-gate ccname = krb5_cc_get_name(context, cred->ccache);
3020Sstevel@tonic-gate
3030Sstevel@tonic-gate if ((strlen(cctype)+strlen(ccname)+2) > sizeof(ccboth)) {
3040Sstevel@tonic-gate if (new_cred->rcache)
3050Sstevel@tonic-gate krb5_rc_close(context, new_cred->rcache);
3060Sstevel@tonic-gate if (new_cred->keytab)
3070Sstevel@tonic-gate krb5_kt_close(context, new_cred->keytab);
3085053Sgtb if (new_cred->princ)
3090Sstevel@tonic-gate krb5_free_principal(context, new_cred->princ);
3105053Sgtb xfree(new_cred);
3110Sstevel@tonic-gate
3125053Sgtb krb5_free_context(context);
3130Sstevel@tonic-gate *minor_status = ENOMEM;
3145053Sgtb return(GSS_S_FAILURE);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate strncpy(ccboth, cctype, sizeof(ccboth) - 1);
3180Sstevel@tonic-gate ccboth[sizeof(ccboth) - 1] = '\0';
3190Sstevel@tonic-gate strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
3200Sstevel@tonic-gate strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
3210Sstevel@tonic-gate
3225053Sgtb code = krb5_cc_resolve(context, ccboth, &new_cred->ccache);
3235053Sgtb if (code) {
3240Sstevel@tonic-gate if (new_cred->rcache)
3250Sstevel@tonic-gate krb5_rc_close(context, new_cred->rcache);
3260Sstevel@tonic-gate if (new_cred->keytab)
3270Sstevel@tonic-gate krb5_kt_close(context, new_cred->keytab);
3285053Sgtb if (new_cred->princ)
3295053Sgtb krb5_free_principal(context, new_cred->princ);
3305053Sgtb xfree(new_cred);
331*13132SGlenn.Barry@oracle.com *minor_status = code;
332*13132SGlenn.Barry@oracle.com save_error_info(*minor_status, context);
3335053Sgtb krb5_free_context(context);
3345053Sgtb return(GSS_S_FAILURE);
3350Sstevel@tonic-gate }
3360Sstevel@tonic-gate } else {
3370Sstevel@tonic-gate new_cred->ccache = NULL;
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate /* intern the credential handle */
3410Sstevel@tonic-gate
3420Sstevel@tonic-gate if (! kg_save_cred_id((gss_cred_id_t) new_cred)) {
3430Sstevel@tonic-gate if (new_cred->ccache)
3440Sstevel@tonic-gate krb5_cc_close(context, new_cred->ccache);
3450Sstevel@tonic-gate if (new_cred->rcache)
3460Sstevel@tonic-gate krb5_rc_close(context, new_cred->rcache);
3470Sstevel@tonic-gate if (new_cred->keytab)
3480Sstevel@tonic-gate krb5_kt_close(context, new_cred->keytab);
3495053Sgtb if (new_cred->princ)
3500Sstevel@tonic-gate krb5_free_principal(context, new_cred->princ);
3515053Sgtb xfree(new_cred);
3525053Sgtb krb5_free_context(context);
3530Sstevel@tonic-gate
3540Sstevel@tonic-gate *minor_status = (OM_uint32) G_VALIDATE_FAILED;
3555053Sgtb return(GSS_S_FAILURE);
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate /* modify new_cred */
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate cred = new_cred;
3610Sstevel@tonic-gate }
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate /* set the flag for the new mechanism */
3640Sstevel@tonic-gate
3650Sstevel@tonic-gate if (g_OID_equal(desired_mech, gss_mech_krb5_old))
3660Sstevel@tonic-gate cred->prerfc_mech = 1;
3670Sstevel@tonic-gate else if (g_OID_equal(desired_mech, gss_mech_krb5))
3680Sstevel@tonic-gate cred->rfc_mech = 1;
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /* set the outputs */
3710Sstevel@tonic-gate
3725053Sgtb if (GSS_ERROR(major_status = krb5_gss_inquire_cred(minor_status,
3737934SMark.Phalan@Sun.COM (gss_cred_id_t)cred,
3745053Sgtb NULL, &lifetime,
3755053Sgtb NULL, actual_mechs))) {
3760Sstevel@tonic-gate OM_uint32 dummy;
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate if (output_cred_handle)
3795053Sgtb (void) krb5_gss_release_cred(&dummy, (gss_cred_id_t *) &cred);
3805053Sgtb krb5_free_context(context);
3810Sstevel@tonic-gate
3825053Sgtb return(major_status);
3830Sstevel@tonic-gate }
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate if (initiator_time_rec)
3860Sstevel@tonic-gate *initiator_time_rec = lifetime;
3870Sstevel@tonic-gate if (acceptor_time_rec)
3880Sstevel@tonic-gate *acceptor_time_rec = lifetime;
3890Sstevel@tonic-gate
3900Sstevel@tonic-gate if (output_cred_handle)
3917934SMark.Phalan@Sun.COM *output_cred_handle = (gss_cred_id_t)cred;
3920Sstevel@tonic-gate
3935053Sgtb krb5_free_context(context);
3945053Sgtb *minor_status = 0;
3955053Sgtb return(GSS_S_COMPLETE);
3960Sstevel@tonic-gate }
397