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