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