Initial revision
authorKen Raeburn <raeburn@mit.edu>
Thu, 1 Nov 1990 15:13:59 +0000 (15:13 +0000)
committerKen Raeburn <raeburn@mit.edu>
Thu, 1 Nov 1990 15:13:59 +0000 (15:13 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1388 dc483132-0cff-0310-8789-dd5450dbe970

25 files changed:
src/lib/krb5/ccache/stdio/Imakefile [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc-proto.h [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc.h [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_close.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_defnam.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_defops.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_destry.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_errs.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_eseq.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_gennew.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_getnam.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_gprin.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_init.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_maybe.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_nseq.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_ops.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_read.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_reslv.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_retrv.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_sflags.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_skip.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_sseq.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_store.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_test.c [new file with mode: 0644]
src/lib/krb5/ccache/stdio/scc_write.c [new file with mode: 0644]

diff --git a/src/lib/krb5/ccache/stdio/Imakefile b/src/lib/krb5/ccache/stdio/Imakefile
new file mode 100644 (file)
index 0000000..b7de205
--- /dev/null
@@ -0,0 +1,29 @@
+#      $Source$
+#      $Author$
+#      $Id$
+#
+#  Copyright 1990 by the Massachusetts Institute of Technology.
+# 
+#  For copying and distribution information, please see the file
+#  <krb5/copyright.h>.
+# 
+NormalLibraryObjectRule()
+
+OBJS   = scc_close.o scc_destry.o scc_eseq.o \
+       scc_gennew.o scc_getnam.o scc_gprin.o scc_init.o \
+       scc_nseq.o scc_read.o scc_reslv.o scc_retrv.o \
+       scc_sseq.o scc_store.o scc_skip.o scc_ops.o scc_write.o \
+       scc_sflags.o scc_defops.o scc_errs.o scc_maybe.o
+
+SRCS   = scc_close.c scc_destry.c scc_eseq.c \
+       scc_gennew.c scc_getnam.c scc_gprin.c scc_init.c \
+       scc_nseq.c scc_read.c scc_reslv.c scc_retrv.c \
+       scc_sseq.c scc_store.c scc_skip.c scc_ops.c scc_write.c \
+       scc_sflags.c scc_defops.c scc_errs.c scc_maybe.c
+
+all:: ${OBJS}
+
+OtherdirLibraryTarget($(TOP)/lib,krb5,$(OBJS))
+
+test: ${OBJS} scc_test.o
+       ${CC} -o test ${OBJS} scc_test.o
diff --git a/src/lib/krb5/ccache/stdio/scc-proto.h b/src/lib/krb5/ccache/stdio/scc-proto.h
new file mode 100644 (file)
index 0000000..0663f60
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * $Source$
+ * $Author$
+ * $Id$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * Prototypes for File-based credentials cache
+ */
+
+#include <krb5/copyright.h>
+
+#ifndef KRB5_SCC_PROTO__
+#define KRB5_SCC_PROTO__
+
+/* scc_close.c */
+krb5_error_code krb5_scc_close PROTOTYPE((krb5_ccache id ));
+
+/* scc_defnam.c */
+char *krb5_scc_default_name PROTOTYPE((void ));
+
+/* scc_destry.c */
+krb5_error_code krb5_scc_destroy PROTOTYPE((krb5_ccache id ));
+
+/* scc_eseq.c */
+krb5_error_code krb5_scc_end_seq_get PROTOTYPE((krb5_ccache id , krb5_cc_cursor *cursor ));
+
+/* scc_gennew.c */
+krb5_error_code krb5_scc_generate_new PROTOTYPE((krb5_ccache *id ));
+
+/* scc_getnam.c */
+char *krb5_scc_get_name PROTOTYPE((krb5_ccache id ));
+
+/* scc_gprin.c */
+krb5_error_code krb5_scc_get_principal PROTOTYPE((krb5_ccache id , krb5_principal *princ ));
+
+/* scc_init.c */
+krb5_error_code krb5_scc_initialize PROTOTYPE((krb5_ccache id , krb5_principal princ ));
+
+/* scc_nseq.c */
+krb5_error_code krb5_scc_next_cred PROTOTYPE((krb5_ccache id , krb5_cc_cursor *cursor , krb5_creds *creds ));
+
+/* scc_read.c */
+krb5_error_code krb5_scc_read_principal PROTOTYPE((krb5_ccache id , krb5_principal *princ ));
+krb5_error_code krb5_scc_read_keyblock PROTOTYPE((krb5_ccache id , krb5_keyblock *keyblock ));
+krb5_error_code krb5_scc_read_data PROTOTYPE((krb5_ccache id , krb5_data *data ));
+krb5_error_code krb5_scc_read_int32 PROTOTYPE((krb5_ccache id , krb5_int32 *i ));
+krb5_error_code krb5_scc_read_ui_2 PROTOTYPE((krb5_ccache id , krb5_ui_2 *i ));
+krb5_error_code krb5_scc_read_keytype PROTOTYPE((krb5_ccache id , krb5_keytype *k ));
+krb5_error_code krb5_scc_read_int PROTOTYPE((krb5_ccache id , int *i ));
+krb5_error_code krb5_scc_read_bool PROTOTYPE((krb5_ccache id , krb5_boolean *b ));
+krb5_error_code krb5_scc_read_times PROTOTYPE((krb5_ccache id , krb5_ticket_times *t ));
+krb5_error_code krb5_scc_read_flags PROTOTYPE((krb5_ccache id , krb5_flags *f ));
+krb5_error_code krb5_scc_read_addrs PROTOTYPE((krb5_ccache, krb5_address ***));
+krb5_error_code krb5_scc_read_addr PROTOTYPE((krb5_ccache, krb5_address *));
+
+/* scc_reslv.c */
+krb5_error_code krb5_scc_resolve PROTOTYPE((krb5_ccache *id , char *residual ));
+
+/* scc_retrv.c */
+krb5_error_code krb5_scc_retrieve PROTOTYPE((krb5_ccache id , krb5_flags whichfields , krb5_creds *mcreds , krb5_creds *creds ));
+
+/* scc_sseq.c */
+krb5_error_code krb5_scc_start_seq_get PROTOTYPE((krb5_ccache id , krb5_cc_cursor *cursor ));
+
+/* scc_store.c */
+krb5_error_code krb5_scc_store PROTOTYPE((krb5_ccache id , krb5_creds *creds ));
+
+/* scc_skip.c */
+krb5_error_code krb5_scc_skip_principal PROTOTYPE((krb5_ccache id ));
+
+/* scc_sflags.c */
+krb5_error_code krb5_scc_set_flags PROTOTYPE((krb5_ccache id , krb5_flags flags ));
+
+/* scc_ops.c */
+
+/* scc_write.c */
+krb5_error_code krb5_scc_write PROTOTYPE((krb5_ccache id , krb5_pointer buf , int len ));
+krb5_error_code krb5_scc_store_principal PROTOTYPE((krb5_ccache id , krb5_principal princ ));
+krb5_error_code krb5_scc_store_keyblock PROTOTYPE((krb5_ccache id , krb5_keyblock *keyblock ));
+krb5_error_code krb5_scc_store_data PROTOTYPE((krb5_ccache id , krb5_data *data ));
+krb5_error_code krb5_scc_store_int32 PROTOTYPE((krb5_ccache id , krb5_int32 *i ));
+krb5_error_code krb5_scc_store_ui_2 PROTOTYPE((krb5_ccache id , krb5_ui_2 *i ));
+krb5_error_code krb5_scc_store_keytype PROTOTYPE((krb5_ccache id , krb5_keytype *k ));
+krb5_error_code krb5_scc_store_int PROTOTYPE((krb5_ccache id , int *i ));
+krb5_error_code krb5_scc_store_bool PROTOTYPE((krb5_ccache id , krb5_boolean *b ));
+krb5_error_code krb5_scc_store_times PROTOTYPE((krb5_ccache id , krb5_ticket_times *t ));
+krb5_error_code krb5_scc_store_flags PROTOTYPE((krb5_ccache id , krb5_flags *f ));
+krb5_error_code krb5_scc_store_addrs PROTOTYPE((krb5_ccache , krb5_address ** ));
+krb5_error_code krb5_scc_store_addr PROTOTYPE((krb5_ccache , krb5_address * ));
+
+/* scc_errs.c */
+krb5_error_code krb5_scc_interpret PROTOTYPE((int ));
+
+#endif /* KRB5_SCC_PROTO__ */
diff --git a/src/lib/krb5/ccache/stdio/scc.h b/src/lib/krb5/ccache/stdio/scc.h
new file mode 100644 (file)
index 0000000..89edc99
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $Source$
+ * $Author$
+ * $Id$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains constant and function declarations used in the
+ * file-based credential cache routines.
+ */
+
+#include <krb5/copyright.h>
+
+#ifndef __KRB5_FILE_CCACHE__
+#define __KRB5_FILE_CCACHE__
+
+#include <krb5/krb5.h>
+#include <krb5/ext-proto.h>
+#include "scc-proto.h"
+#include <krb5/sysincl.h>
+#include <stdio.h>
+
+#define KRB5_OK 0
+
+#define KRB5_SCC_MAXLEN 100
+
+#ifndef TKT_ROOT
+#define TKT_ROOT "/tmp/tkt"
+#endif
+
+/* macros to make checking flags easier */
+#define OPENCLOSE(id) (((krb5_scc_data *)id->data)->flags & KRB5_TC_OPENCLOSE)
+
+typedef struct _krb5_scc_data {
+     char *filename;
+     FILE *file;
+     krb5_flags flags;
+     char stdio_buffer[BUFSIZ];
+} krb5_scc_data;
+
+/* An off_t can be arbitrarily complex */
+typedef struct _krb5_scc_cursor {
+    long pos;
+} krb5_scc_cursor;
+
+#define MAYBE_OPEN(ID, MODE) \
+{                                                                      \
+    if (OPENCLOSE (ID)) {                                              \
+       krb5_error_code maybe_open_ret = krb5_scc_open_file (ID,MODE);  \
+       if (maybe_open_ret) return maybe_open_ret; } }
+
+#define MAYBE_CLOSE(ID, RET) \
+{                                                                      \
+    if (OPENCLOSE (ID)) {                                              \
+       krb5_error_code maybe_close_ret = krb5_scc_close_file (ID);     \
+       if (!(RET)) RET = maybe_close_ret; } }
+
+/* DO NOT ADD ANYTHING AFTER THIS #endif */
+#endif /* __KRB5_FILE_CCACHE__ */
diff --git a/src/lib/krb5/ccache/stdio/scc_close.c b/src/lib/krb5/ccache/stdio/scc_close.c
new file mode 100644 (file)
index 0000000..d4b0b01
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_close.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_close_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Modifies:
+ * id
+ *
+ * Effects:
+ * Closes the file cache, invalidates the id, and frees any resources
+ * associated with the cache.
+ */
+krb5_error_code
+krb5_scc_close(id)
+   krb5_ccache id;
+{
+     register int closeval = KRB5_OK;
+     register krb5_scc_data *data = (krb5_scc_data *) id->data;
+
+     if (!OPENCLOSE(id)) {
+        closeval = fclose (data->file);
+        data->file = 0;
+        if (closeval == -1) {
+            closeval = krb5_scc_interpret(errno);
+        } else
+            closeval = KRB5_OK;
+                
+     }
+     xfree (data->filename);
+     xfree (data);
+     xfree (id);
+
+     return closeval;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_defnam.c b/src/lib/krb5/ccache/stdio/scc_defnam.c
new file mode 100644 (file)
index 0000000..f18c2ba
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Ooops.  This file is completely unncessesary, I think.  <sigh>
+ *
+ * Barr3y
+ */
+
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_default_name.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_defnam_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include "scc.h"
+
+#include <krb5/copyright.h>
+
+static char krb5_default_name_string[KRB5_SCC_MAXLEN] = "";
+
+/*
+ * Effects:
+ * 
+ * Forms the default credential cache name for the current user, which
+ * is defined in the following way.  If it is set, the environment
+ * variable "KRB5CCACHE" will be used (up to the maximum number of
+ * characters of a legal operating system defined path).  Otherwise
+ * TKT_ROOT (from scc.h) and the user's uid are concatenated to
+ * produce the ticket file name (e.g., "/tmp/tkt123").  The pointer
+ * returned is to static storage; the name must be copied elsewhere.
+ */
+
+char *
+krb5_scc_default_name ()
+{
+     char *krb5ccache, *getenv();
+     int len;
+
+     /* Is the environment variable defined? */
+     krb5ccache = getenv("KRB5CCACHE");
+     if (krb5ccache != NULL) {
+         len = strlen(krb5ccache);
+         len = (len < sizeof(krb5_default_name_string) ? len :
+                sizeof(krb5_default_name_string));
+         
+         strncpy(krb5_default_name_string, krb5ccache, len);
+         krb5_default_name_string[len] = '\0';
+     }
+
+     /* No.  Use TKT_ROOT and uid */
+     else {
+         /* XXX It'd be nice if we didn't have to pull in printf */
+         sprintf(krb5_default_name_string, "%s%d", TKT_ROOT, getuid());
+     }
+
+     return krb5_default_name_string;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_defops.c b/src/lib/krb5/ccache/stdio/scc_defops.c
new file mode 100644 (file)
index 0000000..206c769
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the structure krb5_cc_dfl_ops.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_defops_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+krb5_cc_ops krb5_cc_dfl_ops = {
+     "STDIO",
+     krb5_scc_get_name,
+     krb5_scc_resolve,
+     krb5_scc_generate_new,
+     krb5_scc_initialize,
+     krb5_scc_destroy,
+     krb5_scc_close,
+     krb5_scc_store,
+     krb5_scc_retrieve,
+     krb5_scc_get_principal,
+     krb5_scc_start_seq_get,
+     krb5_scc_next_cred,
+     krb5_scc_end_seq_get,
+     NULL, /* XXX krb5_scc_remove, */
+     krb5_scc_set_flags,
+};
diff --git a/src/lib/krb5/ccache/stdio/scc_destry.c b/src/lib/krb5/ccache/stdio/scc_destry.c
new file mode 100644 (file)
index 0000000..be29366
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_destroy.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_destry_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+/*
+ * Effects:
+ * Destroys the contents of id.
+ *
+ * Errors:
+ * system errors
+ */
+krb5_error_code krb5_scc_destroy(id)
+   krb5_ccache id;
+{
+     unsigned long size;
+     char zeros[BUFSIZ];
+     krb5_scc_data *data = (krb5_scc_data *) id->data;
+     register int ret;
+     
+     if (!OPENCLOSE(id)) {
+        (void) fclose(data->file);
+        data->file = 0;
+     }
+
+     ret = remove (data->filename);
+     if (ret < 0) {
+        ret = krb5_scc_interpret(errno);
+        if (OPENCLOSE(id)) {
+            (void) fclose(data->file);
+            data->file = 0;
+        }
+        return ret;
+     }
+
+#if 0
+     /*
+      * Possible future extension: Read entire file to determine
+      * length, then write nulls all over it.  This was the UNIX
+      * version...
+      */
+     ret = fstat(fileno(data->file), &buf);
+     if (ret < 0) {
+        ret = krb5_scc_interpret(errno);
+        if (OPENCLOSE(id)) {
+            (void) fclose(data->file);
+            data->file = 0;
+        }
+        return ret;
+     }
+
+     /* XXX This may not be legal XXX */
+     size = (unsigned long) buf.st_size;
+
+     bzero(zeros, BUFSIZ);
+     for (i=0; i < size / BUFSIZ; i++)
+         if (fwrite(data->file, zeros, BUFSIZ) < 0) {
+             ret = krb5_scc_interpret(errno);
+             if (OPENCLOSE(id)) {
+                 (void) fclose(data->file);
+                 data->file = 0;
+             }
+             return ret;
+         }
+
+     if (fwrite(data->file, zeros, size % BUFSIZ) < 0) {
+        ret = krb5_scc_interpret(errno);
+        if (OPENCLOSE(id)) {
+            (void) fclose(data->file);
+            data->file = 0;
+        }
+        return ret;
+     }
+     
+     ret = fclose(data->file);
+     data->file = 0;
+#endif
+
+     if (ret)
+        ret = krb5_scc_interpret(errno);
+
+     return ret;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_errs.c b/src/lib/krb5/ccache/stdio/scc_errs.c
new file mode 100644 (file)
index 0000000..c0b13f0
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * error code interpretation routine
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_errs_c [] =
+"$Id$";
+#endif /* !lint & !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+krb5_error_code
+krb5_scc_interpret(errnum)
+int errnum;
+{
+    register int retval;
+    switch (errnum) {
+    case ENOENT:
+       retval = KRB5_FCC_NOFILE;
+       break;
+    case EPERM:
+    case EACCES:
+    case EISDIR:
+    case ENOTDIR:
+    case ELOOP:                                /* XXX */
+    case ETXTBSY:
+    case EBUSY:
+    case EROFS:
+       retval = KRB5_FCC_PERM;
+       break;
+    case EINVAL:
+    case EEXIST:                       /* XXX */
+    case EFAULT:
+    case EBADF:
+    case ENAMETOOLONG:
+#ifdef EWOULDBLOCK
+    case EWOULDBLOCK:
+#endif
+       retval = KRB5_FCC_INTERNAL;
+       break;
+#ifdef EDQUOT
+    case EDQUOT:
+#endif
+    case ENOSPC:
+    case EIO:
+    case ENFILE:
+    case EMFILE:
+    case ENXIO:
+    default:
+       retval = KRB5_CC_IO;            /* XXX */
+    }
+    return retval;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_eseq.c b/src/lib/krb5/ccache/stdio/scc_eseq.c
new file mode 100644 (file)
index 0000000..ff51acc
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_end_seq_get.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_eseq_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+#include "scc.h"
+
+/*
+ * Requires:
+ * cursor is a krb5_cc_cursor originally obtained from
+ * krb5_scc_start_seq_get.
+ *
+ * Modifies:
+ * id, cursor
+ *
+ * Effects:
+ * Finishes sequential processing of the file credentials ccache id,
+ * and invalidates the cursor (it must never be used after this call).
+ */
+/* ARGSUSED */
+krb5_error_code
+krb5_scc_end_seq_get(id, cursor)
+   krb5_ccache id;
+   krb5_cc_cursor *cursor;
+{
+    int ret = KRB5_OK;
+/*    MAYBE_CLOSE (id, ret);*/
+
+    xfree((krb5_scc_cursor *) *cursor);
+
+    return ret;
+}
+
+
diff --git a/src/lib/krb5/ccache/stdio/scc_gennew.c b/src/lib/krb5/ccache/stdio/scc_gennew.c
new file mode 100644 (file)
index 0000000..9a98d71
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_generate_new.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_resolve_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include "scc.h"
+
+#include <krb5/copyright.h>
+
+extern krb5_cc_ops krb5_scc_ops;
+
+/*
+ * Effects:
+ * Creates a new file cred cache whose name is guaranteed to be
+ * unique.  The name begins with the string TKT_ROOT (from scc.h).
+ * The cache is not opened, but the new filename is reserved.
+ *  
+ * Returns:
+ * The filled in krb5_ccache id.
+ *
+ * Errors:
+ * KRB5_CC_NOMEM - there was insufficient memory to allocate the
+ *             krb5_ccache.  id is undefined.
+ * system errors (from open)
+ */
+krb5_error_code
+krb5_scc_generate_new (id)
+   krb5_ccache *id;
+{
+     krb5_ccache lid;
+     FILE *f;
+     char scratch[100];  /* XXX Is this large enough */
+     
+     /* Allocate memory */
+     lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
+     if (lid == NULL)
+         return KRB5_CC_NOMEM;
+
+     lid->ops = &krb5_scc_ops;
+
+     sprintf(scratch, "%sXXXXXX", TKT_ROOT);
+     mktemp(scratch);
+
+     lid->data = (krb5_pointer) malloc(sizeof(krb5_scc_data));
+     if (lid->data == NULL) {
+         xfree(lid);
+         return KRB5_CC_NOMEM;
+     }
+
+     ((krb5_scc_data *) lid->data)->filename = (char *)
+         malloc(strlen(scratch) + 1);
+     if (((krb5_scc_data *) lid->data)->filename == NULL) {
+         xfree(((krb5_scc_data *) lid->data));
+         xfree(lid);
+         return KRB5_CC_NOMEM;
+     }
+
+     ((krb5_scc_data *) lid->data)->flags = 0;
+     
+     /* Set up the filename */
+     strcpy(((krb5_scc_data *) lid->data)->filename, scratch);
+
+     /* Make sure the file name is useable */
+     f = fopen (((krb5_scc_data *) lid->data)->filename, "w+");
+     if (!f)
+        return krb5_scc_interpret (errno);
+     else {
+        fclose(f);
+        *id = lid;
+        return KRB5_OK;
+     }
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_getnam.c b/src/lib/krb5/ccache/stdio/scc_getnam.c
new file mode 100644 (file)
index 0000000..50af7ae
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_get_name.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_getnam_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Requires:
+ * id is a file credential cache
+ * 
+ * Returns:
+ * The name of the file cred cache id.
+ */
+char *
+krb5_scc_get_name (id)
+   krb5_ccache id;
+{
+     return (char *) ((krb5_scc_data *) id->data)->filename;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_gprin.c b/src/lib/krb5/ccache/stdio/scc_gprin.c
new file mode 100644 (file)
index 0000000..7b8dad8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_get_principal.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_gprinc_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+#include "scc.h"
+
+/*
+ * Modifies:
+ * id, princ
+ *
+ * Effects:
+ * Retrieves the primary principal from id, as set with
+ * krb5_scc_initialize.  The principal is returned is allocated
+ * storage that must be freed by the caller via krb5_free_principal.
+ *
+ * Errors:
+ * system errors
+ * KRB5_CC_NOMEM
+ */
+krb5_error_code
+krb5_scc_get_principal(id, princ)
+   krb5_ccache id;
+   krb5_principal *princ;
+{
+     krb5_error_code kret;
+
+     MAYBE_OPEN (id, "r");
+     fseek(((krb5_scc_data *) id->data)->file, 0, 0);
+
+     kret = krb5_scc_read_principal(id, princ);
+
+     MAYBE_CLOSE (id, kret);
+     return kret;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_init.c b/src/lib/krb5/ccache/stdio/scc_init.c
new file mode 100644 (file)
index 0000000..ba37877
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_initialize.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_init_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Modifies:
+ * id
+ *
+ * Effects:
+ * Creates/refreshes the file cred cache id.  If the cache exists, its
+ * contents ae destroyed.
+ *
+ * Errors:
+ * system errors
+ * permission errors
+ */
+krb5_error_code
+krb5_scc_initialize(id, princ)
+   krb5_ccache id;
+   krb5_principal princ;
+{
+     int ret;
+
+     ret = krb5_scc_open_file (id, "w+");
+     if (ret < 0)
+         return krb5_scc_interpret(errno);
+
+#if 0
+     ret = fchmod(((krb5_scc_data *) id->data)->fd, S_IREAD | S_IWRITE);
+     if (ret == -1) {
+        ret = krb5_scc_interpret(errno);
+        if (OPENCLOSE(id)) {
+            close(((krb5_scc_data *)id->data)->fd);
+            ((krb5_scc_data *) id->data)->fd = -1;
+        }
+        return ret;
+     }
+#endif
+     krb5_scc_store_principal(id, princ);
+
+     MAYBE_CLOSE (id, ret);
+     return ret;
+}
+
+
diff --git a/src/lib/krb5/ccache/stdio/scc_maybe.c b/src/lib/krb5/ccache/stdio/scc_maybe.c
new file mode 100644 (file)
index 0000000..f684f11
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for conditional open/close calls.
+ */
+
+#include "scc.h"
+
+krb5_error_code
+krb5_scc_close_file (id)
+    krb5_ccache id;
+{
+     krb5_scc_data *data;
+     int ret;
+
+     data = (krb5_scc_data *) id->data;
+     if (data->file == (FILE *) NULL) {
+        abort ();
+     }
+     ret = fflush (data->file);
+     bzero (data->stdio_buffer, sizeof (data->stdio_buffer));
+     if (ret) {
+         (void) fclose (data->file);
+         data->file = 0;
+         return krb5_scc_interpret (errno);
+     }
+     ret = fclose (data->file);
+     data->file = 0;
+     return ret ? krb5_scc_interpret (errno) : 0;
+}
+
+krb5_error_code
+krb5_scc_open_file (id, mode)
+    krb5_ccache id;
+    const char *mode;
+{
+     krb5_scc_data *data;
+     FILE *f;
+     int ret;
+
+     data = (krb5_scc_data *) id->data;
+     if (data->file) {
+         /* Don't know what state it's in; shut down and start anew.  */
+         (void) fclose (data->file);
+         data->file = 0;
+     }
+     f = fopen (data->filename, mode);
+     if (!f)
+         return krb5_scc_interpret (errno);
+     setbuf (f, data->stdio_buffer);
+#if 0 /* alternative, not requiring sizeof stdio_buffer == BUFSIZ */
+     setvbuf(f, data->stdio_buffer, _IOFBF, sizeof (data->stdio_buffer));
+#endif
+     data->file = f;
+     return 0;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_nseq.c b/src/lib/krb5/ccache/stdio/scc_nseq.c
new file mode 100644 (file)
index 0000000..ce8bf50
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_next_cred.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_nseq_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/* XXX Deal with kret values */
+
+/*
+ * Requires:
+ * cursor is a krb5_cc_cursor originally obtained from
+ * krb5_scc_start_seq_get.
+ *
+ * Modifes:
+ * cursor, creds
+ * 
+ * Effects:
+ * Fills in creds with the "next" credentals structure from the cache
+ * id.  The actual order the creds are returned in is arbitrary.
+ * Space is allocated for the variable length fields in the
+ * credentials structure, so the object returned must be passed to
+ * krb5_destroy_credential.
+ *
+ * The cursor is updated for the next call to krb5_scc_next_cred.
+ *
+ * Errors:
+ * system errors
+ */
+krb5_error_code
+krb5_scc_next_cred(id, cursor, creds)
+   krb5_ccache id;
+   krb5_cc_cursor *cursor;
+   krb5_creds *creds;
+{
+#define TCHECK(ret) if (ret != KRB5_OK) goto lose;
+     int ret;
+     krb5_error_code kret;
+     krb5_scc_cursor *fcursor;
+
+     bzero((char *)creds, sizeof(*creds));
+
+     MAYBE_OPEN (id, "r");
+
+     fcursor = (krb5_scc_cursor *) *cursor;
+     ret = fseek(((krb5_scc_data *) id->data)->file, fcursor->pos, 0);
+     if (ret < 0) {
+        ret = krb5_scc_interpret(errno);
+        MAYBE_CLOSE (id, ret);
+        return ret;
+     }
+
+     kret = krb5_scc_read_principal(id, &creds->client);
+     TCHECK(kret);
+     kret = krb5_scc_read_principal(id, &creds->server);
+     TCHECK(kret);
+     kret = krb5_scc_read_keyblock(id, &creds->keyblock);
+     TCHECK(kret);
+     kret = krb5_scc_read_times(id, &creds->times);
+     TCHECK(kret);
+     kret = krb5_scc_read_bool(id, &creds->is_skey);
+     TCHECK(kret);
+     kret = krb5_scc_read_flags(id, &creds->ticket_flags);
+     TCHECK(kret);
+     kret = krb5_scc_read_addrs(id, &creds->addresses);
+     TCHECK(kret);
+     kret = krb5_scc_read_data(id, &creds->ticket);
+     TCHECK(kret);
+     kret = krb5_scc_read_data(id, &creds->second_ticket);
+     TCHECK(kret);
+     
+     fcursor->pos = ftell(((krb5_scc_data *) id->data)->file);
+     cursor = (krb5_cc_cursor *) fcursor;
+
+lose:
+     if (kret != KRB5_OK) {
+        if (creds->client)
+            krb5_free_principal(creds->client);
+        if (creds->server)
+            krb5_free_principal(creds->server);
+        if (creds->keyblock.contents)
+            xfree(creds->keyblock.contents);
+        if (creds->ticket.data)
+            xfree(creds->ticket.data);
+        if (creds->second_ticket.data)
+            xfree(creds->second_ticket.data);
+        if (creds->addresses)
+            krb5_free_address(creds->addresses);
+     }
+     MAYBE_CLOSE (id, kret);
+     return kret;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_ops.c b/src/lib/krb5/ccache/stdio/scc_ops.c
new file mode 100644 (file)
index 0000000..3110217
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the structure krb5_scc_ops.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_ops_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+krb5_cc_ops krb5_scc_ops = {
+     "STDIO",
+     krb5_scc_get_name,
+     krb5_scc_resolve,
+     krb5_scc_generate_new,
+     krb5_scc_initialize,
+     krb5_scc_destroy,
+     krb5_scc_close,
+     krb5_scc_store,
+     krb5_scc_retrieve,
+     krb5_scc_get_principal,
+     krb5_scc_start_seq_get,
+     krb5_scc_next_cred,
+     krb5_scc_end_seq_get,
+     NULL, /* XXX krb5_scc_remove, */
+     krb5_scc_set_flags,
+};
+
+
+
+
+     
+
+
+
diff --git a/src/lib/krb5/ccache/stdio/scc_read.c b/src/lib/krb5/ccache/stdio/scc_read.c
new file mode 100644 (file)
index 0000000..481b501
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for reading variables from a
+ * credentials cache.  These are not library-exported functions.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_read_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+#include "scc.h"
+
+#define CHECK(ret) if (ret != KRB5_OK) goto errout;
+     
+/*
+ * Effects:
+ * Reads len bytes from the cache id, storing them in buf.
+ *
+ * Errors:
+ * KRB5_CC_END - there were not len bytes available
+ * system errors (read)
+ */
+krb5_error_code
+krb5_scc_read(id, buf, len)
+   krb5_ccache id;
+   krb5_pointer buf;
+   int len;
+{
+     int ret;
+
+     ret = fread((char *) buf, 1, len, ((krb5_scc_data *) id->data)->file);
+     if (ret == -1)
+         return krb5_scc_interpret(errno);
+     else if (ret != len)
+         return KRB5_CC_END;
+     else
+         return KRB5_OK;
+}
+
+/*
+ * FOR ALL OF THE FOLLOWING FUNCTIONS:
+ *
+ * Requires:
+ * id is open and set to read at the appropriate place in the file
+ *
+ * Effects:
+ * Fills in the second argument with data of the appropriate type from
+ * the file.  In some cases, the functions have to allocate space for
+ * variable length fields; therefore, krb5_destroy_<type> must be
+ * called for each filled in structure.
+ *
+ * Errors:
+ * system errors (read errors)
+ * KRB5_CC_NOMEM
+ */
+
+krb5_error_code
+krb5_scc_read_principal(id, princ)
+   krb5_ccache id;
+   krb5_principal *princ;
+{
+     krb5_error_code kret;
+     krb5_int32 length;
+     int i;
+
+     *princ = 0;
+
+     /* Read the number of components */
+     kret = krb5_scc_read_int32(id, &length);
+     CHECK(kret);
+
+     /*
+      * The # of levels of indirection is confusing.  A krb5_principal
+      * is an array of pointers to krb5_data.  princ is a pointer to
+      * an array of pointers to krb5_data.  (*princ)[i] a pointer to
+      * krb5_data.
+      */
+
+     /* Make *princ able to hold length pointers to krb5_data structs
+      * Add one extra for a null-terminated list
+      */
+     *princ = (krb5_principal) calloc(length+1, sizeof(krb5_data *));
+     if (*princ == NULL)
+         return KRB5_CC_NOMEM;
+
+     for (i=0; i < length; i++) {
+         (*princ)[i] = (krb5_data *) malloc(sizeof(krb5_data));
+         if ((*princ)[i] == NULL) {
+             krb5_free_principal(*princ);
+             return KRB5_CC_NOMEM;
+          }      
+         kret = krb5_scc_read_data(id, (*princ)[i]);
+         CHECK(kret);
+     }
+
+     return kret;
+ errout:
+     if (*princ)
+        krb5_free_principal(*princ);
+     return kret;
+}
+
+krb5_error_code
+krb5_scc_read_addrs(id, addrs)
+   krb5_ccache id;
+   krb5_address ***addrs;
+{
+     krb5_error_code kret;
+     krb5_int32 length;
+     int i;
+
+     *addrs = 0;
+
+     /* Read the number of components */
+     kret = krb5_scc_read_int32(id, &length);
+     CHECK(kret);
+
+     /* Make *addrs able to hold length pointers to krb5_address structs
+      * Add one extra for a null-terminated list
+      */
+     *addrs = (krb5_address **) calloc(length+1, sizeof(krb5_address *));
+     if (*addrs == NULL)
+         return KRB5_CC_NOMEM;
+
+     for (i=0; i < length; i++) {
+         (*addrs)[i] = (krb5_address *) malloc(sizeof(krb5_address));
+         if ((*addrs)[i] == NULL) {
+             krb5_free_address(*addrs);
+             return KRB5_CC_NOMEM;
+         }       
+         kret = krb5_scc_read_addr(id, (*addrs)[i]);
+         CHECK(kret);
+     }
+
+     return KRB5_OK;
+ errout:
+     if (*addrs)
+        krb5_free_address(*addrs);
+     return kret;
+}
+
+krb5_error_code
+krb5_scc_read_keyblock(id, keyblock)
+   krb5_ccache id;
+   krb5_keyblock *keyblock;
+{
+     krb5_error_code kret;
+     int ret;
+
+     keyblock->contents = 0;
+
+     kret = krb5_scc_read_keytype(id, &keyblock->keytype);
+     CHECK(kret);
+     kret = krb5_scc_read_int(id, &keyblock->length);
+     CHECK(kret);
+     keyblock->contents = (unsigned char *) malloc(keyblock->length*
+                                                  sizeof(krb5_octet));
+     if (keyblock->contents == NULL)
+         return KRB5_CC_NOMEM;
+     
+     ret = fread((char *)keyblock->contents, 1,
+                (keyblock->length)*sizeof(krb5_octet),
+                ((krb5_scc_data *) id->data)->file);
+
+     if (ret < 0) {
+        xfree(keyblock->contents);
+        return krb5_scc_interpret(errno);
+     }
+     if (ret != (keyblock->length)*sizeof(krb5_octet)) {
+        xfree(keyblock->contents);
+        return KRB5_CC_END;
+     }
+
+     return KRB5_OK;
+ errout:
+     if (keyblock->contents)
+        xfree(keyblock->contents);
+     return kret;
+}
+
+krb5_error_code
+krb5_scc_read_data(id, data)
+   krb5_ccache id;
+   krb5_data *data;
+{
+     krb5_error_code kret;
+     int ret;
+
+     data->data = 0;
+
+     kret = krb5_scc_read_int32(id, &data->length);
+     CHECK(kret);
+
+     data->data = (char *) malloc(data->length);
+     if (data->data == NULL)
+         return KRB5_CC_NOMEM;
+
+     ret = fread((char *)data->data, 1,
+                data->length, ((krb5_scc_data *) id->data)->file);
+     if (ret == -1) {
+        xfree(data->data);
+        return krb5_scc_interpret(errno);
+     }
+     if (ret != data->length) {
+        xfree(data->data);
+        return KRB5_CC_END;
+     }
+     return KRB5_OK;
+ errout:
+     if (data->data)
+        xfree(data->data);
+     return kret;
+}
+
+krb5_error_code
+krb5_scc_read_addr(id, addr)
+   krb5_ccache id;
+   krb5_address *addr;
+{
+     krb5_error_code kret;
+     int ret;
+
+     addr->contents = 0;
+
+     kret = krb5_scc_read_ui_2(id, &addr->addrtype);
+     CHECK(kret);
+
+     kret = krb5_scc_read_int(id, &addr->length);
+     CHECK(kret);
+
+     addr->contents = (krb5_octet *) malloc(addr->length);
+     if (addr->contents == NULL)
+         return KRB5_CC_NOMEM;
+
+     ret = fread((char *)addr->contents, 1, (addr->length)*sizeof(krb5_octet),
+                ((krb5_scc_data *) id->data)->file);
+     if (ret == -1) {
+         xfree(addr->contents);
+         return krb5_scc_interpret(errno);
+     }
+     if (ret != (addr->length)*sizeof(krb5_octet)) {
+         xfree(addr->contents);
+         return KRB5_CC_END;
+     }
+     return KRB5_OK;
+ errout:
+     if (addr->contents)
+        xfree(addr->contents);
+     return kret;
+}
+
+krb5_error_code
+krb5_scc_read_int32(id, i)
+   krb5_ccache id;
+   krb5_int32 *i;
+{
+     return krb5_scc_read(id, (krb5_pointer) i, sizeof(krb5_int32));
+}
+
+krb5_error_code
+krb5_scc_read_ui_2(id, i)
+   krb5_ccache id;
+   krb5_ui_2 *i;
+{
+     return krb5_scc_read(id, (krb5_pointer) i, sizeof(krb5_ui_2));
+}
+
+krb5_error_code
+krb5_scc_read_keytype(id, k)
+   krb5_ccache id;
+   krb5_keytype *k;
+{
+     return krb5_scc_read(id, (krb5_pointer) k, sizeof(krb5_keytype));
+}
+
+krb5_error_code
+krb5_scc_read_int(id, i)
+   krb5_ccache id;
+   int *i;
+{
+     return krb5_scc_read(id, (krb5_pointer) i, sizeof(int));
+}
+
+krb5_error_code
+krb5_scc_read_bool(id, b)
+   krb5_ccache id;
+   krb5_boolean *b;
+{
+     return krb5_scc_read(id, (krb5_pointer) b, sizeof(krb5_boolean));
+}
+
+krb5_error_code
+krb5_scc_read_times(id, t)
+   krb5_ccache id;
+   krb5_ticket_times *t;
+{
+     return krb5_scc_read(id, (krb5_pointer) t, sizeof(krb5_ticket_times));
+}
+
+krb5_error_code
+krb5_scc_read_flags(id, f)
+   krb5_ccache id;
+   krb5_flags *f;
+{
+     return krb5_scc_read(id, (krb5_pointer) f, sizeof(krb5_flags));
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_reslv.c b/src/lib/krb5/ccache/stdio/scc_reslv.c
new file mode 100644 (file)
index 0000000..6c05be4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_resolve.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_reslve_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+extern krb5_cc_ops krb5_scc_ops;
+
+/*
+ * Requires:
+ * residual is a legal path name, and a null-terminated string
+ *
+ * Modifies:
+ * id
+ * 
+ * Effects:
+ * creates a file-based cred cache that will reside in the file
+ * residual.  The cache is not opened, but the filename is reserved.
+ * 
+ * Returns:
+ * A filled in krb5_ccache structure "id".
+ *
+ * Errors:
+ * KRB5_CC_NOMEM - there was insufficient memory to allocate the
+ *             krb5_ccache.  id is undefined.
+ * permission errors
+ */
+krb5_error_code
+krb5_scc_resolve (id, residual)
+   krb5_ccache *id;
+   char *residual;
+{
+     krb5_ccache lid;
+     
+     lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
+     if (lid == NULL)
+         return KRB5_CC_NOMEM;
+
+     lid->ops = &krb5_scc_ops;
+     
+     lid->data = (krb5_pointer) malloc(sizeof(krb5_scc_data));
+     if (lid->data == NULL) {
+         xfree(lid);
+         return KRB5_CC_NOMEM;
+     }
+
+     ((krb5_scc_data *) lid->data)->filename = (char *)
+         malloc(strlen(residual) + 1);
+
+     if (((krb5_scc_data *) lid->data)->filename == NULL) {
+         xfree(((krb5_scc_data *) lid->data));
+         xfree(lid);
+         return KRB5_CC_NOMEM;
+     }
+
+     /* default to open/close on every trn */
+     ((krb5_scc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE;
+     ((krb5_scc_data *) lid->data)->file = 0;
+     
+     /* Set up the filename */
+     strcpy(((krb5_scc_data *) lid->data)->filename, residual);
+
+     /* other routines will get errors on open, and callers must expect them,
+       if cache is non-existent/unusable */
+     *id = lid;
+     return KRB5_OK;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_retrv.c b/src/lib/krb5/ccache/stdio/scc_retrv.c
new file mode 100644 (file)
index 0000000..21045ef
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_retrieve.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_retrv_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+#define set(bits) (whichfields & bits)
+#define flags_match(a,b) (a & b == a)
+#define times_match_exact(t1,t2) (bcmp((char *)(t1), (char *)(t2), sizeof(*(t1))) == 0)
+
+static krb5_boolean times_match PROTOTYPE((const krb5_ticket_times *,
+                                          const krb5_ticket_times *));
+static krb5_boolean standard_fields_match
+    PROTOTYPE((const krb5_creds *,
+              const krb5_creds *));
+/*
+ * Effects:
+ * Searches the file cred cache is for a credential matching mcreds,
+ * with the fields specified by whichfields.  If one if found, it is
+ * returned in creds, which should be freed by the caller with
+ * krb5_free_credentials().
+ * 
+ * The fields are interpreted in the following way (all constants are
+ * preceded by KRB5_TC_).  MATCH_IS_SKEY requires the is_skey field to
+ * match exactly.  MATCH_TIMES requires the requested lifetime to be
+ * at least as great as that specified; MATCH_TIMES_EXACT requires the
+ * requested lifetime to be exactly that specified.  MATCH_FLAGS
+ * requires only the set bits in mcreds be set in creds;
+ * MATCH_FLAGS_EXACT requires all bits to match.
+ *
+ * Errors:
+ * system errors
+ * permission errors
+ * KRB5_CC_NOMEM
+ */
+krb5_error_code
+krb5_scc_retrieve(id, whichfields, mcreds, creds)
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+     /* This function could be considerably faster if it kept indexing */
+     /* information.. sounds like a "next version" idea to me. :-) */
+
+     krb5_cc_cursor cursor;
+     krb5_error_code kret;
+     krb5_creds fetchcreds;
+
+     kret = krb5_scc_start_seq_get(id, &cursor);
+     if (kret != KRB5_OK)
+         return kret;
+
+     while ((kret = krb5_scc_next_cred(id, &cursor, &fetchcreds)) == KRB5_OK) {
+         if (standard_fields_match(mcreds, &fetchcreds)
+             &&
+             (! set(KRB5_TC_MATCH_IS_SKEY) ||
+              mcreds->is_skey == fetchcreds.is_skey)
+             &&
+             (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
+              mcreds->ticket_flags == fetchcreds.ticket_flags)
+             &&
+             (! set(KRB5_TC_MATCH_FLAGS) ||
+              flags_match(mcreds->ticket_flags, fetchcreds.ticket_flags))
+             &&
+             (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
+              times_match_exact(&mcreds->times, &fetchcreds.times))
+             &&
+             (! set(KRB5_TC_MATCH_TIMES) ||
+              times_match(&mcreds->times, &fetchcreds.times)))
+         {
+              krb5_scc_end_seq_get(id, &cursor);
+              *creds = fetchcreds;
+              return KRB5_OK;
+         }
+
+         /* This one doesn't match */
+         /* XXX krb5_free_credentials(creds); */
+     }
+
+     /* If we get here, a match wasn't found */
+     krb5_scc_end_seq_get(id, &cursor);
+     return KRB5_CC_NOTFOUND;
+}
+
+static krb5_boolean
+times_match(t1, t2)
+register const krb5_ticket_times *t1;
+register const krb5_ticket_times *t2;
+{
+    if (t1->renew_till) {
+       if (t1->renew_till > t2->renew_till)
+           return FALSE;               /* this one expires too late */
+    }
+    if (t1->endtime) {
+       if (t1->endtime > t2->endtime)
+           return FALSE;               /* this one expires too late */
+    }
+    /* only care about expiration on a times_match */
+    return TRUE;
+}
+
+static krb5_boolean
+standard_fields_match(mcreds, creds)
+register const krb5_creds *mcreds, *creds;
+{
+    return (krb5_principal_compare(mcreds->client,creds->client) &&
+           krb5_principal_compare(mcreds->server,creds->server));
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_sflags.c b/src/lib/krb5/ccache/stdio/scc_sflags.c
new file mode 100644 (file)
index 0000000..2d0db8a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_set_flags.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_set_flags_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Requires:
+ * id is a cred cache returned by krb5_scc_resolve or
+ * krb5_scc_generate_new, but has not been opened by krb5_scc_initialize.
+ *
+ * Modifies:
+ * id
+ * 
+ * Effects:
+ * Sets the operational flags of id to flags.
+ */
+krb5_error_code
+krb5_scc_set_flags(id, flags)
+   krb5_ccache id;
+   krb5_flags flags;
+{
+    krb5_error_code ret = 0;
+
+    /* XXX This should check for illegal combinations, if any.. */
+    if (flags & KRB5_TC_OPENCLOSE) {
+       /* asking to turn on OPENCLOSE mode */
+       if (!OPENCLOSE(id))
+           ret = krb5_scc_close_file (id);
+    } else {
+       /* asking to turn off OPENCLOSE mode, meaning it must be
+          left open.  We open if it's not yet open */
+       if (OPENCLOSE(id)) {
+           ret = krb5_scc_open_file (id, "r+");
+       }
+    }
+
+    ((krb5_scc_data *) id->data)->flags = flags;
+    return ret;
+}
+
diff --git a/src/lib/krb5/ccache/stdio/scc_skip.c b/src/lib/krb5/ccache/stdio/scc_skip.c
new file mode 100644 (file)
index 0000000..bd14c35
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for reading variables from a
+ * credentials cache.  These are not library-exported functions.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_read_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+#include "scc.h"
+
+krb5_error_code
+krb5_scc_skip_principal(id)
+   krb5_ccache id;
+{
+     krb5_error_code kret;
+     krb5_principal princ;
+
+     kret = krb5_scc_read_principal(id, &princ);
+     if (kret != KRB5_OK)
+         return kret;
+
+     /* XXX krb5_destroy_principal(&princ); */
+     return KRB5_OK;
+}
+
+     
diff --git a/src/lib/krb5/ccache/stdio/scc_sseq.c b/src/lib/krb5/ccache/stdio/scc_sseq.c
new file mode 100644 (file)
index 0000000..cab7c9d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_start_seq_get.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_sseq_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Effects:
+ * Prepares for a sequential search of the credentials cache.
+ * Returns and krb5_cc_cursor to be used with krb5_scc_next_cred and
+ * krb5_scc_end_seq_get.
+ *
+ * If the cache is modified between the time of this call and the time
+ * of the final krb5_scc_end_seq_get, the results are undefined.
+ *
+ * Errors:
+ * KRB5_CC_NOMEM
+ * system errors
+ */
+krb5_error_code
+krb5_scc_start_seq_get(id, cursor)
+   krb5_ccache id;
+   krb5_cc_cursor *cursor;
+{
+     krb5_scc_cursor *fcursor;
+     int ret = 0;
+     
+     fcursor = (krb5_scc_cursor *) malloc(sizeof(krb5_scc_cursor));
+     if (fcursor == NULL)
+         return KRB5_CC_NOMEM;
+
+     /* Make sure we start reading right after the primary principal */
+     MAYBE_OPEN (id, "r");
+     fseek(((krb5_scc_data *) id->data)->file, 0, 0);
+
+     krb5_scc_skip_principal(id);
+     fcursor->pos = ftell(((krb5_scc_data *) id->data)->file);
+     *cursor = (krb5_cc_cursor) fcursor;
+
+     MAYBE_CLOSE (id, ret);
+     return KRB5_OK;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_store.c b/src/lib/krb5/ccache/stdio/scc_store.c
new file mode 100644 (file)
index 0000000..24189d8
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_store.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_scc_store_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+/*
+ * Modifies:
+ * the file cache
+ *
+ * Effects:
+ * stores creds in the file cred cache
+ *
+ * Errors:
+ * system errors
+ * storage failure errors
+ */
+krb5_error_code
+krb5_scc_store(id, creds)
+   krb5_ccache id;
+   krb5_creds *creds;
+{
+#define TCHECK(ret) if (ret != KRB5_OK) goto lose;
+     krb5_error_code ret;
+
+     /* Make sure we are writing to the end of the file */
+     MAYBE_OPEN (id, "r+");
+
+     ret = fseek(((krb5_scc_data *) id->data)->file, 0, 2);
+     if (ret < 0)
+         return krb5_scc_interpret(errno);
+
+     ret = krb5_scc_store_principal(id, creds->client);
+     TCHECK(ret);
+     ret = krb5_scc_store_principal(id, creds->server);
+     TCHECK(ret);
+     ret = krb5_scc_store_keyblock(id, &creds->keyblock);
+     TCHECK(ret);
+     ret = krb5_scc_store_times(id, &creds->times);
+     TCHECK(ret);
+     ret = krb5_scc_store_bool(id, &creds->is_skey);
+     TCHECK(ret);
+     ret = krb5_scc_store_flags(id, &creds->ticket_flags);
+     TCHECK(ret);
+     ret = krb5_scc_store_addrs(id, creds->addresses);
+     TCHECK(ret);
+     ret = krb5_scc_store_data(id, &creds->ticket);
+     TCHECK(ret);
+     ret = krb5_scc_store_data(id, &creds->second_ticket);
+     TCHECK(ret);
+
+lose:
+
+     MAYBE_CLOSE (id, ret);
+     return ret;
+#undef TCHECK
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_test.c b/src/lib/krb5/ccache/stdio/scc_test.c
new file mode 100644 (file)
index 0000000..64dfdda
--- /dev/null
@@ -0,0 +1,142 @@
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+krb5_data client1 = {
+#define DATA "client1-comp1"
+     sizeof(DATA),
+     DATA,
+#undef DATA
+};
+
+krb5_data client2 = {
+#define DATA "client1-comp2"
+     sizeof(DATA),
+     DATA,
+#undef DATA
+};
+
+krb5_data server1 = {
+#define DATA "server1-comp1"
+     sizeof(DATA),
+     DATA,
+#undef DATA
+};
+
+krb5_data server2 = {
+#define DATA "server1-comp2"
+     sizeof(DATA),
+     DATA,
+#undef DATA
+};
+
+int x = 0x12345;
+krb5_address addr = {
+    ADDRTYPE_INET,
+    4,
+    (krb5_octet *) &x,
+};
+
+krb5_address *addrs[] = {
+    &addr,
+    0,
+};
+
+krb5_creds test_creds = {
+     NULL,
+     NULL,
+     {
+         1,
+         1,
+         (unsigned char *) "1"
+     },
+     {
+         1111,
+         2222,
+         3333,
+         4444,
+     },
+     1,
+     5555,
+     addrs,
+     {
+#define TICKET "This is ticket 1"
+     sizeof(TICKET),
+     TICKET,
+#undef TICKET
+     },
+     {
+#define TICKET "This is ticket 2"
+     sizeof(TICKET),
+     TICKET,
+#undef TICKET
+     },
+};
+
+void init_test_cred()
+{
+     test_creds.client = (krb5_principal) malloc(sizeof(krb5_data *)*3);
+     test_creds.client[0] = &client1;
+     test_creds.client[1] = &client2;
+     test_creds.client[2] = NULL;
+
+     test_creds.server = (krb5_principal) malloc(sizeof(krb5_data *)*3);
+     test_creds.server[0] = &server1;
+     test_creds.server[1] = &server2;
+     test_creds.server[2] = NULL;
+}
+
+#define CHECK(kret,msg) \
+     if (kret != KRB5_OK) {\
+         com_err(msg, kret, "");\
+     } else printf("%s went ok\n", msg);
+                                                  
+int flags = 0;
+void scc_test()
+{
+     krb5_ccache id;
+     krb5_creds creds;
+     krb5_error_code kret;
+     krb5_cc_cursor cursor;
+
+     init_test_cred();
+
+     kret = krb5_scc_resolve(&id, "/tmp/tkt_test");
+     CHECK(kret, "resolve");
+     kret = krb5_scc_initialize(id, test_creds.client);
+     CHECK(kret, "initialize");
+     kret = krb5_scc_store(id, &test_creds);
+     CHECK(kret, "store");
+
+     kret = krb5_scc_set_flags (id, flags);
+     CHECK(kret, "set_flags");
+     kret = krb5_scc_start_seq_get(id, &cursor);
+     CHECK(kret, "start_seq_get");
+     kret = 0;
+     while (kret != KRB5_CC_END) {
+         printf("Calling next_cred\n");
+         kret = krb5_scc_next_cred(id, &cursor, &creds);
+         CHECK(kret, "next_cred");
+     }
+     kret = krb5_scc_end_seq_get(id, &cursor);
+     CHECK(kret, "end_seq_get");
+
+     kret = krb5_scc_close(id);
+     CHECK(kret, "close");
+
+
+     kret = krb5_scc_resolve(&id, "/tmp/tkt_test");
+     CHECK(kret, "resolve");
+     kret = krb5_scc_destroy(id);
+     CHECK(kret, "destroy");
+}
+
+int remove (s) char*s; { return unlink(s); }
+int main () {
+    initialize_krb5_error_table ();
+    init_test_cred ();
+    scc_test ();
+    flags = !flags;
+    scc_test ();
+    return 0;
+}
diff --git a/src/lib/krb5/ccache/stdio/scc_write.c b/src/lib/krb5/ccache/stdio/scc_write.c
new file mode 100644 (file)
index 0000000..901fec5
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * $Source$
+ * $Author$
+ *
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <krb5/copyright.h>.
+ *
+ * This file contains the source code for krb5_scc_write_<type>.
+ */
+
+#if !defined(lint) && !defined(SABER)
+static char rcsid_rcsid_scc_write_c[] = "$Id$";
+#endif /* !lint && !SABER */
+
+#include <krb5/copyright.h>
+
+#include "scc.h"
+
+#define CHECK(ret) if (ret != KRB5_OK) return ret;
+
+/*
+ * Requires:
+ * id is open
+ *
+ * Effects:
+ * Writes len bytes from buf into the file cred cache id.
+ *
+ * Errors:
+ * system errors
+ */
+krb5_error_code
+krb5_scc_write(id, buf, len)
+   krb5_ccache id;
+   krb5_pointer buf;
+   int len;
+{
+     int ret;
+
+     ret = fwrite((char *) buf, 1, len, ((krb5_scc_data *)id->data)->file);
+     if (ret == 0) {
+         return krb5_scc_interpret (errno);
+     }
+     return KRB5_OK;
+}
+
+/*
+ * FOR ALL OF THE FOLLOWING FUNCTIONS:
+ * 
+ * Requires:
+ * ((krb5_scc_data *) id->data)->file is open and at the right position.
+ * 
+ * Effects:
+ * Stores an encoded version of the second argument in the
+ * cache file.
+ *
+ * Errors:
+ * system errors
+ */
+
+krb5_error_code
+krb5_scc_store_principal(id, princ)
+   krb5_ccache id;
+   krb5_principal princ;
+{
+     krb5_error_code ret;
+     krb5_principal temp;
+     krb5_int32 i, length = 0;
+
+     /* Count the number of components */
+     temp = princ;
+     while (*temp++)
+         length += 1;
+
+     ret = krb5_scc_store_int32(id, &length);
+     CHECK(ret);
+     for (i=0; i < length; i++) {
+         ret = krb5_scc_store_data(id, princ[i]);
+         CHECK(ret);
+     }
+
+     return KRB5_OK;
+}
+
+krb5_error_code
+krb5_scc_store_addrs(id, addrs)
+   krb5_ccache id;
+   krb5_address ** addrs;
+{
+     krb5_error_code ret;
+     krb5_address **temp;
+     krb5_int32 i, length = 0;
+
+     /* Count the number of components */
+     temp = addrs;
+     while (*temp++)
+         length += 1;
+
+     ret = krb5_scc_store_int32(id, &length);
+     CHECK(ret);
+     for (i=0; i < length; i++) {
+         ret = krb5_scc_store_addr(id, addrs[i]);
+         CHECK(ret);
+     }
+
+     return KRB5_OK;
+}
+
+krb5_error_code
+krb5_scc_store_keyblock(id, keyblock)
+   krb5_ccache id;
+   krb5_keyblock *keyblock;
+{
+     krb5_error_code ret;
+
+     ret = krb5_scc_store_keytype(id, &keyblock->keytype);
+     CHECK(ret);
+     ret = krb5_scc_store_int(id, &keyblock->length);
+     CHECK(ret);
+     ret = fwrite((char *)keyblock->contents, 1,
+                 (keyblock->length)*sizeof(krb5_octet),
+                 ((krb5_scc_data *) id->data)->file);
+     if (ret == 0)
+         return krb5_scc_interpret(errno);
+     if (ret != (keyblock->length)*sizeof(krb5_octet))
+        return KRB5_CC_END;
+     
+     return KRB5_OK;
+}
+
+krb5_error_code
+krb5_scc_store_addr(id, addr)
+   krb5_ccache id;
+   krb5_address *addr;
+{
+     krb5_error_code ret;
+
+     ret = krb5_scc_store_ui_2(id, &addr->addrtype);
+     CHECK(ret);
+     ret = krb5_scc_store_int(id, &addr->length);
+     CHECK(ret);
+     ret = fwrite((char *)addr->contents, 1,
+                 (addr->length)*sizeof(krb5_octet),
+                 ((krb5_scc_data *) id->data)->file);
+     if (ret == 0)
+         return krb5_scc_interpret(errno);
+     if (ret != (addr->length)*sizeof(krb5_octet))
+        return KRB5_CC_END;
+     return KRB5_OK;
+}
+
+
+krb5_error_code
+krb5_scc_store_data(id, data)
+   krb5_ccache id;
+   krb5_data *data;
+{
+     krb5_error_code ret;
+
+     ret = krb5_scc_store_int32(id, &data->length);
+     CHECK(ret);
+     ret = fwrite(data->data, 1, data->length,
+                 ((krb5_scc_data *) id->data)->file);
+     if (ret == 0)
+         return krb5_scc_interpret(errno);
+
+     return KRB5_OK;
+}
+
+krb5_error_code
+krb5_scc_store_int32(id, i)
+   krb5_ccache id;
+   krb5_int32 *i;
+{
+     return krb5_scc_write(id, (char *) i, sizeof(krb5_int32));
+}
+
+krb5_error_code
+krb5_scc_store_ui_2(id, i)
+   krb5_ccache id;
+   krb5_ui_2 *i;
+{
+     return krb5_scc_write(id, (char *) i, sizeof(krb5_ui_2));
+}
+   
+krb5_error_code
+krb5_scc_store_keytype(id, k)
+   krb5_ccache id;
+   krb5_keytype *k;
+{
+     return krb5_scc_write(id, (char *) k, sizeof(krb5_keytype));
+}
+   
+krb5_error_code
+krb5_scc_store_int(id, i)
+   krb5_ccache id;
+   int *i;
+{
+     return krb5_scc_write(id, (char *) i, sizeof(int));
+}
+   
+krb5_error_code
+krb5_scc_store_bool(id, b)
+   krb5_ccache id;
+   krb5_boolean *b;
+{
+     return krb5_scc_write(id, (char *) b, sizeof(krb5_boolean));
+}
+   
+krb5_error_code
+krb5_scc_store_times(id, t)
+   krb5_ccache id;
+   krb5_ticket_times *t;
+{
+     return krb5_scc_write(id, (char *) t, sizeof(krb5_ticket_times));
+}
+   
+krb5_error_code
+krb5_scc_store_flags(id, f)
+   krb5_ccache id;
+   krb5_flags *f;
+{
+     return krb5_scc_write(id, (char *) f, sizeof(krb5_flags));
+}