1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6
7 /*
8 * lib/krb5/krb/ser_princ.c
9 *
10 * Copyright 1995 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
34 /*
35 * ser_princ.c - Serialize a krb5_principal structure.
36 */
37 #include "k5-int.h"
38 #include "int-proto.h"
39
40 /*
41 * Routines to deal with externalizing the krb5_principal:
42 * krb5_principal_size();
43 * krb5_principal_externalize();
44 * krb5_principal_internalize();
45 */
46 static krb5_error_code krb5_principal_size
47 (krb5_context, krb5_pointer, size_t *);
48 static krb5_error_code krb5_principal_externalize
49 (krb5_context, krb5_pointer, krb5_octet **, size_t *);
50 static krb5_error_code krb5_principal_internalize
51 (krb5_context,krb5_pointer *, krb5_octet **, size_t *);
52
53 /* Local data */
54 static const krb5_ser_entry krb5_principal_ser_entry = {
55 KV5M_PRINCIPAL, /* Type */
56 krb5_principal_size, /* Sizer routine */
57 krb5_principal_externalize, /* Externalize routine */
58 krb5_principal_internalize /* Internalize routine */
59 };
60
61 /*
62 * krb5_principal_size() - Determine the size required to externalize
63 * the krb5_principal.
64 */
65 static krb5_error_code
krb5_principal_size(krb5_context kcontext,krb5_pointer arg,size_t * sizep)66 krb5_principal_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep)
67 {
68 krb5_error_code kret;
69 krb5_principal principal;
70 char *fname;
71
72 /*
73 * krb5_principal requires:
74 * krb5_int32 for KV5M_PRINCIPAL
75 * krb5_int32 for flattened name size
76 * strlen(name) for name.
77 * krb5_int32 for KV5M_PRINCIPAL
78 */
79 kret = EINVAL;
80 /* Solaris Kerberos */
81 principal = (krb5_principal) arg;
82 if ((principal) &&
83 !(kret = krb5_unparse_name(kcontext, principal, &fname))) {
84 *sizep += (3*sizeof(krb5_int32)) + strlen(fname);
85 /* Solaris Kerberos */
86 krb5_xfree_wrap(fname, strlen(fname) + 1);
87 }
88 return(kret);
89 }
90
91 /*
92 * krb5_principal_externalize() - Externalize the krb5_principal.
93 */
94 static krb5_error_code
krb5_principal_externalize(krb5_context kcontext,krb5_pointer arg,krb5_octet ** buffer,size_t * lenremain)95 krb5_principal_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain)
96 {
97 krb5_error_code kret;
98 krb5_principal principal;
99 size_t required;
100 krb5_octet *bp;
101 size_t remain;
102 char *fname;
103
104 required = 0;
105 bp = *buffer;
106 remain = *lenremain;
107 kret = EINVAL;
108 /* Solaris Kerberos */
109 principal = (krb5_principal) arg;
110 if (principal) {
111 kret = ENOMEM;
112 if (!krb5_principal_size(kcontext, arg, &required) &&
113 (required <= remain)) {
114 if (!(kret = krb5_unparse_name(kcontext, principal, &fname))) {
115
116 (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
117 (void) krb5_ser_pack_int32((krb5_int32) strlen(fname),
118 &bp, &remain);
119 (void) krb5_ser_pack_bytes((krb5_octet *) fname,
120 strlen(fname), &bp, &remain);
121 (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
122 *buffer = bp;
123 *lenremain = remain;
124
125 /* Solaris Kerberos */
126 krb5_xfree_wrap(fname, strlen(fname) + 1);
127 }
128 }
129 }
130 return(kret);
131 }
132
133 /*
134 * krb5_principal_internalize() - Internalize the krb5_principal.
135 */
136 static krb5_error_code
krb5_principal_internalize(krb5_context kcontext,krb5_pointer * argp,krb5_octet ** buffer,size_t * lenremain)137 krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
138 {
139 krb5_error_code kret;
140 krb5_principal principal;
141 krb5_int32 ibuf;
142 krb5_octet *bp;
143 size_t remain;
144 char *tmpname;
145 /* Solaris Kerberos */
146 int tmpsize;
147 bp = *buffer;
148 remain = *lenremain;
149 kret = EINVAL;
150 /* Read our magic number */
151 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
152 ibuf = 0;
153 if (ibuf == KV5M_PRINCIPAL) {
154 kret = ENOMEM;
155
156 /* See if we have enough data for the length */
157 if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
158 /* Get the string */
159 /* Solaris Kerberos */
160 tmpsize = ibuf+1;
161 tmpname = (char *) MALLOC(tmpsize);
162 if ((tmpname) &&
163 !(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname,
164 (size_t) ibuf,
165 &bp, &remain))) {
166 tmpname[ibuf] = '\0';
167
168 /* Parse the name to a principal structure */
169 principal = (krb5_principal) NULL;
170 kret = krb5_parse_name(kcontext, tmpname, &principal);
171 if (!kret) {
172 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
173 if (!kret && (ibuf == KV5M_PRINCIPAL)) {
174 *buffer = bp;
175 *lenremain = remain;
176 *argp = principal;
177 }
178 else
179 kret = EINVAL;
180 }
181 if (kret && principal)
182 krb5_free_principal(kcontext, principal);
183 /* Solaris Kerberos */
184 FREE(tmpname,tmpsize);
185 }
186 }
187 }
188 return(kret);
189 }
190
191 /*
192 * Register the context serializer.
193 */
194 krb5_error_code
krb5_ser_principal_init(krb5_context kcontext)195 krb5_ser_principal_init(krb5_context kcontext)
196 {
197 return(krb5_register_serializer(kcontext, &krb5_principal_ser_entry));
198 }
199