1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 /* 8 * lib/krb5/krb/copy_princ.c 9 * 10 * Copyright 1990 by the Massachusetts Institute of Technology. 11 * All Rights Reserved. 12 * 13 * Export of this software from the United States of America may 14 * require a specific license from the United States Government. 15 * It is the responsibility of any person or organization contemplating 16 * export to obtain such a license before exporting. 17 * 18 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 19 * distribute this software and its documentation for any purpose and 20 * without fee is hereby granted, provided that the above copyright 21 * notice appear in all copies and that both that copyright notice and 22 * this permission notice appear in supporting documentation, and that 23 * the name of M.I.T. not be used in advertising or publicity pertaining 24 * to distribution of the software without specific, written prior 25 * permission. Furthermore if you modify this software you must label 26 * your software as modified software and not distribute it in such a 27 * fashion that it might be confused with the original M.I.T. software. 28 * M.I.T. makes no representations about the suitability of 29 * this software for any purpose. It is provided "as is" without express 30 * or implied warranty. 31 * 32 * 33 * krb5_copy_principal() 34 */ 35 36 #include <k5-int.h> 37 /* 38 * Copy a principal structure, with fresh allocation. 39 */ 40 /*ARGSUSED*/ 41 krb5_error_code KRB5_CALLCONV 42 krb5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc) 43 { 44 register krb5_principal tempprinc; 45 register int i, nelems; 46 47 tempprinc = (krb5_principal)MALLOC(sizeof(krb5_principal_data)); 48 49 if (tempprinc == 0) 50 return ENOMEM; 51 52 #ifdef HAVE_C_STRUCTURE_ASSIGNMENT 53 *tempprinc = *inprinc; /* Copy all of the non-allocated pieces */ 54 #else 55 (void) memcpy(tempprinc, inprinc, sizeof(krb5_principal_data)); 56 #endif 57 58 nelems = (int) krb5_princ_size(context, inprinc); 59 tempprinc->data = MALLOC(nelems * sizeof(krb5_data)); 60 61 if (tempprinc->data == 0) { 62 FREE((char *)tempprinc, sizeof(krb5_principal_data)); 63 return ENOMEM; 64 } 65 66 for (i = 0; i < nelems; i++) { 67 unsigned int len = krb5_princ_component(context, inprinc, i)->length; 68 krb5_princ_component(context, tempprinc, i)->length = len; 69 70 /* 71 * Allocate one extra byte for trailing zero byte so string ops 72 * can be used on the components. 73 */ 74 if (len && 75 ((krb5_princ_component(context, tempprinc, i)->data = 76 MALLOC(len + 1)) == 0)) { 77 while (--i >= 0) 78 FREE(krb5_princ_component(context, tempprinc, i)->data, 79 krb5_princ_component(context, inprinc, i)->length + 1); 80 FREE (tempprinc->data, nelems * sizeof(krb5_data)); 81 FREE (tempprinc,sizeof(krb5_principal_data)); 82 return ENOMEM; 83 } 84 if (len) 85 (void) memcpy(krb5_princ_component(context, tempprinc, i)->data, 86 krb5_princ_component(context, inprinc, i)->data, len); 87 else 88 krb5_princ_component(context, tempprinc, i)->data = 0; 89 } 90 91 tempprinc->realm.length = inprinc->realm.length; 92 93 /* 94 * Allocate one extra byte for the realm name string terminator. The 95 * realm and principle component strings alway leave a null byte after 96 * 'length' bytes that needs to be malloc/freed. 97 */ 98 tempprinc->realm.data = MALLOC(tempprinc->realm.length + 1); 99 if (!tempprinc->realm.data) { 100 for (i = 0; i < nelems; i++) 101 FREE(krb5_princ_component(context, tempprinc, i)->data, 102 krb5_princ_component(context, inprinc, i)->length + 1); 103 FREE(tempprinc->data, nelems * sizeof(krb5_data)); 104 FREE(tempprinc, sizeof(krb5_principal_data)); 105 return ENOMEM; 106 } 107 memcpy(tempprinc->realm.data, inprinc->realm.data, 108 inprinc->realm.length); 109 tempprinc->realm.data[tempprinc->realm.length] = 0; 110 111 *outprinc = tempprinc; 112 return 0; 113 } 114