* scc.h scc_gprin.c scc_maybe.c scc_skip.c scc_sseq.c
authorRichard Basch <probe@mit.edu>
Fri, 9 Feb 1996 02:19:14 +0000 (02:19 +0000)
committerRichard Basch <probe@mit.edu>
Fri, 9 Feb 1996 02:19:14 +0000 (02:19 +0000)
Store and retrieve the os_context time offset from the
credentials cache.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7465 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/ccache/stdio/scc.h
src/lib/krb5/ccache/stdio/scc_gprin.c
src/lib/krb5/ccache/stdio/scc_maybe.c
src/lib/krb5/ccache/stdio/scc_skip.c
src/lib/krb5/ccache/stdio/scc_sseq.c

index aaa75b80ac20dd9dce95ca4d3b482ab814fd2987..627eb3adf0d1a814389e1ae550776a731a5d71f6 100644 (file)
 #define        SCC_OPEN_RDWR           2
 #define        SCC_OPEN_RDONLY         3
 
+/* Credential file header tags.
+ * The header tags are constructed as:
+ *     krb5_ui_2       tag
+ *     krb5_ui_2       len
+ *     krb5_octet      data[len]
+ * This format allows for older versions of the fcc processing code to skip
+ * past unrecognized tag formats.
+ */
+#define SCC_TAG_DELTATIME      1
+
 #ifndef TKT_ROOT
 #define TKT_ROOT "/tmp/tkt"
 #endif
index 3f6c90d5e682d4307ed129d9674db6b8f9255532..5fbc4822d6eccd9fdfe4a1d40cb5d3b54cbd2166 100644 (file)
@@ -49,11 +49,13 @@ krb5_scc_get_principal(context, id, princ)
      krb5_error_code kret;
 
      MAYBE_OPEN (context, id, SCC_OPEN_RDONLY);
-     /* skip over vno at beginning of file */
-     fseek(((krb5_scc_data *) id->data)->file, sizeof(krb5_int16), 0);
+
+     kret = krb5_scc_skip_header(context, id);
+     if (kret) goto done;
 
      kret = krb5_scc_read_principal(context, id, princ);
 
+done:
      MAYBE_CLOSE (context, id, kret);
      return kret;
 }
index 2e09b3da6e25f4c8141dcf7864c9279137b691d5..ebddd0559d9f775437096e31da33bd7312f4612f 100644 (file)
@@ -70,128 +70,202 @@ krb5_scc_close_file (context, id)
 
 krb5_error_code
 krb5_scc_open_file (context, id, mode)
-   krb5_context context;
+    krb5_context context;
     krb5_ccache id;
     int mode;
 {
-     char fvno_bytes[2];       /* In nework standard byte order, big endian */
-     krb5_scc_data *data;
-     FILE *f;
-     char *open_flag;
-     krb5_error_code retval;
-
-     data = (krb5_scc_data *) id->data;
-     if (data->file) {
-         /* Don't know what state it's in; shut down and start anew.  */
-         (void) krb5_unlock_file(context, fileno(data->file));
-         (void) fclose (data->file);
-         data->file = 0;
-     }
+    krb5_os_context os_ctx = (krb5_os_context) context->os_context;
+    krb5_scc_data *data = (krb5_scc_data *) id->data;
+    char fvno_bytes[2];                /* In nework byte order */
+    krb5_ui_2 scc_vno;
+    krb5_ui_2 scc_tag;
+    krb5_ui_2 scc_taglen;
+    krb5_ui_2 scc_hlen;
+    FILE *f;
+    char *open_flag;
+    krb5_error_code retval = 0;
+    
+    if (data->file) {
+       /* Don't know what state it's in; shut down and start anew.  */
+       (void) krb5_unlock_file(context, fileno(data->file));
+       (void) fclose (data->file);
+       data->file = 0;
+    }
 #ifdef ANSI_STDIO
-     switch(mode) {
-     case SCC_OPEN_AND_ERASE:
-        unlink(data->filename);
-        /* XXX should do an exclusive open here, but no way to do */
-        /* this under stdio */
-        open_flag = "wb+";
-        break;
-     case SCC_OPEN_RDWR:
-        open_flag = "rb+";
-        break;
-     case SCC_OPEN_RDONLY:
-     default:
-        open_flag = "rb";
-        break;
-     }
+    switch(mode) {
+    case SCC_OPEN_AND_ERASE:
+       unlink(data->filename);
+       /* XXX should do an exclusive open here, but no way to do */
+       /* this under stdio */
+       open_flag = "wb+";
+       break;
+    case SCC_OPEN_RDWR:
+       open_flag = "rb+";
+       break;
+    case SCC_OPEN_RDONLY:
+    default:
+       open_flag = "rb";
+       break;
+    }
 #else
-     switch(mode) {
-     case SCC_OPEN_AND_ERASE:
-        unlink(data->filename);
-        /* XXX should do an exclusive open here, but no way to do */
-        /* this under stdio */
-        open_flag = "w+";
-        break;
-     case SCC_OPEN_RDWR:
-        open_flag = "r+";
-        break;
-     case SCC_OPEN_RDONLY:
-     default:
-        open_flag = "r";
-        break;
-     }
+    switch(mode) {
+    case SCC_OPEN_AND_ERASE:
+       unlink(data->filename);
+       /* XXX should do an exclusive open here, but no way to do */
+       /* this under stdio */
+       open_flag = "w+";
+       break;
+    case SCC_OPEN_RDWR:
+       open_flag = "r+";
+       break;
+    case SCC_OPEN_RDONLY:
+    default:
+       open_flag = "r";
+       break;
+    }
 #endif
 
-     f = fopen (data->filename, open_flag);
-     if (!f)
-         return krb5_scc_interpret (context, errno);
+    f = fopen (data->filename, open_flag);
+    if (!f)
+       return krb5_scc_interpret (context, errno);
 #ifdef HAS_SETVBUF
-     setvbuf(f, data->stdio_buffer, _IOFBF, sizeof (data->stdio_buffer));
+    setvbuf(f, data->stdio_buffer, _IOFBF, sizeof (data->stdio_buffer));
 #else
-     setbuf (f, data->stdio_buffer);
+    setbuf (f, data->stdio_buffer);
 #endif
-     switch (mode) {
-     case SCC_OPEN_RDONLY:
-        if ((retval = krb5_lock_file(context,fileno(f),KRB5_LOCKMODE_SHARED))){
-            (void) fclose(f);
-            return retval;
-        }
-        break;
-     case SCC_OPEN_RDWR:
-     case SCC_OPEN_AND_ERASE:
-        if ((retval = krb5_lock_file(context, fileno(f), 
-                                     KRB5_LOCKMODE_EXCLUSIVE))) {
-            (void) fclose(f);
-            return retval;
-        }
-        break;
-     }
-     if (mode == SCC_OPEN_AND_ERASE) {
-        /* write the version number */
-        int errsave;
+    switch (mode) {
+    case SCC_OPEN_RDONLY:
+       if ((retval = krb5_lock_file(context,fileno(f),KRB5_LOCKMODE_SHARED))){
+           (void) fclose(f);
+           return retval;
+       }
+       break;
+    case SCC_OPEN_RDWR:
+    case SCC_OPEN_AND_ERASE:
+       if ((retval = krb5_lock_file(context, fileno(f), 
+                                    KRB5_LOCKMODE_EXCLUSIVE))) {
+           (void) fclose(f);
+           return retval;
+       }
+       break;
+    }
+    if (mode == SCC_OPEN_AND_ERASE) {
+       /* write the version number */
+       int errsave;
+
+       data->file = f;
+       data->version = context->scc_default_format;
+       retval = krb5_scc_store_ui_2(context, id, data->version);
+       if (retval) goto done;
 
-        fvno_bytes[0] = (context->scc_default_format >> 8) & 0xFF;
-        fvno_bytes[1] = context->scc_default_format & 0xFF;
-        data->version = context->scc_default_format;
-        if (!fwrite((char *)fvno_bytes, sizeof(fvno_bytes), 1, f)) {
-            errsave = errno;
-            (void) krb5_unlock_file(context, fileno(f));
-            (void) fclose(f);
-            return krb5_scc_interpret(context, errsave);
-        }
-     } else {
-        /* verify a valid version number is there */
-        if (!fread((char *)fvno_bytes, sizeof(fvno_bytes), 1, f)) {
-            (void) krb5_unlock_file(context, fileno(f));
-            (void) fclose(f);
-            return KRB5_CC_FORMAT;
-        }
-        data->version = (fvno_bytes[0] << 8) + fvno_bytes[1];
-        if ((data->version != KRB5_SCC_FVNO_1) &&
-            (data->version != KRB5_SCC_FVNO_2) &&
-            (data->version != KRB5_SCC_FVNO_3) &&
-            (data->version != KRB5_SCC_FVNO_4)) {
-            (void) krb5_unlock_file(context, fileno(f));
-            (void) fclose(f);
-            return KRB5_CCACHE_BADVNO;
-        }
        if (data->version == KRB5_SCC_FVNO_4) {
-           char buf[1024];
-           int len;
+           scc_hlen = 0;
+
+           if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID)
+                 scc_hlen += (2*sizeof(krb5_ui_2) + 2*sizeof(krb5_int32));
+           /* Write header length */
+           retval = krb5_scc_store_ui_2(context, id, (krb5_int32)scc_hlen);
+           if (retval) goto done;
+           if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) {
+               /* Write time offset tag */
+               scc_tag = SCC_TAG_DELTATIME;
+               scc_taglen = 2*sizeof(krb5_int32);
+                 
+               retval = krb5_scc_store_ui_2(context,id,(krb5_int32)scc_tag);
+               if (retval) goto done;
+               retval = krb5_scc_store_ui_2(context,id,(krb5_int32)scc_taglen);
+               if (retval) goto done;
+               retval = krb5_scc_store_int32(context,id,os_ctx->time_offset);
+               if (retval) goto done;
+               retval = krb5_scc_store_int32(context,id,os_ctx->usec_offset);
+               if (retval) goto done;
+           }
+       }
+       goto done;
+    }
+
+    /* verify a valid version number is there */
+    if (!fread((char *)fvno_bytes, sizeof(fvno_bytes), 1, f))
+    {
+       retval = KRB5_CC_FORMAT;
+       goto done;
+    }
+    data->version = (fvno_bytes[0] << 8) + fvno_bytes[1];
+    if ((data->version != KRB5_SCC_FVNO_1) &&
+       (data->version != KRB5_SCC_FVNO_2) &&
+       (data->version != KRB5_SCC_FVNO_3) &&
+       (data->version != KRB5_SCC_FVNO_4))
+    {
+       retval = KRB5_CCACHE_BADVNO;
+       goto done;
+    }
+
+    data->file = f;
+    
+    if (data->version == KRB5_SCC_FVNO_4) {
+       char buf[1024];
 
-           if (!fread((char *)fvno_bytes, sizeof(fvno_bytes), 1, f)) {
-               (void) krb5_unlock_file(context, fileno(f));
-               (void) fclose(f);
-               return KRB5_CC_FORMAT;
+       if (krb5_scc_read_ui_2(context, id, &scc_hlen) ||
+           (scc_hlen > sizeof(buf)))
+       {
+           retval = KRB5_CC_FORMAT;
+           goto done;
+       }
+       
+       while (scc_hlen) {
+           if ((scc_hlen < (2*sizeof(krb5_ui_2))) ||
+               krb5_scc_read_ui_2(context, id, &scc_tag) ||
+               krb5_scc_read_ui_2(context, id, &scc_taglen) ||
+               (scc_taglen > (scc_hlen - 2*sizeof(krb5_ui_2))))
+           {
+               retval = KRB5_CC_FORMAT;
+               goto done;
            }
-           if ((len = (fvno_bytes[0] << 8) + fvno_bytes[1]) != 0) {
-               if (!fread(buf, len, 1, f)) {
-                   (void) krb5_unlock_file(context, fileno(f));
-                   (void) fclose(f);
-                   return KRB5_CC_FORMAT;
+
+           switch (scc_tag) {
+           case SCC_TAG_DELTATIME:
+               if (scc_taglen != 2*sizeof(krb5_int32)) {
+                   retval = KRB5_CC_FORMAT;
+                   goto done;
                }
+                 if (!(context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) ||
+                     (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID))
+                 {
+                     if (krb5_scc_read(context, id, buf, scc_taglen)) {
+                         retval = KRB5_CC_FORMAT;
+                         goto done;
+                     }
+                     break;
+                 }
+                 if (krb5_scc_read_int32(context, id, &os_ctx->time_offset) ||
+                     krb5_scc_read_int32(context, id, &os_ctx->usec_offset))
+                 {
+                     retval = KRB5_CC_FORMAT;
+                     goto done;
+                 }
+                 os_ctx->os_flags =
+                     ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) |
+                      KRB5_OS_TOFFSET_VALID);
+                 break;
+           default:
+                 if (scc_taglen && krb5_scc_read(context,id,buf,scc_taglen)) {
+                     retval = KRB5_CC_FORMAT;
+                     goto done;
+                 }
+                 break;
            }
+           scc_hlen -= (2*sizeof(krb5_ui_2) + scc_taglen);
        }
     }
-    data->file = f;
-    return 0;
+
+done:
+    if (retval)
+       if (f) {
+           data->file = 0;
+           (void) krb5_unlock_file(context, fileno(f));
+           (void) fclose(f);
+       }
+    return retval;
 }
index 01824026f6e1d39b514494277e3f572bf2729dbb..6b072dc5e884a6b18d245e6591adfd2939264d1b 100644 (file)
 
 #include "scc.h"
 
+krb5_error_code
+krb5_scc_skip_header(context, id)
+   krb5_context context;
+   krb5_ccache id;
+{
+     krb5_error_code kret;
+     krb5_principal princ;
+     krb5_scc_data *data = (krb5_scc_data *) id->data;
+     krb5_ui_2 scc_flen;
+
+     if (fseek(data->file, sizeof(krb5_ui_2), SEEK_SET))
+        return errno;
+     if (data->version == KRB5_SCC_FVNO_4) {
+        kret = krb5_scc_read_ui_2(context, id, &scc_flen);
+        if (kret) return kret;
+        if (fseek(data->file, scc_flen, SEEK_CUR))
+            return errno;
+     }
+     return KRB5_OK;
+}
+
 krb5_error_code
 krb5_scc_skip_principal(context, id)
    krb5_context context;
@@ -43,5 +64,3 @@ krb5_scc_skip_principal(context, id)
      krb5_free_principal(context, princ);
      return KRB5_OK;
 }
-
-     
index f1971c5d26cf2e13ccaa53b3eb94da377f2e689a..c5bac1967216ee4d08ae50bb9f5e632d5d54bef8 100644 (file)
@@ -56,13 +56,16 @@ krb5_scc_start_seq_get(context, id, cursor)
 
      /* Make sure we start reading right after the primary principal */
      MAYBE_OPEN (context, id, SCC_OPEN_RDONLY);
-     /* skip over vno at beginning of file */
-     fseek(((krb5_scc_data *) id->data)->file, sizeof(krb5_int16), 0);
 
-     krb5_scc_skip_principal(context, id);
+     ret = krb5_scc_skip_header(context, id);
+     if (ret) goto done;
+     ret = krb5_scc_skip_principal(context, 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);
      return(ret);
 }