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 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 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 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 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 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 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 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 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 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 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