xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/copy_princ.c (revision 505d05c73a6e56769f263d4803b22eddd168ee24)
1 /*
2  * Copyright 2005 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     if (tempprinc->realm.length) {
99         tempprinc->realm.data = MALLOC(tempprinc->realm.length + 1);
100         if (!tempprinc->realm.data) {
101 	    for (i = 0; i < nelems; i++)
102                 FREE(krb5_princ_component(context, tempprinc, i)->data,
103 			krb5_princ_component(context, inprinc, i)->length + 1);
104 	    FREE(tempprinc->data, nelems * sizeof(krb5_data));
105 	    FREE(tempprinc, sizeof(krb5_principal_data));
106 	    return ENOMEM;
107         }
108 	memcpy(tempprinc->realm.data, inprinc->realm.data,
109 	       inprinc->realm.length);
110     } else
111         tempprinc->realm.data = 0;
112 
113     *outprinc = tempprinc;
114     return 0;
115 }
116