1 /*
2 * Copyright 2008 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 #include "kdb_ldap.h"
9 #include "ldap_principal.h"
10 #include "princ_xdr.h"
11 #include <kadm5/admin.h>
12
13 bool_t
ldap_xdr_krb5_ui_2(XDR * xdrs,krb5_ui_2 * objp)14 ldap_xdr_krb5_ui_2(XDR *xdrs, krb5_ui_2 *objp)
15 {
16 unsigned int tmp;
17
18 tmp = (unsigned int) *objp;
19
20 if (!xdr_u_int(xdrs, &tmp))
21 return(FALSE);
22
23 *objp = (krb5_ui_2) tmp;
24 return(TRUE);
25 }
26
27 bool_t
ldap_xdr_krb5_int16(XDR * xdrs,krb5_int16 * objp)28 ldap_xdr_krb5_int16(XDR *xdrs, krb5_int16 *objp)
29 {
30 int tmp;
31
32 tmp = (int) *objp;
33
34 if (!xdr_int(xdrs, &tmp))
35 return(FALSE);
36
37 *objp = (krb5_int16) tmp;
38 return(TRUE);
39 }
40
41 bool_t
ldap_xdr_nullstring(XDR * xdrs,char ** objp)42 ldap_xdr_nullstring(XDR *xdrs, char **objp)
43 {
44 u_int size;
45
46 if (xdrs->x_op == XDR_ENCODE) {
47 if (*objp == NULL)
48 size = 0;
49 else
50 size = strlen(*objp) + 1;
51 }
52 if (! xdr_u_int(xdrs, &size)) {
53 return FALSE;
54 }
55 switch (xdrs->x_op) {
56 case XDR_DECODE:
57 if (size == 0) {
58 *objp = NULL;
59 return TRUE;
60 } else if (*objp == NULL) {
61 *objp = (char *) mem_alloc(size);
62 if (*objp == NULL) {
63 /*errno = ENOMEM;*/
64 return FALSE;
65 }
66 }
67 return (xdr_opaque(xdrs, *objp, size));
68
69 case XDR_ENCODE:
70 if (size != 0)
71 return (xdr_opaque(xdrs, *objp, size));
72 return TRUE;
73
74 case XDR_FREE:
75 if (*objp != NULL)
76 mem_free(*objp, size);
77 *objp = NULL;
78 return TRUE;
79 }
80 return FALSE;
81 }
82
83 bool_t
ldap_xdr_krb5_kvno(XDR * xdrs,krb5_kvno * objp)84 ldap_xdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp)
85 {
86 unsigned char tmp;
87
88 tmp = '\0'; /* for purify, else xdr_u_char performs a umr */
89
90 if (xdrs->x_op == XDR_ENCODE)
91 tmp = (unsigned char) *objp;
92
93 if (!xdr_u_char(xdrs, &tmp))
94 return (FALSE);
95
96 if (xdrs->x_op == XDR_DECODE)
97 *objp = (krb5_kvno) tmp;
98 return (TRUE);
99 }
100
101 bool_t
ldap_xdr_krb5_key_data(XDR * xdrs,krb5_key_data * objp)102 ldap_xdr_krb5_key_data(XDR *xdrs, krb5_key_data *objp)
103 {
104 unsigned int tmp;
105
106 if (!ldap_xdr_krb5_int16(xdrs, &objp->key_data_ver))
107 return(FALSE);
108 if (!ldap_xdr_krb5_int16(xdrs, &objp->key_data_kvno))
109 return(FALSE);
110 if (!ldap_xdr_krb5_int16(xdrs, &objp->key_data_type[0]))
111 return(FALSE);
112 if (!ldap_xdr_krb5_int16(xdrs, &objp->key_data_type[1]))
113 return(FALSE);
114 /*
115 * Solaris kerberos: need this cast for now, should go away when kdb.h is
116 * resynced.
117 */
118 if (!ldap_xdr_krb5_ui_2(xdrs, (krb5_ui_2 *)&objp->key_data_length[0]))
119 return(FALSE);
120 if (!ldap_xdr_krb5_ui_2(xdrs, (krb5_ui_2 *)&objp->key_data_length[1]))
121 return(FALSE);
122
123 tmp = (unsigned int) objp->key_data_length[0];
124 if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[0],
125 &tmp, (unsigned int) ~0))
126 return FALSE;
127
128 tmp = (unsigned int) objp->key_data_length[1];
129 if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[1],
130 &tmp, (unsigned int) ~0))
131 return FALSE;
132
133 /* don't need to copy tmp out, since key_data_length will be set
134 by the above encoding. */
135 return(TRUE);
136 }
137
138 bool_t
ldap_xdr_osa_pw_hist_ent(XDR * xdrs,osa_pw_hist_ent * objp)139 ldap_xdr_osa_pw_hist_ent(XDR *xdrs, osa_pw_hist_ent *objp)
140 {
141 if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
142 (u_int *) &objp->n_key_data, (unsigned int) ~0,
143 sizeof(krb5_key_data),
144 ldap_xdr_krb5_key_data))
145 return (FALSE);
146 return (TRUE);
147 }
148
149 bool_t
ldap_xdr_osa_princ_ent_rec(XDR * xdrs,osa_princ_ent_t objp)150 ldap_xdr_osa_princ_ent_rec(XDR *xdrs, osa_princ_ent_t objp)
151 {
152 switch (xdrs->x_op) {
153 case XDR_ENCODE:
154 objp->version = OSA_ADB_PRINC_VERSION_1;
155 /* fall through */
156 /*LINTED*/
157 case XDR_FREE:
158 if (!xdr_int(xdrs, &objp->version))
159 return FALSE;
160 break;
161 case XDR_DECODE:
162 if (!xdr_int(xdrs, &objp->version))
163 return FALSE;
164 if (objp->version != OSA_ADB_PRINC_VERSION_1)
165 return FALSE;
166 break;
167 }
168
169 if (!ldap_xdr_nullstring(xdrs, &objp->policy))
170 return (FALSE);
171 if (!xdr_long(xdrs, &objp->aux_attributes))
172 return (FALSE);
173 if (!xdr_u_int(xdrs, &objp->old_key_next))
174 return (FALSE);
175 if (!ldap_xdr_krb5_kvno(xdrs, &objp->admin_history_kvno))
176 return (FALSE);
177 if (!xdr_array(xdrs, (caddr_t *) &objp->old_keys,
178 (unsigned int *) &objp->old_key_len, (unsigned int) ~0,
179 sizeof(osa_pw_hist_ent),
180 ldap_xdr_osa_pw_hist_ent))
181 return (FALSE);
182 return (TRUE);
183 }
184
185 void
ldap_osa_free_princ_ent(osa_princ_ent_t val)186 ldap_osa_free_princ_ent(osa_princ_ent_t val)
187 {
188 XDR xdrs;
189
190 xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
191
192 ldap_xdr_osa_princ_ent_rec(&xdrs, val);
193 free(val);
194 }
195
196 krb5_error_code
krb5_lookup_tl_kadm_data(krb5_tl_data * tl_data,osa_princ_ent_rec * princ_entry)197 krb5_lookup_tl_kadm_data(krb5_tl_data *tl_data, osa_princ_ent_rec *princ_entry)
198 {
199
200 XDR xdrs;
201
202 xdrmem_create(&xdrs, (const caddr_t)tl_data->tl_data_contents,
203 tl_data->tl_data_length, XDR_DECODE);
204 if (! ldap_xdr_osa_princ_ent_rec(&xdrs, princ_entry)) {
205 xdr_destroy(&xdrs);
206 return(KADM5_XDR_FAILURE);
207 }
208 xdr_destroy(&xdrs);
209
210 return 0;
211
212 }
213
214 krb5_error_code
krb5_update_tl_kadm_data(policy_dn,new_tl_data,old_tl_data)215 krb5_update_tl_kadm_data(policy_dn, new_tl_data, old_tl_data)
216 char * policy_dn;
217 krb5_tl_data * new_tl_data;
218 /* Solaris Kerberos: adding support for key history in LDAP KDB */
219 krb5_tl_data * old_tl_data;
220 {
221 XDR xdrs;
222 osa_princ_ent_t princ_entry;
223 /* Solaris Kerberos: added the next line to fix a memleak. */
224 char *tmpbuf;
225
226 if ((princ_entry = (osa_princ_ent_t) malloc(sizeof(osa_princ_ent_rec))) == NULL)
227 return ENOMEM;
228
229 memset(princ_entry, 0, sizeof(osa_princ_ent_rec));
230 princ_entry->aux_attributes = KADM5_POLICY;
231
232 /* Solaris Kerberos: adding support for key history in LDAP KDB */
233 if (old_tl_data != NULL) {
234 /* get the key history from the old tl_data */
235 xdrmem_create(&xdrs, (caddr_t)old_tl_data->tl_data_contents,
236 old_tl_data->tl_data_length, XDR_DECODE);
237 if (! ldap_xdr_osa_princ_ent_rec(&xdrs, princ_entry)) {
238 xdr_destroy(&xdrs);
239 free(princ_entry);
240 return(KADM5_XDR_FAILURE);
241 }
242 xdr_destroy(&xdrs);
243 /* will set the policy field further down, avoid mem leak */
244 free(princ_entry->policy);
245 } else {
246 princ_entry->admin_history_kvno = 2;
247 }
248 princ_entry->policy = policy_dn;
249
250 xdralloc_create(&xdrs, XDR_ENCODE);
251 if (! ldap_xdr_osa_princ_ent_rec(&xdrs, princ_entry)) {
252 xdr_destroy(&xdrs);
253 free(princ_entry);
254 return(KADM5_XDR_FAILURE);
255 }
256 new_tl_data->tl_data_type = KRB5_TL_KADM_DATA;
257 new_tl_data->tl_data_length = xdr_getpos(&xdrs);
258 /* Solaris Kerberos: added the next line to fix a memleak. */
259 if ((tmpbuf = (char *) malloc(new_tl_data->tl_data_length)) == NULL)
260 return ENOMEM;
261 memcpy(tmpbuf, xdralloc_getdata(&xdrs), new_tl_data->tl_data_length);
262 new_tl_data->tl_data_contents = (krb5_octet *)tmpbuf;
263
264 /* Solaris Kerberos: added the next lines to fix a memleak. */
265 free(princ_entry);
266 xdr_destroy(&xdrs);
267
268 return(0);
269 }
270