xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/krb5/krb/ser_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 /*
9  * lib/krb5/krb/ser_princ.c
10  *
11  * Copyright 1995 by the Massachusetts Institute of Technology.
12  * All Rights Reserved.
13  *
14  * Export of this software from the United States of America may
15  *   require a specific license from the United States Government.
16  *   It is the responsibility of any person or organization contemplating
17  *   export to obtain such a license before exporting.
18  *
19  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
20  * distribute this software and its documentation for any purpose and
21  * without fee is hereby granted, provided that the above copyright
22  * notice appear in all copies and that both that copyright notice and
23  * this permission notice appear in supporting documentation, and that
24  * the name of M.I.T. not be used in advertising or publicity pertaining
25  * to distribution of the software without specific, written prior
26  * permission.  M.I.T. makes no representations about the suitability of
27  * this software for any purpose.  It is provided "as is" without express
28  * or implied warranty.
29  *
30  */
31 
32 /*
33  * ser_princ.c - Serialize a krb5_principal structure.
34  */
35 #include <k5-int.h>
36 #include <int-proto.h>
37 
38 /*
39  * Routines to deal with externalizing the krb5_principal:
40  *	krb5_principal_size();
41  *	krb5_principal_externalize();
42  *	krb5_principal_internalize();
43  */
44 static krb5_error_code krb5_principal_size
45 	(krb5_context, krb5_pointer, size_t *);
46 static krb5_error_code krb5_principal_externalize
47 	(krb5_context, krb5_pointer, krb5_octet **, size_t *);
48 static krb5_error_code krb5_principal_internalize
49 	(krb5_context,krb5_pointer *, krb5_octet **, size_t *);
50 
51 /* Local data */
52 static const krb5_ser_entry krb5_principal_ser_entry = {
53     KV5M_PRINCIPAL,			/* Type			*/
54     krb5_principal_size,		/* Sizer routine	*/
55     krb5_principal_externalize,		/* Externalize routine	*/
56     krb5_principal_internalize		/* Internalize routine	*/
57 };
58 
59 /*
60  * krb5_principal_size()	- Determine the size required to externalize
61  *				  the krb5_principal.
62  */
63 static krb5_error_code
64 krb5_principal_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
65 {
66     krb5_error_code	kret;
67     krb5_principal	principal;
68     char		*fname;
69 
70     /*
71      * krb5_principal requires:
72      *	krb5_int32			for KV5M_PRINCIPAL
73      *	krb5_int32			for flattened name size
74      *	strlen(name)			for name.
75      *	krb5_int32			for KV5M_PRINCIPAL
76      */
77     kret = EINVAL;
78     principal = (krb5_principal) arg;
79     if ((principal) &&
80 	!(kret = krb5_unparse_name(kcontext, principal, &fname))) {
81 	*sizep += (3*sizeof(krb5_int32)) + strlen(fname);
82 	krb5_xfree_wrap(fname, strlen(fname) + 1);
83     }
84     return(kret);
85 }
86 
87 /*
88  * krb5_principal_externalize()	- Externalize the krb5_principal.
89  */
90 static krb5_error_code
91 krb5_principal_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain)
92 {
93     krb5_error_code	kret;
94     krb5_principal	principal;
95     size_t		required;
96     krb5_octet		*bp;
97     size_t		remain;
98     char		*fname;
99 
100     required = 0;
101     bp = *buffer;
102     remain = *lenremain;
103     kret = EINVAL;
104     principal = (krb5_principal) arg;
105     if (principal) {
106 	kret = ENOMEM;
107 	if (!krb5_principal_size(kcontext, arg, &required) &&
108 	    (required <= remain)) {
109 	    if (!(kret = krb5_unparse_name(kcontext, principal, &fname))) {
110 
111 		(void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
112 		(void) krb5_ser_pack_int32((krb5_int32) strlen(fname),
113 					   &bp, &remain);
114 		(void) krb5_ser_pack_bytes((krb5_octet *) fname,
115 					   strlen(fname), &bp, &remain);
116 		(void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
117 		*buffer = bp;
118 		*lenremain = remain;
119 
120 		krb5_xfree_wrap(fname, strlen(fname) + 1);
121 	    }
122 	}
123     }
124     return(kret);
125 }
126 
127 /*
128  * krb5_principal_internalize()	- Internalize the krb5_principal.
129  */
130 static krb5_error_code
131 krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
132 {
133     krb5_error_code	kret;
134     krb5_principal	principal;
135     krb5_int32		ibuf;
136     krb5_octet		*bp;
137     size_t		remain;
138     char		*tmpname;
139     int			tmpsize;
140     bp = *buffer;
141     remain = *lenremain;
142     kret = EINVAL;
143     /* Read our magic number */
144     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
145 	ibuf = 0;
146     if (ibuf == KV5M_PRINCIPAL) {
147 	kret = ENOMEM;
148 
149 	/* See if we have enough data for the length */
150 	if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
151 	    /* Get the string */
152 	    tmpsize = ibuf+1;
153 	    tmpname = (char *) MALLOC(tmpsize);
154 	    if ((tmpname) &&
155 		!(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname,
156 					       (size_t) ibuf,
157 					       &bp, &remain))) {
158 		tmpname[ibuf] = '\0';
159 
160 		/* Parse the name to a principal structure */
161 		principal = (krb5_principal) NULL;
162 		kret = krb5_parse_name(kcontext, tmpname, &principal);
163 		if (!kret) {
164 		    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
165 		    if (!kret && (ibuf == KV5M_PRINCIPAL)) {
166 			*buffer = bp;
167 			*lenremain = remain;
168 			*argp = principal;
169 		    }
170 		    else
171 			kret = EINVAL;
172 		}
173 		if (kret && principal)
174 		    krb5_free_principal(kcontext, principal);
175 		FREE(tmpname,tmpsize);
176 	    }
177 	}
178     }
179     return(kret);
180 }
181 
182 /*
183  * Register the context serializer.
184  */
185 krb5_error_code
186 krb5_ser_principal_init(krb5_context kcontext)
187 {
188     return(krb5_register_serializer(kcontext, &krb5_principal_ser_entry));
189 }
190