2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A/*
2N/A * lib/kdb/kdb_ldap/kdb_xdr.c
2N/A *
2N/A * Copyright 1995 by the Massachusetts Institute of Technology.
2N/A * All Rights Reserved.
2N/A *
2N/A * Export of this software from the United States of America may
2N/A * require a specific license from the United States Government.
2N/A * It is the responsibility of any person or organization contemplating
2N/A * export to obtain such a license before exporting.
2N/A *
2N/A * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
2N/A * distribute this software and its documentation for any purpose and
2N/A * without fee is hereby granted, provided that the above copyright
2N/A * notice appear in all copies and that both that copyright notice and
2N/A * this permission notice appear in supporting documentation, and that
2N/A * the name of M.I.T. not be used in advertising or publicity pertaining
2N/A * to distribution of the software without specific, written prior
2N/A * permission. Furthermore if you modify this software you must label
2N/A * your software as modified software and not distribute it in such a
2N/A * fashion that it might be confused with the original M.I.T. software.
2N/A * M.I.T. makes no representations about the suitability of
2N/A * this software for any purpose. It is provided "as is" without express
2N/A * or implied warranty.
2N/A *
2N/A */
2N/A
2N/A#include <k5-int.h>
2N/A#include <string.h>
2N/A#include <stdio.h>
2N/A#include <errno.h>
2N/A#include "kdb_xdr.h"
2N/A
2N/A#define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n)))
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_update_tl_data(krb5_context context, krb5_db_entry *entry,
2N/A krb5_tl_data *new_tl_data)
2N/A{
2N/A krb5_tl_data * tl_data;
2N/A krb5_octet * tmp;
2N/A
2N/A /* copy the new data first, so we can fail cleanly if malloc()
2N/A fails */
2N/A
2N/A if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL)
2N/A return(ENOMEM);
2N/A
2N/A /* Find an existing entry of the specified type and point at
2N/A it, or NULL if not found */
2N/A
2N/A for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next)
2N/A if (tl_data->tl_data_type == new_tl_data->tl_data_type)
2N/A break;
2N/A
2N/A /* if necessary, chain a new record in the beginning and point at it */
2N/A
2N/A if (!tl_data) {
2N/A if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data)))
2N/A == NULL) {
2N/A free(tmp);
2N/A return(ENOMEM);
2N/A }
2N/A tl_data->tl_data_next = entry->tl_data;
2N/A entry->tl_data = tl_data;
2N/A entry->n_tl_data++;
2N/A }
2N/A
2N/A /* fill in the record */
2N/A
2N/A if (tl_data->tl_data_contents)
2N/A free(tl_data->tl_data_contents);
2N/A
2N/A tl_data->tl_data_type = new_tl_data->tl_data_type;
2N/A tl_data->tl_data_length = new_tl_data->tl_data_length;
2N/A tl_data->tl_data_contents = tmp;
2N/A memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
2N/A
2N/A return(0);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_lookup_tl_data(krb5_context context, krb5_db_entry *entry,
2N/A krb5_tl_data *ret_tl_data)
2N/A{
2N/A krb5_tl_data *tl_data;
2N/A
2N/A for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
2N/A if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
2N/A *ret_tl_data = *tl_data;
2N/A return(0);
2N/A }
2N/A }
2N/A
2N/A /* if the requested record isn't found, return zero bytes.
2N/A if it ever means something to have a zero-length tl_data,
2N/A this code and its callers will have to be changed */
2N/A
2N/A ret_tl_data->tl_data_length = 0;
2N/A ret_tl_data->tl_data_contents = NULL;
2N/A return(0);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_update_last_pwd_change(krb5_context context, krb5_db_entry *entry,
2N/A krb5_timestamp stamp)
2N/A{
2N/A krb5_tl_data tl_data;
2N/A krb5_octet buf[4]; /* this is the encoded size of an int32 */
2N/A
2N/A tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2N/A tl_data.tl_data_length = sizeof(buf);
2N/A krb5_kdb_encode_int32((krb5_int32) stamp, buf);
2N/A tl_data.tl_data_contents = buf;
2N/A
2N/A return(krb5_dbe_update_tl_data(context, entry, &tl_data));
2N/A}
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_lookup_last_pwd_change(krb5_context context, krb5_db_entry *entry,
2N/A krb5_timestamp *stamp)
2N/A{
2N/A krb5_tl_data tl_data;
2N/A krb5_error_code code;
2N/A krb5_int32 tmp;
2N/A
2N/A tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2N/A
2N/A if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2N/A return(code);
2N/A
2N/A if (tl_data.tl_data_length != 4) {
2N/A *stamp = 0;
2N/A return(0);
2N/A }
2N/A
2N/A krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
2N/A
2N/A *stamp = (krb5_timestamp) tmp;
2N/A
2N/A return(0);
2N/A}
2N/A
2N/A/* it seems odd that there's no function to remove a tl_data, but if
2N/A I need one, I'll add one */
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_update_mod_princ_data(krb5_context context, krb5_db_entry *entry,
2N/A krb5_timestamp mod_date,
2N/A krb5_const_principal mod_princ)
2N/A{
2N/A krb5_tl_data tl_data;
2N/A
2N/A krb5_error_code retval = 0;
2N/A krb5_octet * nextloc = 0;
2N/A char * unparse_mod_princ = 0;
2N/A unsigned int unparse_mod_princ_size;
2N/A
2N/A if ((retval = krb5_unparse_name(context, mod_princ,
2N/A &unparse_mod_princ)))
2N/A return(retval);
2N/A
2N/A unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
2N/A
2N/A if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
2N/A == NULL) {
2N/A free(unparse_mod_princ);
2N/A return(ENOMEM);
2N/A }
2N/A
2N/A tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2N/A tl_data.tl_data_length = unparse_mod_princ_size + 4;
2N/A tl_data.tl_data_contents = nextloc;
2N/A
2N/A /* Mod Date */
2N/A krb5_kdb_encode_int32(mod_date, nextloc);
2N/A
2N/A /* Mod Princ */
2N/A memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
2N/A
2N/A retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
2N/A
2N/A free(unparse_mod_princ);
2N/A free(nextloc);
2N/A
2N/A return(retval);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Akrb5_dbe_lookup_mod_princ_data(krb5_context context, krb5_db_entry *entry,
2N/A krb5_timestamp *mod_time,
2N/A krb5_principal *mod_princ)
2N/A{
2N/A krb5_tl_data tl_data;
2N/A krb5_error_code code;
2N/A
2N/A tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2N/A
2N/A if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2N/A return(code);
2N/A
2N/A if ((tl_data.tl_data_length < 5) ||
2N/A (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0'))
2N/A return(KRB5_KDB_TRUNCATED_RECORD);
2N/A
2N/A /* Mod Date */
2N/A krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
2N/A
2N/A /* Mod Princ */
2N/A if ((code = krb5_parse_name(context,
2N/A (const char *) (tl_data.tl_data_contents+4),
2N/A mod_princ)))
2N/A return(code);
2N/A
2N/A return(0);
2N/A}