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