Esempio n. 1
0
/* Get a TGT for use at the remote host */
krb5_error_code KRB5_CALLCONV
krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, char *rhost, krb5_principal client, krb5_principal server, krb5_ccache cc, int forwardable, krb5_data *outbuf)
                         
                                   
                
                          
                          
                   
                          /* Should forwarded TGT also be forwardable? */
                      
{
    krb5_replay_data replaydata;
    krb5_data * scratch = 0;
    krb5_address **addrs = NULL;
    krb5_error_code retval;
    krb5_creds creds, tgt;
    krb5_creds *pcreds;
    krb5_flags kdcoptions;
    int close_cc = 0;
    int free_rhost = 0;
    krb5_enctype enctype = 0;
    krb5_keyblock *session_key;
    krb5_boolean old_use_conf_ktypes = context->use_conf_ktypes;

    memset((char *)&creds, 0, sizeof(creds));
    memset((char *)&tgt, 0, sizeof(creds));

    if (cc == 0) {
      if ((retval = krb5int_cc_default(context, &cc)))
	goto errout;
      close_cc = 1;
    }
    retval = krb5_auth_con_getkey (context, auth_context, &session_key);
    if (retval)
      goto errout;
    if (session_key) {
	enctype = session_key->enctype;
	krb5_free_keyblock (context, session_key);
	session_key = NULL;
    } else if (server) { /* must server be non-NULL when rhost is given? */
	/* Try getting credentials to see what the remote side supports.
	   Not bulletproof, just a heuristic.  */
	krb5_creds in, *out = 0;
	memset (&in, 0, sizeof(in));

	retval = krb5_copy_principal (context, server, &in.server);
	if (retval)
	    goto punt;
	retval = krb5_copy_principal (context, client, &in.client);
	if (retval)
	    goto punt;
	retval = krb5_get_credentials (context, 0, cc, &in, &out);
	if (retval)
	    goto punt;
	/* Got the credentials.  Okay, now record the enctype and
	   throw them away.  */
	enctype = out->keyblock.enctype;
	krb5_free_creds (context, out);
    punt:
	krb5_free_cred_contents (context, &in);
    }

    if ((retval = krb5_copy_principal(context, client, &creds.client)))
	goto errout;
    
    if ((retval = krb5_build_principal_ext(context, &creds.server,
					   client->realm.length,
					   client->realm.data,
					   KRB5_TGS_NAME_SIZE,
					   KRB5_TGS_NAME,
					   client->realm.length,
					   client->realm.data,
					   0)))
	goto errout;
	
    /* fetch tgt directly from cache */
    context->use_conf_ktypes = 1;
    retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_SUPPORTED_KTYPES,
				    &creds, &tgt);
    context->use_conf_ktypes = old_use_conf_ktypes;
    if (retval)
	goto errout;

    /* tgt->client must be equal to creds.client */
    if (!krb5_principal_compare(context, tgt.client, creds.client)) {	
        /* Solaris Kerberos */
        char *r_name = NULL;
	char *t_name = NULL;
	krb5_error_code r_err, t_err;
	t_err = krb5_unparse_name(context, tgt.client, &t_name);
	r_err = krb5_unparse_name(context, creds.client, &r_name);
	krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
			    dgettext(TEXT_DOMAIN,
				    "Requested principal and ticket don't match:  Requested principal is '%s' and TGT principal is '%s'"),
			    r_err ? "unknown" : r_name,
			    t_err ? "unknown" : t_name);
	if (r_name)
	    krb5_free_unparsed_name(context, r_name);
	if (t_name)
	    krb5_free_unparsed_name(context, t_name);
	retval = KRB5_PRINC_NOMATCH;
	goto errout;
    }

    if (!tgt.ticket.length) {
	retval = KRB5_NO_TKT_SUPPLIED;
	goto errout;
    }
    
    if (tgt.addresses && *tgt.addresses) {
      if (rhost == NULL) {
	if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST) {
retval = KRB5_FWD_BAD_PRINCIPAL;
 goto errout;
	}

	if (krb5_princ_size(context, server) < 2){
	  retval = KRB5_CC_BADNAME;
	  goto errout;
	}
	
	rhost = malloc(server->data[1].length+1);
	if (!rhost) {
	  retval = ENOMEM;
	  goto errout;
	}
	free_rhost = 1;
	/* Solaris Kerberos */
	(void) 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;
    }
    
    creds.keyblock.enctype = enctype;
    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))) {
	if (enctype) {
	    creds.keyblock.enctype = 0;
	    if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
						addrs, &creds, &pcreds))) 
		goto errout;
	}
	else goto errout;
    }
    retval = krb5_mk_1cred(context, auth_context, pcreds,
                           &scratch, &replaydata);
    krb5_free_creds(context, pcreds);

    /*
     * Solaris Kerberos: changed this logic from the MIT 1.2.1 version to be
     * more robust.
     */
    if (scratch) {
	if (retval)
	    krb5_free_data(context, scratch);
	else {                                 
	    *outbuf = *scratch;
	    krb5_xfree(scratch);
	}                      
    }
        
errout:
    if (addrs)
	krb5_free_addresses(context, addrs);
    /* Solaris Kerberos */
    if (close_cc)
	(void) krb5_cc_close(context, cc);
    if (free_rhost)
	free(rhost);
    krb5_free_cred_contents(context, &creds);
    krb5_free_cred_contents(context, &tgt);
    return retval;
}
Esempio n. 2
0
/**
 * @brief
 * 		Get a TGT for use at the remote host.
 *
 * @param[in]	context	-	The Kerberos context.
 * @param[in]	auth_context	- Authentication context
 * @param[in]	client	-	Principal to be copied
 * @param[in]	server	-	Server of type krb5_principal
 * @param[in]	cc	-	Credential cache handle
 * @param[out]	outbuf	-	Replay cache data (NULL if not needed)
 *
 * @return	krb5_error_code
 * @retval	0	- success
 * @retval	!=0	- failure
 */
static
krb5_error_code
fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context, krb5_principal client, krb5_principal server, krb5_ccache cc, krb5_data outbuf)
{
	krb5_replay_data	replaydata;
	krb5_data		*scratch = 0;
	krb5_address		**addrs = 0;
	krb5_flags		kdcoptions;
	krb5_error_code		retval;
	krb5_creds		creds, tgt;
	krb5_creds		*pcreds;
	int			free_rhost = 0;
	char			*rhost;

	memset((char *)&creds, 0, sizeof(creds));
	memset((char *)&tgt, 0, sizeof(creds));

	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,
		client->realm.length,
		client->realm.data,
		KRB5_TGS_NAME_SIZE,
		KRB5_TGS_NAME,
		client->realm.length,
		client->realm.data,
		0)))
		goto errout;

	/* fetch tgt directly from cache */
	retval = 	krb5_cc_retrieve_cred(context, cc, KRB5_TC_SUPPORTED_KTYPES,
		&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;
	}

	kdcoptions = flags2options(tgt.ticket_flags)|
		KDC_OPT_FORWARDED;

	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) {
		if (scratch)
			krb5_free_data(context, scratch);
	}
	else {
		*outbuf = *scratch;
		free(scratch);
	}

errout:
	if (addrs)
		krb5_free_addresses(context, addrs);
	if (free_rhost)
		free(rhost);
	krb5_free_cred_contents(context, &creds);
	krb5_free_cred_contents(context, &tgt);

	return retval;
}
Esempio n. 3
0
int
auks_krb5_cred_get_fwd(char *ccachefilename, char *serverName,
		       char **p_buffer,
		       size_t * p_buffer_length)
{

	int fstatus = AUKS_ERROR ;

	/* kerberos related variables */
	krb5_error_code err_code;
	krb5_context context;
	krb5_ccache ccache;
	krb5_principal principal;
	krb5_creds **out_creds_array = NULL;
	krb5_auth_context auth_context;
	krb5_flags authopts;
	krb5_data outbuf;
	krb5_data *p_outbuf;
	krb5_replay_data krdata;

	authopts = AP_OPTS_MUTUAL_REQUIRED;
	authopts &= (~OPTS_FORWARD_CREDS);
	authopts &= (~OPTS_FORWARDABLE_CREDS);

	if ( serverName == NULL ) {
		auks_error("no host specified");
		fstatus = AUKS_ERROR_KRB5_CRED_NO_HOST_SPECIFIED ;
		goto exit;
	}

	/* initialize kerberos context */
	err_code = krb5_init_context(&context);
	if (err_code) {
		auks_error("unable to initialize kerberos context : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_CTX ;
		goto exit;
	}
	auks_log("kerberos context successfully initialized");

	/* initialize kerberos credential cache structure */
	if (ccachefilename == NULL)
		err_code = krb5_cc_default(context, &ccache);
	else
		err_code = krb5_cc_resolve(context,ccachefilename,&ccache);
	if (err_code) {
		auks_error("unable to resolve credential cache : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_OPEN_CC ;
		goto ctx_exit ;
	}
	auks_log("credential cache successfully resolved");

	/* get principal using credential cache */
	err_code = krb5_cc_get_principal(context,ccache,&principal);
	if (err_code) {
		auks_error("unable to get principal from credential cache : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_GET_PRINC ;
		goto cc_exit ;
	}
	auks_log("principal successfully extracted from credential cache");

	/* initialize kerberos authentication context */
	err_code = krb5_auth_con_init(context,&auth_context);
	if (err_code) {
		auks_error("unable to initialize kerberos authentication "
			   "context : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto princ_exit;
	}
	auks_log("kerberos authentication context successfully initialized");

	/* do replay detection using timestamps */
	krb5_auth_con_setflags(context,auth_context,KRB5_AUTH_CONTEXT_RET_TIME);

	/* get forwarded credential for server */
	err_code = krb5_fwd_tgt_creds(context,auth_context,serverName,
				      principal,NULL,NULL,authopts,&outbuf);
	if (err_code) {
		auks_error("unable to get serialized and crypted forwarded "
			   "credential for %s from KDC : %s",
			   serverName,error_message(err_code));
		fstatus =  AUKS_ERROR_KRB5_CRED_GET_FWD_CRED ;
		goto auth_ctx_exit;
	}
	auks_log("serialized and crypted forwarded credential for %s "
		 "successfully got from KDC",serverName);

	/* desactive replay detection */
	krb5_auth_con_setflags(context,auth_context,0);

	/* decrypt (using session key stored in auth context) and */
	/* unserialized forwarded credential in a kerberos credential */
	/* structure */
	err_code = krb5_rd_cred(context,auth_context,&outbuf,&out_creds_array,
				&krdata);
	if (err_code) {
		auks_error("unable to unserialize and decrypt forwarded "
			   "credential for %s : %s",serverName,
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_RD_CRED ;
		goto fwd_exit;
	}
	auks_log("unserialization and decryption of forwarded "
		 "credential for %s succesfully done",serverName);

	/* Reinitialize kerberos authentication context in order to */
	/* write credential to output buffer */
	krb5_auth_con_free(context,auth_context);
	err_code = krb5_auth_con_init(context,&auth_context);
	if (err_code) {
		auks_error("unable to reinitialize kerberos connection "
			   "authentication context : %s",error_message
			   (err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto rd_cred_exit;
	}
	auks_log("kerberos connection authentication context "
		 "reinitialization successfully done");

	/* no flags */
	krb5_auth_con_setflags(context,auth_context,0);

	/* serialize forwarded credential (no encryption because auth */
	/* context session key is nullified) */
	err_code = krb5_mk_1cred(context,auth_context,*out_creds_array,
				 &p_outbuf,&krdata);
	if (err_code) {
		auks_error("unable to serialize forwarded credential for "
			   "%s : %s",serverName,error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_MK_CRED ;
		goto rd_cred_exit;
	}
	auks_log("forwarded credential for %s successfully serialized",
		 serverName);

	/* allocate output buffer and store serialized credential */
	(*p_buffer) = (char *) malloc(p_outbuf->length * sizeof(char));
	if ((*p_buffer) == NULL) {
		auks_error("unable to allocate serialized credential output "
			   "buffer for %s",serverName);
		*p_buffer_length = 0 ;
		fstatus = AUKS_ERROR_KRB5_CRED_MALLOC ;
	} else {
		/* copy data */
		memcpy(*p_buffer,p_outbuf->data,p_outbuf->length);
		*p_buffer_length = p_outbuf->length;
		auks_log("forwarded credential successfully stored "
			 "in output buffer");
		fstatus	= AUKS_SUCCESS ;
	}

	krb5_free_data(context,p_outbuf);

rd_cred_exit:
	krb5_free_creds(context,*out_creds_array);
	free(out_creds_array);

fwd_exit:
	krb5_free_data_contents(context, &outbuf);

auth_ctx_exit:
	krb5_auth_con_free(context,auth_context);

princ_exit:
	krb5_free_principal(context, principal);

cc_exit:
	krb5_cc_close(context, ccache);

ctx_exit:
	krb5_free_context(context);

exit:
	return fstatus;
}
Esempio n. 4
0
int
auks_krb5_cred_deladdr_buffer(char *in_buf,size_t in_buf_len,
			      char** pout_buf,size_t *pout_buf_len)
{
	int fstatus = AUKS_ERROR ;

	/* kerberos related variables */
	krb5_error_code err_code;
	krb5_context context;
	krb5_auth_context auth_context;

	krb5_creds **creds;
	krb5_data data;
	krb5_replay_data krdata;

	krb5_data *p_outbuf;

	krb5_creds fwd_cred;
	krb5_creds *p_cred_out = NULL;

	krb5_address **addresses;

	char* buffer;
	size_t length;

	/* initialize kerberos context */
	err_code = krb5_init_context(&context);
	if (err_code) {
		auks_error("unable to initialize kerberos context : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_CTX ; 
		goto exit;
	}
	auks_log("kerberos context successfully initialized");

	/* initialize a nullified kerberos authentication context in order */
	/* to decode credential from buffer */
	err_code = krb5_auth_con_init(context, &auth_context);
	if (err_code) {
		auks_error("unable to initialize kerberos authentication"
			   " context : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto ctx_exit;
	}
	auks_log("kerberos authentication context successfully initialized");

	/* clear kerberos authentication context flags */
	krb5_auth_con_setflags(context, auth_context, 0);

	/* build a kerberos data structure with input buffer */
	data.data = in_buf;
	data.length = in_buf_len;

	/* build kerberos credential structure using this data structure */
	err_code = krb5_rd_cred(context, auth_context, &data,&creds,&krdata);
	if (err_code) {
		auks_error("unable to deserialize credential data : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_RD_CRED ;
		goto auth_ctx_exit;
	}
	auks_log("credential data successfully deserialized");

	memset(&fwd_cred, 0,sizeof(fwd_cred));

	/* copy client principal in futur credential */
	err_code = krb5_copy_principal(context,(*creds)->client,
				       &fwd_cred.client);
	if (err_code) {
		auks_error("unable to put client principal into "
			   "request cred : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_CP_PRINC ;
		goto cred_exit;
	}
	auks_log("client principal successfully put into request cred");

	/* copy krbtgt/... principal in futur credential as required */
	/* server principal for TGS */
	err_code = krb5_copy_principal(context,(*creds)->server,
				       &fwd_cred.server);
	if (err_code) {
		auks_error("unable to put server principal into "
			   "request cred : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_CP_PRINC ;
		goto cred_exit;
	}
	auks_log("server principal successfully put into request cred");

	/* get addressless forwarded ticket */
	err_code = krb5_get_cred_via_tkt(context,(*creds),
					 ( KDC_OPT_CANONICALIZE |
					   KDC_OPT_FORWARDED |
					   ( (*creds)->ticket_flags &
					     KDC_TKT_COMMON_MASK )  ),
					 addresses=NULL,
					 &fwd_cred,&p_cred_out);
	if (err_code) {
		auks_error("unable to get addressless forwarded cred from auks"
			   " cred buffer : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_GET_FWD_CRED ;
		goto cred_exit;
	}
	auks_log("addressless forwarded cred successfully"
		 " got using auks cred buffer");

	/* extract credential data */
	err_code = krb5_mk_1cred(context,auth_context,p_cred_out,
				 &p_outbuf,&krdata);
	if (err_code) {
		auks_error("unable to dump credential into working buffer : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_MK_CRED ;
		goto fwd_exit;
	}
	auks_log("credential successfully dumped into buffer");

	/* allocate output buffer */
	length = p_outbuf->length;
	buffer = (char *) malloc(length * sizeof(char));
	if (buffer == NULL) {
		auks_error("unable to allocate memory for credential data "
			   "storage");
		fstatus = AUKS_ERROR_KRB5_CRED_MALLOC ;
		goto mk_exit;
	}

	/* copy credential data into output buffer */
	memcpy(buffer,p_outbuf->data,length);
	*pout_buf = buffer;
	*pout_buf_len = length;
	auks_log("credential successfully stored in output buffer");
	fstatus = AUKS_SUCCESS ;

	auks_log("in length : %u | out length : %u",
		 in_buf_len,
		 p_outbuf->length);
mk_exit:
	krb5_free_data(context,p_outbuf);

fwd_exit:
	krb5_free_creds(context,p_cred_out);

cred_exit:
	krb5_free_cred_contents(context,&fwd_cred);
	krb5_free_creds(context, *creds);
	free(creds);

auth_ctx_exit:
	krb5_auth_con_free(context, auth_context);

ctx_exit:
	krb5_free_context(context);

exit:
	return fstatus;
}
Esempio n. 5
0
int
auks_krb5_cred_get(char *ccachefilename,char **pbuffer,
		   size_t * plength)
{
	int fstatus = AUKS_ERROR ;

	/* kerberos related variables */
	krb5_error_code err_code;
	krb5_context context;
	krb5_auth_context auth_context;
	krb5_ccache ccache;
	krb5_creds read_cred;
	krb5_cc_cursor cc_cursor;
	krb5_data *p_outbuf;
	krb5_replay_data krdata;

	int read_cred_was_used = 0;
	int read_cred_is_tgt = 0;

	char *buffer;
	size_t length;

	/* initialize kerberos context */
	err_code = krb5_init_context(&context);
	if (err_code) {
		auks_error("unable to initialize kerberos context : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_CTX ;
		goto exit;
	}
	auks_log("kerberos context successfully initialized");

	/* initialize kerberos credential cache structure */
	if (ccachefilename == NULL)
		err_code = krb5_cc_default(context, &ccache);
	else
		err_code = krb5_cc_resolve(context, ccachefilename,&ccache);
	if (err_code) {
		auks_error("unable to resolve credential cache : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_OPEN_CC ;
		goto ctx_exit ;
	}
	auks_log("credential cache successfully resolved");

	/* start credential cache sequential reading */
	err_code = krb5_cc_start_seq_get(context, ccache,&cc_cursor);
	if (err_code) {
		auks_error("unable to start credential cache sequential "
			   "read : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_READ_CC ;
		goto cc_exit;
	}
	auks_log("credential cache sequential read successfully started");

	/* look for the first TGT of the cache */
	do {
		err_code = krb5_cc_next_cred(context,ccache,
					     &cc_cursor,&read_cred);
		if (!err_code) {
			/* mark read_cred variable as used */
			read_cred_was_used = 1;
			/* just check initial or forwarded tickets (TGTs) */
			if ((read_cred.ticket_flags & TKT_FLG_INITIAL)
			    || (read_cred.ticket_flags & TKT_FLG_FORWARDED)) {
				read_cred_is_tgt = 1 ;
				break;
			}
		}
	}
	while (!err_code);

	/* stop credential cache sequential reading */
	err_code = krb5_cc_end_seq_get(context,ccache,&cc_cursor);
	if (err_code) {
		auks_error("unable to stop credential cache sequential "
			   "read : %s",error_message(err_code));
	} else
		auks_log("credential cache sequential read "
			 "successfully stopped");

	/* extract credential if a TGT was found */
	if (!read_cred_is_tgt) {
		auks_error("no TGT found in credential cache");
		fstatus = AUKS_ERROR_KRB5_CRED_NO_TGT_FOUND ;
		goto seq_exit;
	}
	auks_log("TGT found in credential cache");

	/* initialize a nullified kerberos authentication context in order */
	/* to serialize credential into buffer */
	err_code = krb5_auth_con_init(context,&auth_context);
	if (err_code) {
		auks_error("unable to initialize kerberos authentication "
			   "context : %s",error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_INIT_AUTH_CTX ;
		goto seq_exit;
	}
	auks_log("kerberos authentication context successfully initialized");

	/* clear kerberos authentication context flags */
	krb5_auth_con_setflags(context,auth_context,0);

	/* extract credential data */
	err_code = krb5_mk_1cred(context,auth_context,&read_cred,
				 &p_outbuf,&krdata);
	if (err_code) {
		auks_error("unable to dump credential into working buffer : %s",
			   error_message(err_code));
		fstatus = AUKS_ERROR_KRB5_CRED_MK_CRED ;
		goto auth_ctx_exit;
	}
	auks_log("credential successfully dumped into buffer");

	/* allocate output buffer */
	length = p_outbuf->length;
	buffer = (char *) malloc(length * sizeof(char));
	if (buffer == NULL) {
		auks_error("unable to allocate memory for credential data "
			   "storage");
		fstatus = AUKS_ERROR_KRB5_CRED_MALLOC ;
		goto cred_exit;
	}

	/* copy credential data into output buffer */
	memcpy(buffer,p_outbuf->data,length);
	*pbuffer = buffer;
	*plength = length;
	auks_log("credential successfully stored in output buffer");
	fstatus = AUKS_SUCCESS ;

cred_exit:
	krb5_free_data(context,p_outbuf);

auth_ctx_exit:
	/* free kerberos authentication context */
	krb5_auth_con_free(context,auth_context);

seq_exit:
	/* free credential contents */
	if (read_cred_was_used)
		krb5_free_cred_contents(context,&read_cred);

cc_exit:
	krb5_cc_close(context, ccache);

ctx_exit:
	krb5_free_context(context);

exit:
	return fstatus;
}