#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
krb5_copy_creds(krb5_context context, const krb5_creds *incred, krb5_creds **outcred)
{
krb5_creds *tempcred;
krb5_error_code retval;
if (!(tempcred = (krb5_creds *)malloc(sizeof(*tempcred))))
return ENOMEM;
retval = krb5int_copy_creds_contents(context, incred, tempcred);
if (retval)
free(tempcred);
else
*outcred = tempcred;
return retval;
}
krb5_error_code
krb5int_copy_creds_contents(krb5_context context, const krb5_creds *incred,
krb5_creds *tempcred)
{
krb5_error_code retval;
krb5_data *scratch;
*tempcred = *incred;
retval = krb5_copy_principal(context, incred->client, &tempcred->client);
if (retval)
goto cleanlast;
retval = krb5_copy_principal(context, incred->server, &tempcred->server);
if (retval)
goto cleanclient;
retval = krb5_copy_keyblock_contents(context, &incred->keyblock,
&tempcred->keyblock);
if (retval)
goto cleanserver;
retval = krb5_copy_addresses(context, incred->addresses, &tempcred->addresses);
if (retval)
goto cleanblock;
retval = krb5_copy_data(context, &incred->ticket, &scratch);
if (retval)
goto cleanaddrs;
tempcred->ticket = *scratch;
krb5_xfree(scratch);
retval = krb5_copy_data(context, &incred->second_ticket, &scratch);
if (retval)
goto clearticket;
tempcred->second_ticket = *scratch;
krb5_xfree(scratch);
retval = krb5_copy_authdata(context, incred->authdata,&tempcred->authdata);
if (retval)
goto clearsecondticket;
return 0;
clearsecondticket:
memset(tempcred->second_ticket.data,0,tempcred->second_ticket.length);
free(tempcred->second_ticket.data);
clearticket:
memset(tempcred->ticket.data,0,tempcred->ticket.length);
free(tempcred->ticket.data);
cleanaddrs:
krb5_free_addresses(context, tempcred->addresses);
cleanblock:
krb5_xfree(tempcred->keyblock.contents);
cleanserver:
krb5_free_principal(context, tempcred->server);
cleanclient:
krb5_free_principal(context, tempcred->client);
cleanlast:
return retval;
}