1 /* 2 * lib/kdb/kdb_ldap/kdb_xdr.c 3 * 4 * Copyright 1995 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 * 26 */ 27 28 #include <k5-int.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <errno.h> 32 #include "kdb_xdr.h" 33 34 #define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n))) 35 36 krb5_error_code 37 krb5_dbe_update_tl_data(context, entry, new_tl_data) 38 krb5_context context; 39 krb5_db_entry * entry; 40 krb5_tl_data * new_tl_data; 41 { 42 krb5_tl_data * tl_data; 43 krb5_octet * tmp; 44 45 /* copy the new data first, so we can fail cleanly if malloc() 46 fails */ 47 48 if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL) 49 return(ENOMEM); 50 51 /* Find an existing entry of the specified type and point at 52 it, or NULL if not found */ 53 54 for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) 55 if (tl_data->tl_data_type == new_tl_data->tl_data_type) 56 break; 57 58 /* if necessary, chain a new record in the beginning and point at it */ 59 60 if (!tl_data) { 61 if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data))) 62 == NULL) { 63 free(tmp); 64 return(ENOMEM); 65 } 66 tl_data->tl_data_next = entry->tl_data; 67 entry->tl_data = tl_data; 68 entry->n_tl_data++; 69 } 70 71 /* fill in the record */ 72 73 if (tl_data->tl_data_contents) 74 free(tl_data->tl_data_contents); 75 76 tl_data->tl_data_type = new_tl_data->tl_data_type; 77 tl_data->tl_data_length = new_tl_data->tl_data_length; 78 tl_data->tl_data_contents = tmp; 79 memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); 80 81 return(0); 82 } 83 84 krb5_error_code 85 krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) 86 krb5_context context; 87 krb5_db_entry * entry; 88 krb5_tl_data * ret_tl_data; 89 { 90 krb5_tl_data *tl_data; 91 92 for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { 93 if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { 94 *ret_tl_data = *tl_data; 95 return(0); 96 } 97 } 98 99 /* if the requested record isn't found, return zero bytes. 100 if it ever means something to have a zero-length tl_data, 101 this code and its callers will have to be changed */ 102 103 ret_tl_data->tl_data_length = 0; 104 ret_tl_data->tl_data_contents = NULL; 105 return(0); 106 } 107 108 krb5_error_code 109 krb5_dbe_update_last_pwd_change(context, entry, stamp) 110 krb5_context context; 111 krb5_db_entry * entry; 112 krb5_timestamp stamp; 113 { 114 krb5_tl_data tl_data; 115 krb5_octet buf[4]; /* this is the encoded size of an int32 */ 116 117 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 118 tl_data.tl_data_length = sizeof(buf); 119 krb5_kdb_encode_int32((krb5_int32) stamp, buf); 120 tl_data.tl_data_contents = buf; 121 122 return(krb5_dbe_update_tl_data(context, entry, &tl_data)); 123 } 124 125 krb5_error_code 126 krb5_dbe_lookup_last_pwd_change(context, entry, stamp) 127 krb5_context context; 128 krb5_db_entry * entry; 129 krb5_timestamp * stamp; 130 { 131 krb5_tl_data tl_data; 132 krb5_error_code code; 133 krb5_int32 tmp; 134 135 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 136 137 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 138 return(code); 139 140 if (tl_data.tl_data_length != 4) { 141 *stamp = 0; 142 return(0); 143 } 144 145 krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); 146 147 *stamp = (krb5_timestamp) tmp; 148 149 return(0); 150 } 151 152 /* it seems odd that there's no function to remove a tl_data, but if 153 I need one, I'll add one */ 154 155 krb5_error_code 156 krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) 157 krb5_context context; 158 krb5_db_entry * entry; 159 krb5_timestamp mod_date; 160 krb5_const_principal mod_princ; 161 { 162 krb5_tl_data tl_data; 163 164 krb5_error_code retval = 0; 165 krb5_octet * nextloc = 0; 166 char * unparse_mod_princ = 0; 167 unsigned int unparse_mod_princ_size; 168 169 if ((retval = krb5_unparse_name(context, mod_princ, 170 &unparse_mod_princ))) 171 return(retval); 172 173 unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; 174 175 if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) 176 == NULL) { 177 free(unparse_mod_princ); 178 return(ENOMEM); 179 } 180 181 tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 182 tl_data.tl_data_length = unparse_mod_princ_size + 4; 183 tl_data.tl_data_contents = nextloc; 184 185 /* Mod Date */ 186 krb5_kdb_encode_int32(mod_date, nextloc); 187 188 /* Mod Princ */ 189 memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); 190 191 retval = krb5_dbe_update_tl_data(context, entry, &tl_data); 192 193 free(unparse_mod_princ); 194 free(nextloc); 195 196 return(retval); 197 } 198 199 krb5_error_code 200 krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) 201 krb5_context context; 202 krb5_db_entry * entry; 203 krb5_timestamp * mod_time; 204 krb5_principal * mod_princ; 205 { 206 krb5_tl_data tl_data; 207 krb5_error_code code; 208 209 tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 210 211 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 212 return(code); 213 214 if ((tl_data.tl_data_length < 5) || 215 (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0')) 216 return(KRB5_KDB_TRUNCATED_RECORD); 217 218 /* Mod Date */ 219 krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); 220 221 /* Mod Princ */ 222 if ((code = krb5_parse_name(context, 223 (const char *) (tl_data.tl_data_contents+4), 224 mod_princ))) 225 return(code); 226 227 return(0); 228 } 229