#include "k5-int.h"
krb5_error_code KRB5_CALLCONV
krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc)
{
register krb5_principal tempprinc;
register int i, nelems;
tempprinc = (krb5_principal)MALLOC(sizeof(krb5_principal_data));
if (tempprinc == 0)
return ENOMEM;
*tempprinc = *inprinc;
nelems = (int) krb5_princ_size(context, inprinc);
tempprinc->data = MALLOC(nelems * sizeof(krb5_data));
if (tempprinc->data == 0) {
FREE((char *)tempprinc, sizeof(krb5_principal_data));
return ENOMEM;
}
for (i = 0; i < nelems; i++) {
unsigned int len = krb5_princ_component(context, inprinc, i)->length;
krb5_princ_component(context, tempprinc, i)->length = len;
if (len &&
((krb5_princ_component(context, tempprinc, i)->data =
MALLOC(len + 1)) == 0)) {
while (--i >= 0)
FREE(krb5_princ_component(context, tempprinc, i)->data,
krb5_princ_component(context, inprinc, i)->length + 1);
FREE (tempprinc->data, nelems * sizeof(krb5_data));
FREE (tempprinc,sizeof(krb5_principal_data));
return ENOMEM;
}
if (len)
(void) memcpy(krb5_princ_component(context, tempprinc, i)->data,
krb5_princ_component(context, inprinc, i)->data, len);
else
krb5_princ_component(context, tempprinc, i)->data = 0;
}
tempprinc->realm.length = inprinc->realm.length;
tempprinc->realm.data = MALLOC(tempprinc->realm.length + 1);
if (!tempprinc->realm.data) {
for (i = 0; i < nelems; i++)
FREE(krb5_princ_component(context, tempprinc, i)->data,
krb5_princ_component(context, inprinc, i)->length + 1);
FREE(tempprinc->data, nelems * sizeof(krb5_data));
FREE(tempprinc, sizeof(krb5_principal_data));
return ENOMEM;
}
memcpy(tempprinc->realm.data, inprinc->realm.data,
inprinc->realm.length);
tempprinc->realm.data[tempprinc->realm.length] = 0;
*outprinc = tempprinc;
return 0;
}