krb5_scc_cc_?seq()

Nicolas Williams Nicolas.Williams at ubsw.com
Tue Jul 23 17:29:01 EDT 2002


Going back to the STDIO/FILE ccache implementations for a moment, I'd
like to produce a patch to ccbase.c and the SCC (buffered file ccache)
to improve sequencing performance on large ccaches.

Currently I'm making krb5_scc_cursor be a typedef for (krb5_ccache *) -
yes, I'm making the cursor be a separate ccache, with the openclose
flag off, opened separately and no more no-op ftell()/fseek()s.

It would be a [somewhat] smaller patch to just ignore the cursor,
drop the openclose flag at the start of a sequencing and restore
it at the end. It would also be less elegant, IMO, and non-reentrant
(though it wouldn't break anything, AFAICT). The current implementation
is reentrant (or ties to be), so I think I should keep to that.

As for ccbase.c, my patch may allow the runtime selection of FCC vs.
SCC implementation of FILE - SCC will be the default. The reasons for
not making this configure/compile time option are:

 - it's easier (i.e., no need to modify configure.in and friends)

 - STDIO on 32-bit Solaris is limited to 256 file descriptors; having
   been bitten by this more than once I would like the option to choose
   a non-buffered implementation on an app-by-app basis

The aim, for SCC, is to require one open/lock/unlock/close cycle and no
redundant seek()s while doing buffered I/O. For ccbase.c the aim is
to default to the SCC ccache implementation.

I note too that the SCC cc_destroy function doesn't overwrite the ccache
the way the FCC version does. And krb5_scc_close() needs to scrub the
scc ccache's STDIO buffer (the code therein for this is currently
ifdef'ed out and it is truly horrible).

Attached is an initial pass at the SCC side of the patch. It compiles
for me, but no doubt some effort has to be put into DOS/Windows/MacOS
compatibility (or else ccbase.c should default to FCC for those
platforms).

NOT TESTED! DO NOT USE - ALPHA, ALPHA patch.

Cheers,

Nico
-- 
-DISCLAIMER: an automatically appended disclaimer may follow. By posting-
-to a public e-mail mailing list I hereby grant permission to distribute-
-and copy this message.-

-------------- next part --------------
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_sseq.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_sseq.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_sseq.c Tue, 23 Jul 2002 16:27:25 -0400
@@ -51,24 +51,53 @@
    krb5_cc_cursor *cursor;
 {
      krb5_scc_cursor *fcursor;
+     krb5_ccache seq_id;
      int ret = 0;
      
-     fcursor = (krb5_scc_cursor *) malloc(sizeof(krb5_scc_cursor));
+     /* The cursor is a ccache! Yes, the krb5_scc_read*() functions
+      * work on a ccache and we need a separate FILE for sequencing,
+      * really. So a 2nd ccache is the way to go.
+      */
+     fcursor = (krb5_scc_cursor *) malloc(sizeof(krb5_ccache));
      if (fcursor == NULL)
-	  return KRB5_CC_NOMEM;
+	return KRB5_CC_NOMEM;
+
+     seq_id = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
+     if (seq_id == NULL) {
+	free(fcursor);
+	return KRB5_CC_NOMEM;
+     }
+     *fcursor = (krb5_scc_cursor) seq_id;
+
+     /* Set up the new ccache */
+     seq_id->magic = id->magic;
+     seq_id->data = malloc(sizeof(krb5_scc_data));
+     if (seq_id->data == NULL) {
+	free(seq_id);
+	free(fcursor);
+	return KRB5_CC_NOMEM;
+     }
+     ((krb5_scc_data *) seq_id->data)->filename =
+	 strdup(((krb5_scc_data *) id->data)->filename);
+     ((krb5_scc_data *) seq_id->data)->version =
+	 ((krb5_scc_data *) id->data)->version;
+     /* We don't want to open/close the seq cc on every call to nseq()! */
+     ((krb5_scc_data *) seq_id->data)->flags =
+	 ( ((krb5_scc_data *) id->data)->flags & ~KRB5_TC_OPENCLOSE);
 
      /* Make sure we start reading right after the primary principal */
-     MAYBE_OPEN (context, id, SCC_OPEN_RDONLY);
+     MAYBE_OPEN (context, seq_id, SCC_OPEN_RDONLY);
 
-     ret = krb5_scc_skip_header(context, id);
+     /* We skip the header and default principal for nseq() */
+     ret = krb5_scc_skip_header(context, seq_id);
      if (ret) goto done;
-     ret = krb5_scc_skip_principal(context, id);
+     ret = krb5_scc_skip_principal(context, seq_id);
      if (ret) goto done;
      
-     fcursor->pos = ftell(((krb5_scc_data *) id->data)->file);
-     *cursor = (krb5_cc_cursor) fcursor;
-
 done:
-     MAYBE_CLOSE (context, id, ret);
+     /* Leave sequencing sub-ccache open, but unlocked  */
+     (void) krb5_unlock_file(context, fileno(
+	     (((krb5_scc_data *) seq_id->data)->file) ));
+
      return(ret);
 }
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_ops.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_ops.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_ops.c Tue, 23 Jul 2002 17:21:49 -0400
@@ -33,7 +33,7 @@
 
 krb5_cc_ops krb5_scc_ops = {
      0,
-     "STDIO",
+     "FILE",
      krb5_scc_get_name,
      krb5_scc_resolve,
      krb5_scc_generate_new,
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_nseq.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_nseq.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_nseq.c Tue, 23 Jul 2002 12:05:45 -0400
@@ -62,6 +62,7 @@
      int ret;
      krb5_error_code kret;
      krb5_scc_cursor *fcursor;
+     krb5_ccache seq_id;
      krb5_int32 int32;
      krb5_octet octet;
 
@@ -75,46 +76,34 @@
      Z (addresses);
 #undef Z
 
-     MAYBE_OPEN (context, id, SCC_OPEN_RDONLY);
+     seq_id = (krb5_ccache) *cursor;
 
-     fcursor = (krb5_scc_cursor *) *cursor;
-     ret = fseek(((krb5_scc_data *) id->data)->file, fcursor->pos, 0);
-     if (ret < 0) {
-	 ret = krb5_scc_interpret(context, errno);
-	 MAYBE_CLOSE (context, id, ret);
-	 return ret;
-     }
-
-     kret = krb5_scc_read_principal(context, id, &creds->client);
+     kret = krb5_scc_read_principal(context, seq_id, &creds->client);
      TCHECK(kret);
-     kret = krb5_scc_read_principal(context, id, &creds->server);
+     kret = krb5_scc_read_principal(context, seq_id, &creds->server);
      TCHECK(kret);
-     kret = krb5_scc_read_keyblock(context, id, &creds->keyblock);
+     kret = krb5_scc_read_keyblock(context, seq_id, &creds->keyblock);
      TCHECK(kret);
-     kret = krb5_scc_read_times(context, id, &creds->times);
+     kret = krb5_scc_read_times(context, seq_id, &creds->times);
      TCHECK(kret);
-     kret = krb5_scc_read_octet(context, id, &octet);
+     kret = krb5_scc_read_octet(context, seq_id, &octet);
      TCHECK(kret);
      creds->is_skey = octet;
-     kret = krb5_scc_read_int32(context, id, &int32);
+     kret = krb5_scc_read_int32(context, seq_id, &int32);
      TCHECK(kret);
      creds->ticket_flags = int32;
-     kret = krb5_scc_read_addrs(context, id, &creds->addresses);
+     kret = krb5_scc_read_addrs(context, seq_id, &creds->addresses);
      TCHECK(kret);
-     kret = krb5_scc_read_authdata (context, id, &creds->authdata);
+     kret = krb5_scc_read_authdata (context, seq_id, &creds->authdata);
      TCHECK (kret);
-     kret = krb5_scc_read_data(context, id, &creds->ticket);
+     kret = krb5_scc_read_data(context, seq_id, &creds->ticket);
      TCHECK(kret);
-     kret = krb5_scc_read_data(context, id, &creds->second_ticket);
+     kret = krb5_scc_read_data(context, seq_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) {
 	 krb5_free_cred_contents(context, creds);
      }
-     MAYBE_CLOSE (context, id, kret);
      return kret;
 }
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_eseq.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_eseq.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_eseq.c Tue, 23 Jul 2002 16:35:46 -0400
@@ -50,9 +50,13 @@
    krb5_cc_cursor *cursor;
 {
     int ret = KRB5_OK;
+    krb5_scc_data *data = (krb5_scc_data *) ((krb5_ccache) *cursor)->data;
 /*    MAYBE_CLOSE (context, id, ret); */
 
-    krb5_xfree((krb5_scc_cursor *) *cursor);
+    data->flags |= KRB5_TC_OPENCLOSE;
+    MAYBE_CLOSE(context, ((krb5_ccache) *cursor), ret);
+    krb5_cc_close(context, ((krb5_ccache) *cursor));
+    krb5_xfree(cursor);
 
     return ret;
 }
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_destry.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_destry.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_destry.c Tue, 23 Jul 2002 17:16:29 -0400
@@ -46,29 +46,32 @@
    krb5_context context;
    krb5_ccache id;
 {
-#if 0
-     unsigned long size;
+#if 1
+     size_t size;
      char zeros[BUFSIZ];
 #endif
+     struct stat buf;
      krb5_scc_data *data = (krb5_scc_data *) id->data;
      register int ret;
+     int i;
      
-     if (!OPENCLOSE(id)) {
-	 (void) fclose(data->file);
-	 data->file = 0;
+     if (data->file) {
+	 ret = krb5_scc_close_file(context, id);
+         if (ret < 0) {
+	     ret = krb5_scc_interpret(context, errno);
+	     MAYBE_CLOSE(context, id, ret);
+	     goto cleanup;
+         }
      }
 
-     ret = remove (data->filename);
+     ret = unlink(data->filename);
      if (ret < 0) {
 	 ret = krb5_scc_interpret(context, errno);
-	 if (OPENCLOSE(id)) {
-	     (void) fclose(data->file);
-	     data->file = 0;
-	 }
+	 MAYBE_CLOSE(context, id, ret);
 	 goto cleanup;
      }
 
-#if 0
+#if 1
      /*
       * Possible future extension: Read entire file to determine
       * length, then write nulls all over it.  This was the UNIX
@@ -77,33 +80,23 @@
      ret = fstat(fileno(data->file), &buf);
      if (ret < 0) {
 	 ret = krb5_scc_interpret(context, errno);
-	 if (OPENCLOSE(id)) {
-	     (void) fclose(data->file);
-	     data->file = 0;
-	 }
+	 MAYBE_CLOSE(context, id, ret);
 	 goto cleanup;
      }
 
-     /* XXX This may not be legal XXX */
-     size = (unsigned long) buf.st_size;
+     size = (size_t) buf.st_size;
 
      memset (zeros, 0, BUFSIZ);
      for (i=0; i < size / BUFSIZ; i++)
-	  if (fwrite(data->file, zeros, BUFSIZ) < 0) {
+	  if (fwrite(zeros, BUFSIZ, 1, data->file) < 0) {
 	      ret = krb5_scc_interpret(context, errno);
-	      if (OPENCLOSE(id)) {
-		  (void) fclose(data->file);
-		  data->file = 0;
-	      }
+	      MAYBE_CLOSE(context, id, ret);
 	      goto cleanup;
 	  }
 
-     if (fwrite(data->file, zeros, size % BUFSIZ) < 0) {
+     if (fwrite(zeros, size % BUFSIZ, 1, data->file) < 0) {
 	 ret = krb5_scc_interpret(context, errno);
-	 if (OPENCLOSE(id)) {
-	     (void) fclose(data->file);
-	     data->file = 0;
-	 }
+	 MAYBE_CLOSE(context, id, ret);
 	 goto cleanup;
      }
      
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_defops.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_defops.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_defops.c Tue, 23 Jul 2002 17:21:45 -0400
@@ -33,7 +33,7 @@
 
 krb5_cc_ops krb5_cc_stdio_ops = {
      0,
-     "STDIO",
+     "FILE",
      krb5_scc_get_name,
      krb5_scc_resolve,
      krb5_scc_generate_new,
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc.h
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc.h Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc.h Tue, 23 Jul 2002 16:36:53 -0400
@@ -81,10 +81,7 @@
      int version;
 } krb5_scc_data;
 
-/* An off_t can be arbitrarily complex */
-typedef struct _krb5_scc_cursor {
-    long pos;
-} krb5_scc_cursor;
+typedef krb5_ccache krb5_scc_cursor;
 
 #define MAYBE_OPEN(context, ID, MODE) \
 {									\
Index: LOCAL-122.25/lib/krb5/ccache/stdio/scc_close.c
--- LOCAL-122.25/lib/krb5/ccache/stdio/scc_close.c Wed, 14 Mar 2001 14:20:32 -0500
+++ LOCAL-122.25(w)/lib/krb5/ccache/stdio/scc_close.c Tue, 23 Jul 2002 16:42:39 -0400
@@ -44,21 +44,14 @@
    krb5_context context;
    krb5_ccache id;
 {
-     register int closeval = KRB5_OK;
+     register int ret = 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(context, errno);
-	 } else
-	     closeval = KRB5_OK;
-		 
-     }
-     krb5_xfree (data->filename);
-     krb5_xfree (data);
-     krb5_xfree (id);
+     if (data->file)
+	ret = krb5_scc_close_file(context, id);
+     krb5_xfree(data->filename);
+     krb5_xfree(data);
+     krb5_xfree(id);
 
-     return closeval;
+     return ret;
 }
-------------- next part --------------

Visit our website at http://www.ubswarburg.com

This message contains confidential information and is intended only 
for the individual named.  If you are not the named addressee you 
should not disseminate, distribute or copy this e-mail.  Please 
notify the sender immediately by e-mail if you have received this 
e-mail by mistake and delete this e-mail from your system.

E-mail transmission cannot be guaranteed to be secure or error-free 
as information could be intercepted, corrupted, lost, destroyed, 
arrive late or incomplete, or contain viruses.  The sender therefore 
does not accept liability for any errors or omissions in the contents 
of this message which arise as a result of e-mail transmission.  If 
verification is required please request a hard-copy version.  This 
message is provided for informational purposes and should not be 
construed as a solicitation or offer to buy or sell any securities or 
related financial instruments.


More information about the krbdev mailing list