[196] in Kerberos-V5-bugs
shar file for support of deletion in keytab/file
daemon@ATHENA.MIT.EDU (Joe Pato)
Tue Sep 10 14:07:07 1991
From: pato@apollo.com (Joe Pato)
Date: Tue, 10 Sep 91 14:03:19 EDT
To: krb5-bugs@MIT.EDU
Cc: tytso@athena.mit.edu
This shar file contains the modifications to the beta1 keytab code to support
deletion from the keytab file. This involves a change in format to the keytab
file (defined in ktf_util.c). We have also added a timestamp field to the
krb5_keytab_entry data type (which is used by garbage collectors). Included is
also lib/os/krbfileio.c which supports a function to create "secure" files and
another to sync a file to disk.
This shar file does not contain changes to the keytab API reflecting the use of
multiple keytypes (i.e., the get function should take a keytype as an
input argument so that it yields a key of the proper form) (this will follow
shortly).
-- Joe Pato
Cooperative Computing Division
Hewlett-Packard Company
pato@apollo.hp.com
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 09/10/1991 17:57 UTC by pato@chelm
# Source directory //chelm/pato/sandbox/pe2/source
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 3555 -rw-rw-r-- krb5.src/include/krb5/keytab.h
# 2887 -rw-rw-r-- krb5.src/lib/keytab/file/ktf_remove.c
# 15979 -rw-rw-r-- krb5.src/lib/keytab/file/ktf_util.c
# 4072 -rw-rw-r-- krb5.src/lib/keytab/file/ktfile.h
# 2131 -rw-rw-r-- krb5.src/lib/os/Imakefile
# 2543 -rw-rw-r-- krb5.src/lib/os/krbfileio.c
#
# ============= krb5.src/include/krb5/keytab.h ==============
if test ! -d 'krb5.src'; then
echo 'x - creating directory krb5.src'
mkdir 'krb5.src'
fi
if test ! -d 'krb5.src/include'; then
echo 'x - creating directory krb5.src/include'
mkdir 'krb5.src/include'
fi
if test ! -d 'krb5.src/include/krb5'; then
echo 'x - creating directory krb5.src/include/krb5'
mkdir 'krb5.src/include/krb5'
fi
if test -f 'krb5.src/include/krb5/keytab.h' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/include/krb5/keytab.h (File already exists)'
else
echo 'x - extracting krb5.src/include/krb5/keytab.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/include/krb5/keytab.h' &&
/*
X * $Source: /afs/athena.mit.edu/astaff/project/krb5/src/include/krb5/RCS/keytab.h,v $
X * $Author: jtkohl $
X * $Id: keytab.h,v 5.12 91/06/06 09:33:36 jtkohl Exp $
X *
X * Copyright 1990 by the Massachusetts Institute of Technology.
X * All Rights Reserved.
X *
X * Export of this software from the United States of America is assumed
X * to require a specific license from the United States Government.
X * It is the responsibility of any person or organization contemplating
X * export to obtain such a license before exporting.
X *
X * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
X * distribute this software and its documentation for any purpose and
X * without fee is hereby granted, provided that the above copyright
X * notice appear in all copies and that both that copyright notice and
X * this permission notice appear in supporting documentation, and that
X * the name of M.I.T. not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. M.I.T. makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X *
X * Keytab definitions.
X */
X
X
#ifndef KRB5_KEYTAB__
#define KRB5_KEYTAB__
X
X
/* XXX */
#define MAX_KEYTAB_NAME_LEN 1100 /* Long enough for MAXPATHLEN + some extra */
X
typedef krb5_pointer krb5_kt_cursor; /* XXX */
X
typedef struct krb5_keytab_entry_st {
X krb5_principal principal; /* principal of this key */
X krb5_timestamp timestamp; /* time entry written to keytable */
X krb5_kvno vno; /* key version number */
X krb5_keyblock key; /* the secret key */
} krb5_keytab_entry;
X
X
typedef struct _krb5_kt {
X struct _krb5_kt_ops *ops;
X krb5_pointer data;
} *krb5_keytab;
X
X
/* widen prototypes, if needed */
#include <krb5/widen.h>
X
typedef struct _krb5_kt_ops {
X char *prefix;
X /* routines always present */
X krb5_error_code (*resolve) PROTOTYPE((char *,
X krb5_keytab *));
X krb5_error_code (*get_name) PROTOTYPE((krb5_keytab,
X char *,
X int));
X krb5_error_code (*close) PROTOTYPE((krb5_keytab));
X krb5_error_code (*get) PROTOTYPE((krb5_keytab,
X krb5_principal,
X krb5_kvno,
X krb5_keytab_entry *));
X krb5_error_code (*start_seq_get) PROTOTYPE((krb5_keytab,
X krb5_kt_cursor *));
X krb5_error_code (*get_next) PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *,
X krb5_kt_cursor *));
X krb5_error_code (*end_get) PROTOTYPE((krb5_keytab,
X krb5_kt_cursor *));
X /* routines to be included on extended version (write routines) */
X krb5_error_code (*add) PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *));
X krb5_error_code (*remove) PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *));
} krb5_kt_ops;
X
/* and back to narrow */
#include <krb5/narrow.h>
X
#define krb5_kt_get_name(keytab, name, namelen) (*(keytab)->ops->get_name)(keytab,name,namelen)
#define krb5_kt_close(keytab) (*(keytab)->ops->close)(keytab)
#define krb5_kt_get_entry(keytab, principal, vno, entry) (*(keytab)->ops->get)(keytab, principal, vno, entry)
#define krb5_kt_start_seq_get(keytab, cursor) (*(keytab)->ops->start_seq_get)(keytab, cursor)
#define krb5_kt_next_entry(keytab, entry, cursor) (*(keytab)->ops->get_next)(keytab, entry, cursor)
#define krb5_kt_end_seq_get(keytab, cursor) (*(keytab)->ops->end_get)(keytab, cursor)
/* remove and add are functions, so that they can return NOWRITE
X if not a writable keytab */
X
X
extern krb5_kt_ops krb5_kt_dfl_ops;
X
#endif /* KRB5_KEYTAB__ */
SHAR_EOF
chmod 0664 krb5.src/include/krb5/keytab.h ||
echo 'restore of krb5.src/include/krb5/keytab.h failed'
Wc_c="`wc -c < 'krb5.src/include/krb5/keytab.h'`"
test 3555 -eq "$Wc_c" ||
echo 'krb5.src/include/krb5/keytab.h: original size 3555, current size' "$Wc_c"
fi
# ============= krb5.src/lib/keytab/file/ktf_remove.c ==============
if test ! -d 'krb5.src/lib'; then
echo 'x - creating directory krb5.src/lib'
mkdir 'krb5.src/lib'
fi
if test ! -d 'krb5.src/lib/keytab'; then
echo 'x - creating directory krb5.src/lib/keytab'
mkdir 'krb5.src/lib/keytab'
fi
if test ! -d 'krb5.src/lib/keytab/file'; then
echo 'x - creating directory krb5.src/lib/keytab/file'
mkdir 'krb5.src/lib/keytab/file'
fi
if test -f 'krb5.src/lib/keytab/file/ktf_remove.c' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/lib/keytab/file/ktf_remove.c (File already exists)'
else
echo 'x - extracting krb5.src/lib/keytab/file/ktf_remove.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/lib/keytab/file/ktf_remove.c' &&
/*
X * $Source: /afs/athena.mit.edu/astaff/project/krb5/src/lib/keytab/file/RCS/ktf_remove.c,v $
X * $Author: pato $
X *
X * Copyright (c) Hewlett-Packard Company 1991
X * Released to the Massachusetts Institute of Technology for inclusion
X * in the Kerberos source code distribution.
X *
X * Copyright 1990, 1991 by the Massachusetts Institute of Technology.
X * All Rights Reserved.
X *
X * Export of this software from the United States of America is assumed
X * to require a specific license from the United States Government.
X * It is the responsibility of any person or organization contemplating
X * export to obtain such a license before exporting.
X *
X * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
X * distribute this software and its documentation for any purpose and
X * without fee is hereby granted, provided that the above copyright
X * notice appear in all copies and that both that copyright notice and
X * this permission notice appear in supporting documentation, and that
X * the name of M.I.T. not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. M.I.T. makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X *
X * krb5_ktfile_remove()
X */
X
#if !defined(lint) && !defined(SABER)
static char rcsid_ktf_add_c[] =
"$Id: ktf_remove.c,v 5.3 91/06/06 09:45:34 jtkohl Exp $";
#endif /* !lint & !SABER */
X
#include <krb5/krb5.h>
#include <krb5/ext-proto.h>
X
#include "ktfile.h"
X
krb5_error_code
krb5_ktfile_remove(id, entry)
krb5_keytab id;
krb5_keytab_entry *entry;
{
X krb5_keytab_entry *cur_entry;
X krb5_error_code kerror;
X krb5_int32 delete_point;
X krb5_boolean found = FALSE;
X
X if (kerror = krb5_ktfileint_openw(id)) {
X return kerror;
X }
X
X /*
X * For efficiency and simplicity, we'll use a while true that
X * is exited with a break statement.
X */
X while (TRUE) {
X cur_entry = 0;
X if (kerror = krb5_ktfileint_internal_read_entry(id, &cur_entry,
X &delete_point))
X break;
X
X if ((entry->vno == cur_entry->vno) &&
X (entry->key.keytype == cur_entry->key.keytype) &&
X krb5_principal_compare(entry->principal, cur_entry->principal)) {
X /* found a match */
X found = TRUE;
X krb5_kt_free_entry(cur_entry);
X break;
X }
X krb5_kt_free_entry(cur_entry);
X }
X
X if (kerror && kerror != KRB5_KT_END) {
X (void) krb5_ktfileint_close(id);
X return kerror;
X }
X
X if (found) {
X kerror = krb5_ktfileint_delete_entry(id, delete_point);
X } else {
X kerror = KRB5_KT_NOTFOUND;
X }
X
X if (kerror) {
X (void) krb5_ktfileint_close(id);
X } else {
X kerror = krb5_ktfileint_close(id);
X }
X
X return kerror;
}
SHAR_EOF
chmod 0664 krb5.src/lib/keytab/file/ktf_remove.c ||
echo 'restore of krb5.src/lib/keytab/file/ktf_remove.c failed'
Wc_c="`wc -c < 'krb5.src/lib/keytab/file/ktf_remove.c'`"
test 2887 -eq "$Wc_c" ||
echo 'krb5.src/lib/keytab/file/ktf_remove.c: original size 2887, current size' "$Wc_c"
fi
# ============= krb5.src/lib/keytab/file/ktf_util.c ==============
if test -f 'krb5.src/lib/keytab/file/ktf_util.c' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/lib/keytab/file/ktf_util.c (File already exists)'
else
echo 'x - extracting krb5.src/lib/keytab/file/ktf_util.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/lib/keytab/file/ktf_util.c' &&
/*
X * $Source: /afs/athena.mit.edu/astaff/project/krb5/src/lib/keytab/file/RCS/ktf_util.c,v $
X * $Author: jtkohl, pato $
X *
X * Copyright (c) Hewlett-Packard Company 1991
X * Released to the Massachusetts Institute of Technology for inclusion
X * in the Kerberos source code distribution.
X *
X * Copyright 1990,1991 by the Massachusetts Institute of Technology.
X * All Rights Reserved.
X *
X * Export of this software from the United States of America is assumed
X * to require a specific license from the United States Government.
X * It is the responsibility of any person or organization contemplating
X * export to obtain such a license before exporting.
X *
X * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
X * distribute this software and its documentation for any purpose and
X * without fee is hereby granted, provided that the above copyright
X * notice appear in all copies and that both that copyright notice and
X * this permission notice appear in supporting documentation, and that
X * the name of M.I.T. not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. M.I.T. makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X *
X * This function contains utilities for the file based implementation of
X * the keytab. There are no public functions in this file.
X *
X * This file is the only one that has knowledge of the format of a
X * keytab file.
X *
X * The format is as follows:
X *
X * <file format vno>
X * <record length>
X * principal timestamp vno key
X * <record length>
X * principal timestamp vno key
X * ....
X *
X * A length field (sizeof(krb5_int32)) exists between entries. When this
X * length is positive it indicates an active entry, when negative a hole.
X * The length indicates the size of the block in the file (this may be
X * larger than the size of the next record, since we are using a first
X * fit algorithm for re-using holes and the first fit may be larger than
X * the entry we are writing). Another (compatible) implementation could
X * break up holes when allocating them to smaller entries to minimize
X * wasted space. (Such an implementation should also coalesce adjacent
X * holes to reduce fragmentation). This implementation does neither.
X *
X * There are no separators between fields of an entry.
X * A principal is a length-encoded array of length-encoded strings. The
X * length is a krb5_int16 in each case. The specific format, then, is
X * multiple entries concatinated with no separators. An entry has this
X * exact format:
X *
X * sizeof(krb5_int16) bytes for number of components in the principal;
X * then, each component listed in ordser.
X * For each component, sizeof(krb5_int16) bytes for the number of bytes
X * in the component, followed by the component.
X * sizeof(krb5_timestamp) bytes for the timestamp
X * sizeof(krb5_kvno) bytes for the key version number
X * sizeof(krb5_keytype) bytes for the keytype
X * sizeof(krb5_int32) bytes for the key length, followed by the key
X *
X */
X
#if !defined(lint) && !defined(SABER)
static char rcsid_ktf_util_c[] =
"$Id: ktf_util.c,v 5.12 91/06/06 09:44:54 jtkohl Exp $";
#endif /* !lint & !SABER */
X
#include <krb5/krb5.h>
#include <krb5/ext-proto.h>
#include <krb5/libos.h>
#include <krb5/los-proto.h>
X
#include "ktfile.h"
#include <krb5/osconf.h>
X
#ifdef KRB5_USE_INET
#include <netinet/in.h>
#else
X #error find some way to use net-byte-order file version numbers.
#endif
X
#define KRB5_KT_VNO 0x0501 /* krb5, keytab v 1 */
typedef krb5_int16 krb5_kt_vno;
X
#define xfwrite(a, b, c, d) fwrite((char *)a, b, c, d)
#define xfread(a, b, c, d) fread((char *)a, b, c, d)
X
extern int errno;
X
static krb5_error_code
krb5_ktfileint_open(id, mode)
krb5_keytab id;
int mode;
{
X krb5_error_code kerror;
X krb5_kt_vno kt_vno = htons(KRB5_KT_VNO);
X int writevno = 0;
X
#if defined(__STDC__)
X KTFILEP(id) = fopen(KTFILENAME(id),
X (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb");
#else
X KTFILEP(id) = fopen(KTFILENAME(id),
X (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "r+" : "r");
#endif
X if (!KTFILEP(id)) {
X if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) {
X /* try making it first time around */
X krb5_create_secure_file(KTFILENAME(id));
#if defined(__STDC__)
X KTFILEP(id) = fopen(KTFILENAME(id), "rb+");
#else
X KTFILEP(id) = fopen(KTFILENAME(id), "r+");
#endif
X if (!KTFILEP(id))
X return errno;
X writevno = 1;
X } else /* some other error */
X return errno;
X }
X if (kerror = krb5_lock_file(KTFILEP(id), KTFILENAME(id),
X mode)) {
X (void) fclose(KTFILEP(id));
X KTFILEP(id) = 0;
X return kerror;
X }
X /* assume ANSI or BSD-style stdio */
X setbuf(KTFILEP(id), NULL);
X
X /* get the vno and verify it */
X if (writevno) {
X if (!xfwrite(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) {
X kerror = errno;
X (void) krb5_unlock_file(KTFILEP(id), KTFILENAME(id));
X (void) fclose(KTFILEP(id));
X return kerror;
X }
X } else {
X /* gotta verify it instead... */
X if (!xfread(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) {
X kerror = errno;
X (void) krb5_unlock_file(KTFILEP(id), KTFILENAME(id));
X (void) fclose(KTFILEP(id));
X return kerror;
X }
X if (kt_vno != ntohs(KRB5_KT_VNO)) {
X (void) krb5_unlock_file(KTFILEP(id), KTFILENAME(id));
X (void) fclose(KTFILEP(id));
X return -1 /* KRB5_KEYTAB_BADVNO */;
X }
X }
X return 0;
}
X
krb5_error_code
krb5_ktfileint_openr(id)
krb5_keytab id;
{
X return krb5_ktfileint_open(id, KRB5_LOCKMODE_SHARED);
}
X
krb5_error_code
krb5_ktfileint_openw(id)
krb5_keytab id;
{
X return krb5_ktfileint_open(id, KRB5_LOCKMODE_EXCLUSIVE);
}
X
krb5_error_code
krb5_ktfileint_close(id)
krb5_keytab id;
{
X krb5_error_code kerror;
X
X if (!KTFILEP(id))
X return 0;
X kerror = krb5_unlock_file(KTFILEP(id), KTFILENAME(id));
X (void) fclose(KTFILEP(id));
X KTFILEP(id) = 0;
X return kerror;
}
X
krb5_error_code
krb5_ktfileint_delete_entry(id, delete_point)
krb5_keytab id;
krb5_int32 delete_point;
{
X krb5_int32 size;
X krb5_int32 len;
X char iobuf[BUFSIZ];
X
X if (fseek(KTFILEP(id), delete_point, SEEK_SET)) {
X return errno;
X }
X if (!xfread(&size, sizeof(size), 1, KTFILEP(id))) {
X return KRB5_KT_END;
X }
X if (size > 0) {
X size = -size;
X if (fseek(KTFILEP(id), delete_point, SEEK_SET)) {
X return errno;
X }
X if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) {
X return KRB5_KT_IOERR;
X }
X
X size = -size;
X if (size < BUFSIZ) {
X len = size;
X } else {
X len = BUFSIZ;
X }
X
X memset(iobuf, 0, len);
X while (size > 0) {
X xfwrite(iobuf, 1, len, KTFILEP(id));
X size -= len;
X if (size < len) {
X len = size;
X }
X }
X
X return krb5_sync_disk_file(KTFILEP(id));
X }
X
X return 0;
}
X
krb5_error_code
krb5_ktfileint_internal_read_entry(id, entrypp, delete_point)
krb5_keytab id;
krb5_keytab_entry **entrypp;
krb5_int32 *delete_point;
{
X register krb5_keytab_entry *ret_entry;
X krb5_int16 count;
X krb5_int16 princ_size;
X register int i;
X krb5_int32 size;
X krb5_int32 start_pos;
X
X if (!(ret_entry = (krb5_keytab_entry *)calloc(1, sizeof(*ret_entry))))
X return ENOMEM;
X
X do {
X *delete_point = ftell(KTFILEP(id));
X if (!xfread(&size, sizeof(size), 1, KTFILEP(id))) {
X return KRB5_KT_END;
X }
X
X if (size < 0) {
X if (fseek(KTFILEP(id), -size, SEEK_CUR)) {
X return errno;
X }
X }
X } while (size < 0);
X
X if (size == 0) {
X return KRB5_KT_END;
X }
X
X start_pos = ftell(KTFILEP(id));
X
X /* deal with guts of parsing... */
X
X /* first, int16 with #princ components */
X if (!xfread(&count, sizeof(count), 1, KTFILEP(id)))
X return KRB5_KT_END;
X if (!count || (count < 0))
X return KRB5_KT_END;
X if (!(ret_entry->principal = (krb5_data **)calloc(count+1, sizeof(krb5_data *))))
X return ENOMEM;
X for (i = 0; i < count; i++) {
X if (!xfread(&princ_size, sizeof(princ_size), 1, KTFILEP(id)))
X return KRB5_KT_END;
X if (!princ_size || (princ_size < 0))
X return KRB5_KT_END;
X
X if (!(ret_entry->principal[i] = (krb5_data *)malloc(sizeof(krb5_data))))
X return ENOMEM;
X ret_entry->principal[i]->length = princ_size;
X ret_entry->principal[i]->data = malloc(princ_size);
X if (!ret_entry->principal[i]->data)
X return ENOMEM;
X if (!xfread(ret_entry->principal[i]->data, sizeof(char), princ_size,
X KTFILEP(id)))
X return KRB5_KT_END;
X }
X if (!xfread(&ret_entry->timestamp, sizeof(ret_entry->timestamp), 1, KTFILEP(id)))
X return KRB5_KT_END;
X if (!xfread(&ret_entry->vno, sizeof(ret_entry->vno), 1, KTFILEP(id)))
X return KRB5_KT_END;
X /* key type */
X if (!xfread(&ret_entry->key.keytype, sizeof(ret_entry->key.keytype), 1,
X KTFILEP(id)))
X return KRB5_KT_END;
X /* key contents */
X if (!xfread(&count, sizeof(count), 1, KTFILEP(id)))
X return KRB5_KT_END;
X if (!count || (count < 0))
X return KRB5_KT_END;
X ret_entry->key.length = count;
X if (!(ret_entry->key.contents = (krb5_octet *)malloc(count)))
X return ENOMEM;
X if (!xfread(ret_entry->key.contents, sizeof(krb5_octet), count,
X KTFILEP(id)))
X return KRB5_KT_END;
X
X *entrypp = ret_entry;
X
X /*
X * Reposition file pointer to the next inter-record length field.
X */
X fseek(KTFILEP(id), start_pos + size, SEEK_SET);
X return 0;
}
X
krb5_error_code
krb5_ktfileint_read_entry(id, entrypp)
krb5_keytab id;
krb5_keytab_entry **entrypp;
{
X krb5_int32 delete_point;
X
X return krb5_ktfileint_internal_read_entry(id, entrypp, &delete_point);
}
X
krb5_error_code
krb5_ktfileint_write_entry(id, entry)
krb5_keytab id;
krb5_keytab_entry *entry;
{
X krb5_data **princp;
X krb5_int16 count, size;
X krb5_error_code retval = 0;
X krb5_int32 size_needed;
X krb5_int32 commit_point;
X char iobuf[BUFSIZ];
X
X retval = krb5_ktfileint_size_entry(entry, &size_needed);
X if (retval)
X return retval;
X retval = krb5_ktfileint_find_slot(id, &size_needed, &commit_point);
X if (retval)
X return retval;
X
X setbuf(KTFILEP(id), iobuf);
X
X /* count up principal components */
X for (count = 0, princp = entry->principal; *princp; princp++, count++);
X
X if (!xfwrite(&count, sizeof(count), 1, KTFILEP(id))) {
X abend:
X setbuf(KTFILEP(id), 0);
X return KRB5_KT_IOERR;
X }
X
X for (princp = entry->principal; *princp; princp++) {
X size = (*princp)->length;
X if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) {
X goto abend;
X }
X if (!xfwrite((*princp)->data, sizeof(char), size, KTFILEP(id))) {
X goto abend;
X }
X }
X /*
X * Fill in the time of day the entry was written to the keytab.
X */
X if (krb5_timeofday(&entry->timestamp)) {
X entry->timestamp = 0;
X }
X if (!xfwrite(&entry->timestamp, sizeof(entry->timestamp), 1, KTFILEP(id))) {
X goto abend;
X }
X if (!xfwrite(&entry->vno, sizeof(entry->vno), 1, KTFILEP(id))) {
X goto abend;
X }
X if (!xfwrite(&entry->key.keytype, sizeof(entry->key.keytype), 1,
X KTFILEP(id))) {
X goto abend;
X }
X size = entry->key.length;
X if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) {
X goto abend;
X }
X if (!xfwrite(entry->key.contents, sizeof(krb5_octet), size, KTFILEP(id))) {
X memset(iobuf, 0, sizeof(iobuf));
X setbuf(KTFILEP(id), 0);
X return KRB5_KT_IOERR;
X }
X
X retval = krb5_sync_disk_file(KTFILEP(id));
X (void) memset(iobuf, 0, sizeof(iobuf));
X setbuf(KTFILEP(id), 0);
X
X if (retval) {
X return retval;
X }
X
X if (fseek(KTFILEP(id), commit_point, SEEK_SET)) {
X return errno;
X }
X if (!xfwrite(&size_needed, sizeof(size_needed), 1, KTFILEP(id))) {
X goto abend;
X }
X retval = krb5_sync_disk_file(KTFILEP(id));
X
X return retval;
}
X
/*
X * Determine the size needed for a file entry for the given
X * keytab entry.
X */
krb5_error_code
krb5_ktfileint_size_entry(entry, size_needed)
krb5_keytab_entry *entry;
krb5_int32 *size_needed;
{
X krb5_data **princp;
X krb5_int16 count, size;
X krb5_int32 total_size;
X krb5_error_code retval = 0;
X
X /* count up principal components */
X for (count = 0, princp = entry->principal; *princp; princp++, count++);
X
X total_size = sizeof(count);
X
X for (princp = entry->principal; *princp; princp++) {
X total_size += (*princp)->length + (sizeof(size));
X }
X
X total_size += sizeof(entry->timestamp);
X total_size += sizeof(entry->vno);
X total_size += sizeof(entry->key.keytype);
X total_size += sizeof(size) + entry->key.length;
X
X *size_needed = total_size;
X return retval;
}
X
/*
X * Find and reserve a slot in the file for an entry of the needed size.
X * The commit point will be set to the position in the file where the
X * the length (sizeof(krb5_int32) bytes) of this node should be written
X * when commiting the write. The file position left as a result of this
X * call is the position where the actual data should be written.
X *
X * The size_needed argument may be adjusted if we find a hole that is
X * larger than the size needed. (Recall that size_needed will be used
X * to commit the write, but that this field must indicate the size of the
X * block in the file rather than the size of the actual entry)
X */
krb5_error_code
krb5_ktfileint_find_slot(id, size_needed, commit_point)
krb5_keytab id;
krb5_int32 *size_needed;
krb5_int32 *commit_point;
{
X krb5_int32 size;
X krb5_int32 remainder;
X krb5_int32 zero_point;
X krb5_kt_vno kt_vno;
X krb5_boolean found = FALSE;
X char iobuf[BUFSIZ];
X
X /*
X * Skip over file version number
X */
X if (fseek(KTFILEP(id), 0, SEEK_SET)) {
X return errno;
X }
X if (!xfread(&kt_vno, sizeof(kt_vno), 1, KTFILEP(id))) {
X return KRB5_KT_IOERR;
X }
X
X while (!found) {
X *commit_point = ftell(KTFILEP(id));
X if (!xfread(&size, sizeof(size), 1, KTFILEP(id))) {
X /*
X * Hit the end of file, reserve this slot.
X */
X setbuf(KTFILEP(id), 0);
X size = 0;
X if (!xfwrite(&size, sizeof(size), 1, KTFILEP(id))) {
X abend:
X return KRB5_KT_IOERR;
X }
X found = TRUE;
X }
X
X if (size > 0) {
X if (fseek(KTFILEP(id), size, SEEK_CUR)) {
X return errno;
X }
X } else if (!found) {
X size = -size;
X if (size >= *size_needed) {
X *size_needed = size;
X found = TRUE;
X } else if (size > 0) {
X /*
X * The current hole is not large enough, so skip it
X */
X if (fseek(KTFILEP(id), size, SEEK_CUR)) {
X return errno;
X }
X } else {
X /*
X * Found the end of the file (marked by a 0 length buffer)
X * Make sure we zero any trailing data.
X */
X zero_point = ftell(KTFILEP(id));
X setbuf(KTFILEP(id), iobuf);
X while (size = xfread(iobuf, 1, sizeof(iobuf), KTFILEP(id))) {
X if (size != sizeof(iobuf)) {
X remainder = size % sizeof(krb5_int32);
X if (remainder) {
X size += sizeof(krb5_int32) - remainder;
X }
X }
X memset(iobuf, 0, size);
X xfwrite(iobuf, 1, size, KTFILEP(id));
X if (feof(KTFILEP(id))) {
X break;
X }
X }
X setbuf(KTFILEP(id), 0);
X if (fseek(KTFILEP(id), zero_point, SEEK_SET)) {
X return errno;
X }
X }
X }
X }
X
X return 0;
}
X
SHAR_EOF
chmod 0664 krb5.src/lib/keytab/file/ktf_util.c ||
echo 'restore of krb5.src/lib/keytab/file/ktf_util.c failed'
Wc_c="`wc -c < 'krb5.src/lib/keytab/file/ktf_util.c'`"
test 15979 -eq "$Wc_c" ||
echo 'krb5.src/lib/keytab/file/ktf_util.c: original size 15979, current size' "$Wc_c"
fi
# ============= krb5.src/lib/keytab/file/ktfile.h ==============
if test -f 'krb5.src/lib/keytab/file/ktfile.h' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/lib/keytab/file/ktfile.h (File already exists)'
else
echo 'x - extracting krb5.src/lib/keytab/file/ktfile.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/lib/keytab/file/ktfile.h' &&
/*
X * $Source: /afs/athena.mit.edu/astaff/project/krb5/src/lib/keytab/file/RCS/ktfile.h,v $
X * $Author: jtkohl $
X * $Id: ktfile.h,v 5.7 91/06/06 09:45:18 jtkohl Exp $
X *
X * Copyright 1990 by the Massachusetts Institute of Technology.
X * All Rights Reserved.
X *
X * Export of this software from the United States of America is assumed
X * to require a specific license from the United States Government.
X * It is the responsibility of any person or organization contemplating
X * export to obtain such a license before exporting.
X *
X * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
X * distribute this software and its documentation for any purpose and
X * without fee is hereby granted, provided that the above copyright
X * notice appear in all copies and that both that copyright notice and
X * this permission notice appear in supporting documentation, and that
X * the name of M.I.T. not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. M.I.T. makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X *
X * This header file contains information needed by internal routines
X * of the file-based ticket cache implementation.
X */
X
X
#ifndef KRB5_KTFILE__
#define KRB5_KTFILE__
X
#include <stdio.h>
X
/*
X * Constants
X */
#define IGNORE_VNO 0
X
X
/*
X * Types
X */
typedef struct _krb5_ktfile_data {
X char *name; /* Name of the file */
X FILE *openf; /* open file, if any. */
} krb5_ktfile_data;
X
/*
X * Macros
X */
#define KTPRIVATE(id) ((krb5_ktfile_data *)(id)->data)
#define KTFILENAME(id) (((krb5_ktfile_data *)(id)->data)->name)
#define KTFILEP(id) (((krb5_ktfile_data *)(id)->data)->openf)
X
extern struct _krb5_kt_ops krb5_ktf_ops;
extern struct _krb5_kt_ops krb5_ktf_writable_ops;
X
/* widen prototypes, if needed */
#include <krb5/widen.h>
X
krb5_error_code krb5_ktfile_resolve PROTOTYPE((char *,
X krb5_keytab *));
krb5_error_code krb5_ktfile_wresolve PROTOTYPE((char *,
X krb5_keytab *));
krb5_error_code krb5_ktfile_get_name PROTOTYPE((krb5_keytab,
X char *,
X int));
krb5_error_code krb5_ktfile_close PROTOTYPE((krb5_keytab));
krb5_error_code krb5_ktfile_get_entry PROTOTYPE((krb5_keytab,
X krb5_principal,
X krb5_kvno,
X krb5_keytab_entry *));
krb5_error_code krb5_ktfile_start_seq_get PROTOTYPE((krb5_keytab,
X krb5_kt_cursor *));
krb5_error_code krb5_ktfile_get_next PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *,
X krb5_kt_cursor *));
krb5_error_code krb5_ktfile_end_get PROTOTYPE((krb5_keytab,
X krb5_kt_cursor *));
/* routines to be included on extended version (write routines) */
krb5_error_code krb5_ktfile_add PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *));
krb5_error_code krb5_ktfile_remove PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *));
X
krb5_error_code krb5_ktfileint_openr PROTOTYPE((krb5_keytab));
krb5_error_code krb5_ktfileint_openw PROTOTYPE((krb5_keytab));
krb5_error_code krb5_ktfileint_close PROTOTYPE((krb5_keytab));
krb5_error_code krb5_ktfileint_read_entry PROTOTYPE((krb5_keytab,
X krb5_keytab_entry **));
krb5_error_code krb5_ktfileint_write_entry PROTOTYPE((krb5_keytab,
X krb5_keytab_entry *));
krb5_error_code krb5_ktfileint_delete_entry PROTOTYPE((krb5_keytab,
X krb5_int32));
krb5_error_code krb5_ktfileint_internal_read_entry PROTOTYPE((krb5_keytab,
X krb5_keytab_entry **,
X krb5_int32 *));
krb5_error_code krb5_ktfileint_size_entry PROTOTYPE((krb5_keytab_entry *,
X krb5_int32 *));
krb5_error_code krb5_ktfileint_find_slot PROTOTYPE((krb5_keytab,
X krb5_int32 *,
X krb5_int32 *));
/* and back to normal... */
#include <krb5/narrow.h>
X
#endif /* KRB5_KTFILE__ */
SHAR_EOF
chmod 0664 krb5.src/lib/keytab/file/ktfile.h ||
echo 'restore of krb5.src/lib/keytab/file/ktfile.h failed'
Wc_c="`wc -c < 'krb5.src/lib/keytab/file/ktfile.h'`"
test 4072 -eq "$Wc_c" ||
echo 'krb5.src/lib/keytab/file/ktfile.h: original size 4072, current size' "$Wc_c"
fi
# ============= krb5.src/lib/os/Imakefile ==============
if test ! -d 'krb5.src/lib/os'; then
echo 'x - creating directory krb5.src/lib/os'
mkdir 'krb5.src/lib/os'
fi
if test -f 'krb5.src/lib/os/Imakefile' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/lib/os/Imakefile (File already exists)'
else
echo 'x - extracting krb5.src/lib/os/Imakefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/lib/os/Imakefile' &&
# $Source: /afs/athena.mit.edu/astaff/project/krb5/src/lib/os/RCS/Imakefile,v $
# $Author: jfc $
# $Id: Imakefile,v 5.19 91/06/06 20:51:51 jfc Exp $
#
# Copyright 1990,1991 by the Massachusetts Institute of Technology.
# All Rights Reserved.
#
# Export of this software from the United States of America is assumed
# to require a specific license from the United States Government.
# It is the responsibility of any person or organization contemplating
# export to obtain such a license before exporting.
#
# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
# distribute this software and its documentation for any purpose and
# without fee is hereby granted, provided that the above copyright
# notice appear in all copies and that both that copyright notice and
# this permission notice appear in supporting documentation, and that
# the name of M.I.T. not be used in advertising or publicity pertaining
# to distribution of the software without specific, written prior
# permission. M.I.T. makes no representations about the suitability of
# this software for any purpose. It is provided "as is" without express
# or implied warranty.
#
#
NormalLibraryObjectRule()
X
OBJS= \
X an_to_ln.o \
X def_realm.o \
X ccdefname.o \
X free_krbhs.o \
X free_hstrl.o \
X full_ipadr.o \
X get_krbhst.o \
X gen_port.o \
X gen_rname.o \
X hst_realm.o \
X krbfileio.o \
X ktdefname.o \
X kuserok.o \
X localaddr.o \
X locate_kdc.o \
X lock_file.o \
X net_read.o \
X net_write.o \
X osconfig.o \
X port2ip.o \
X rnd_confoun.o \
X read_msg.o \
X read_pwd.o \
X sendto_kdc.o \
X sn2princ.o \
X timeofday.o \
X unlck_file.o \
X ustime.o \
X write_msg.o
X
X
SRCS= \
X an_to_ln.c \
X def_realm.c \
X ccdefname.c \
X free_krbhs.c \
X free_hstrl.c \
X full_ipadr.c \
X get_krbhst.c \
X gen_port.c \
X gen_rname.c \
X hst_realm.c \
X krbfileio.c \
X ktdefname.c \
X kuserok.c \
X localaddr.c \
X locate_kdc.c \
X lock_file.c \
X net_read.c \
X net_write.c \
X osconfig.c \
X read_msg.c \
X read_pwd.c \
X port2ip.c \
X rnd_confoun.c \
X sendto_kdc.c \
X sn2princ.c \
X timeofday.c \
X unlck_file.c \
X ustime.c \
X write_msg.c
X
OtherdirLibraryTarget(..,krb5,$(OBJS))
SHAR_EOF
chmod 0664 krb5.src/lib/os/Imakefile ||
echo 'restore of krb5.src/lib/os/Imakefile failed'
Wc_c="`wc -c < 'krb5.src/lib/os/Imakefile'`"
test 2131 -eq "$Wc_c" ||
echo 'krb5.src/lib/os/Imakefile: original size 2131, current size' "$Wc_c"
fi
# ============= krb5.src/lib/os/krbfileio.c ==============
if test -f 'krb5.src/lib/os/krbfileio.c' -a X"$1" != X"-c"; then
echo 'x - skipping krb5.src/lib/os/krbfileio.c (File already exists)'
else
echo 'x - extracting krb5.src/lib/os/krbfileio.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'krb5.src/lib/os/krbfileio.c' &&
/*
X * $Source: /afs/athena.mit.edu/astaff/project/krb5/src/lib/os/RCS/krbfileio.c,v $
X * $Author: pato $
X *
X *
X * Copyright (c) Hewlett-Packard Company 1991
X * Released to the Massachusetts Institute of Technology for inclusion
X * in the Kerberos source code distribution.
X *
X * Copyright 1991 by the Massachusetts Institute of Technology.
X * All Rights Reserved.
X *
X * Export of this software from the United States of America is assumed
X * to require a specific license from the United States Government.
X * It is the responsibility of any person or organization contemplating
X * export to obtain such a license before exporting.
X *
X * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
X * distribute this software and its documentation for any purpose and
X * without fee is hereby granted, provided that the above copyright
X * notice appear in all copies and that both that copyright notice and
X * this permission notice appear in supporting documentation, and that
X * the name of M.I.T. not be used in advertising or publicity pertaining
X * to distribution of the software without specific, written prior
X * permission. M.I.T. makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *
X *
X * krb5_create_secure_file
X * krb5_sync_disk_file
X */
X
#ifdef MODULE_VERSION_ID
static char *VersionID = "@(#)krbfileio.c 2 - 08/22/91";
#endif
X
#include <krb5/krb5.h>
#include <krb5/libos.h>
X
#include <stdio.h>
#include <sys/file.h>
X
#include <sys/types.h>
#include <krb5/ext-proto.h>
X
#ifdef apollo
# define OPEN_MODE_NOT_TRUSTWORTHY
#endif
X
krb5_error_code
krb5_create_secure_file(pathname)
X char *pathname;
{
X int fd;
X
X /*
X * Create the file with access restricted to the owner
X */
X fd = open(pathname, O_RDWR | O_CREAT | O_EXCL, 0600);
X
#ifdef OPEN_MODE_NOT_TRUSTWORTHY
X /*
X * Some systems that support default acl inheritance do not
X * apply ownership information from the process - force the file
X * to have the proper info.
X */
X if (fd > -1) {
X uid_t uid;
X gid_t gid;
X
X uid = getuid();
X gid = getgid();
X
X fchown(fd, uid, gid);
X
X fchmod(fd, 0600);
X }
#endif /* OPEN_MODE_NOT_TRUSTWORTHY */
X
X if (fd > -1) {
X close(fd);
X return 0;
X } else {
X return errno;
X }
}
X
krb5_error_code
krb5_sync_disk_file(fp)
X FILE *fp;
{
X fflush(fp);
X if (fsync(fileno(fp))) {
X return errno;
X }
X
X return 0;
}
X
SHAR_EOF
chmod 0664 krb5.src/lib/os/krbfileio.c ||
echo 'restore of krb5.src/lib/os/krbfileio.c failed'
Wc_c="`wc -c < 'krb5.src/lib/os/krbfileio.c'`"
test 2543 -eq "$Wc_c" ||
echo 'krb5.src/lib/os/krbfileio.c: original size 2543, current size' "$Wc_c"
fi
exit 0
-------