ser_ctx.c (krb5_context_size, krb5_context_externalize,
authorTheodore Tso <tytso@mit.edu>
Tue, 14 May 1996 08:41:32 +0000 (08:41 +0000)
committerTheodore Tso <tytso@mit.edu>
Tue, 14 May 1996 08:41:32 +0000 (08:41 +0000)
krb5_context_internalize): Add missing fields from the serialized
context: clockskew, default_kdc_req_sumtype, default_ap_req_sumtype,
default_safe_sumtype, kdc_default_options, library_options,
profile_secure, fcc_default_format, scc_default_format.

ser_actx.c (krb5_auth_context_size, krb5_auth_context_externalize,
krb5_auth_context_internalize): Serialize the two fields req_cksumtype
and safe_cksumtype, instead of the one cksumtype field.

mk_safe.c (krb_mk_safe): Use safe_cksumtype instead of cksumtype in
the auth context.

mk_req_ext.c (krb5_mk_req_extended): Use req_cksumtype instead of
cksumtype in the auth context.

init_ctx.c (krb5_init_context): Add support for new profile
relations libdefaults/tkt_lifetime, libdefaults/kdc_req_checksum_type,
libdefaults/ap_req_cksumtype, libdefaults/safe_checksumtype, and
libdefaults/kdc_default_options.

auth_con.h: Remove old cksumtype element, and replace it with
req_cksumtype and safe_cksumtype.

auth_con.c (krb5_auth_con_init): Initialize the req_cksumtype and
safe_cksumtype from the context's default req_cksumtype and
safe_cksumtype.  (krb5_auth_con_set_req_cksumtype,
krb5_auth_con_set_safe_cksumtype): New functions, to replace old
krb5_auth_con_setcksumtype

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

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/auth_con.c
src/lib/krb5/krb/auth_con.h
src/lib/krb5/krb/init_ctx.c
src/lib/krb5/krb/mk_req_ext.c
src/lib/krb5/krb/mk_safe.c
src/lib/krb5/krb/ser_actx.c
src/lib/krb5/krb/ser_ctx.c

index 1593195ba87ea9046109e8adfded5cef8d7f210f..c94c31cfa18d1465e280ef5952cdeb49296e1d57 100644 (file)
@@ -1,3 +1,40 @@
+Tue May 14 02:53:42 1996  Theodore Y. Ts'o  <tytso@mit.edu>
+
+       * ser_ctx.c (krb5_context_size, krb5_context_externalize,
+               krb5_context_internalize): Add missing fields from the
+               serialized context: clockskew, default_kdc_req_sumtype,
+               default_ap_req_sumtype, default_safe_sumtype,
+               kdc_default_options, library_options, profile_secure,
+               fcc_default_format, scc_default_format.
+
+       * ser_actx.c (krb5_auth_context_size, krb5_auth_context_externalize,
+               krb5_auth_context_internalize): Serialize the two fields
+               req_cksumtype and safe_cksumtype, instead of the one
+               cksumtype field.
+
+       * mk_safe.c (krb_mk_safe): Use safe_cksumtype instead of cksumtype
+               in the auth context.
+
+       * mk_req_ext.c (krb5_mk_req_extended): Use req_cksumtype instead
+               of cksumtype in the auth context.
+
+       * init_ctx.c (krb5_init_context): Add support for new profile
+               relations libdefaults/tkt_lifetime,
+               libdefaults/kdc_req_checksum_type,
+               libdefaults/ap_req_cksumtype,
+               libdefaults/safe_checksumtype, and
+               libdefaults/kdc_default_options.
+
+       * auth_con.h: Remove old cksumtype element, and replace it with
+               req_cksumtype and safe_cksumtype.
+
+       * auth_con.c (krb5_auth_con_init): Initialize the req_cksumtype
+               and safe_cksumtype from the context's default
+               req_cksumtype and safe_cksumtype.
+               (krb5_auth_con_set_req_cksumtype,
+               krb5_auth_con_set_safe_cksumtype): New functions, to
+               replace old krb5_auth_con_setcksumtype
+       
 Fri May 10 18:48:38 EDT 1996  Richard Basch  <basch@lehman.com>
 
        * init_ctx.c: Removed des3-cbc-md5 default support
index fc96acbc216daf71bf13c8afd6a35e8cc6e3134d..ec8918208ab751cf94227fde2d4de27029714eca 100644 (file)
@@ -42,8 +42,8 @@ krb5_auth_con_init(context, auth_context)
     (*auth_context)->auth_context_flags = 
            KRB5_AUTH_CONTEXT_DO_TIME |  KRB5_AUTH_CONN_INITIALIZED;
 
-    (*auth_context)->cksumtype = CKSUMTYPE_RSA_MD4_DES;
-    /* (*auth_context)->cksumtype = CKSUMTYPE_CRC32; */
+    (*auth_context)->req_cksumtype = context->default_ap_req_sumtype;
+    (*auth_context)->safe_cksumtype = context->default_safe_sumtype;
     (*auth_context)->magic = KV5M_AUTH_CONTEXT;
     return 0;
 }
@@ -220,12 +220,22 @@ krb5_auth_con_getremotesubkey(context, auth_context, keyblock)
 }
 
 krb5_error_code
-krb5_auth_con_setcksumtype(context, auth_context, cksumtype)
+krb5_auth_con_set_req_cksumtype(context, auth_context, cksumtype)
     krb5_context         context;
     krb5_auth_context    auth_context;
     krb5_cksumtype       cksumtype;            
 {
-    auth_context->cksumtype = cksumtype;
+    auth_context->req_cksumtype = cksumtype;
+    return 0;
+}
+
+krb5_error_code
+krb5_auth_con_set_safe_cksumtype(context, auth_context, cksumtype)
+    krb5_context         context;
+    krb5_auth_context    auth_context;
+    krb5_cksumtype       cksumtype;            
+{
+    auth_context->safe_cksumtype = cksumtype;
     return 0;
 }
 
index 4fec7a690e453f246889068dc8bf61b73907bc06..9d9df0e8676aef0209e632750da03822e626d3e1 100644 (file)
@@ -16,7 +16,8 @@ struct _krb5_auth_context {
     krb5_int32         remote_seq_number;
     krb5_int32         local_seq_number;
     krb5_authenticator *authentp;              /* mk_req, rd_req, mk_rep, ...*/
-    krb5_cksumtype     cksumtype;              /* mk_safe, ... */
+    krb5_cksumtype     req_cksumtype;          /* mk_safe, ... */
+    krb5_cksumtype     safe_cksumtype;         /* mk_safe, ... */
     krb5_pointer       i_vector;               /* mk_priv, rd_priv only */
     krb5_rcache                rcache;
 };
index d28f63d0302c26a8e2ce17e1a82436da00ff9f8c..83b2c48cdc22b60d09e20f828b361eb686c17a28 100644 (file)
@@ -57,12 +57,31 @@ krb5_init_context(context)
                            0, 5 * 60, &tmp);
        ctx->clockskew = tmp;
 
+       /* Default ticket lifetime is 
+       profile_get_integer(ctx->profile, "libdefaults", "tkt_lifetime",
+                           0, 10 * 60 * 60, &tmp);
+       ctx->clockskew = tmp;
+
        /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2)  */
-       /* DCE add checksum_type = 2 to krb5.conf */
-       profile_get_integer(ctx->profile, "libdefaults", "checksum_type", 0,
-                           CKSUMTYPE_RSA_MD5, &tmp);
+       /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
+       profile_get_integer(ctx->profile, "libdefaults",
+                           "kdc_req_checksum_type", 0, CKSUMTYPE_RSA_MD5, 
+                           &tmp);
        ctx->kdc_req_sumtype = tmp;
 
+       profile_get_integer(ctx->profile, "libdefaults",
+                           "ap_req_checksum_type", 0, CKSUMTYPE_RSA_MD5,
+                           &tmp);
+       ctx->default_ap_req_sumtype = tmp;
+
+       profile_get_integer(ctx->profile, "libdefaults",
+                           "safe_checksum_type", 0,
+                           CKSUMTYPE_RSA_MD5_DES, &tmp);
+       ctx->default_safe_sumtype = tmp;
+
+       profile_get_integer(ctx->profile, "libdefaults",
+                           "kdc_default_options", 0,
+                           KDC_OPT_RENEWABLE_OK, &tmp);
        ctx->kdc_default_options = KDC_OPT_RENEWABLE_OK;
 #ifdef _MACINTOSH
 #define DEFAULT_KDC_TIMESYNC 1
index dfff907c287ce1aeadf237d0d80f10987d89aede..8193d3016c1de14e1ba97a5d41459c9995351949 100644 (file)
@@ -137,7 +137,7 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
 
 
     if (in_data) {
-      if ((*auth_context)->cksumtype == 0x8003) {
+      if ((*auth_context)->req_cksumtype == 0x8003) {
        /* XXX Special hack for GSSAPI */
        checksum.checksum_type = 0x8003;
        checksum.length = in_data->length;
@@ -145,12 +145,12 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
       } else  {
        /* Generate checksum, XXX What should the seed be? */
        if ((checksum.contents = (krb5_octet *)malloc(krb5_checksum_size(context,
-                                (*auth_context)->cksumtype))) == NULL) {
+                                (*auth_context)->req_cksumtype))) == NULL) {
          retval = ENOMEM;
          goto cleanup;
        }
        if ((retval = krb5_calculate_checksum(context, 
-                                             (*auth_context)->cksumtype, 
+                                             (*auth_context)->req_cksumtype, 
                                              in_data->data, in_data->length,
                                              (*auth_context)->keyblock->contents,
                                              (*auth_context)->keyblock->length,
index 0dfb16591825b60509cec72d4119e43084a41651..816b26d861a6cf43f838f83cc2b9bf363c029a69 100644 (file)
@@ -209,7 +209,7 @@ krb5_mk_safe(context, auth_context, userdata, outbuf, outdata)
 
     if ((retval = krb5_mk_safe_basic(context, userdata, keyblock, &replaydata, 
                                     plocal_fulladdr, premote_fulladdr,
-                                    auth_context->cksumtype, outbuf))) {
+                                    auth_context->safe_cksumtype, outbuf))) {
        CLEANUP_DONE();
        goto error;
     }
index ed15d1283d9a09b5605d8675447a26635962b2db..8be618a89b75d6ef9d673cd3b6726de470a38ce7 100644 (file)
@@ -88,13 +88,14 @@ krb5_auth_context_size(kcontext, arg, sizep)
      * krb5_int32              for auth_context_flags
      * krb5_int32              for remote_seq_number
      * krb5_int32              for local_seq_number
-     * krb5_int32              for cksumtype
+     * krb5_int32              for req_cksumtype
+     * krb5_int32              for safe_cksumtype
      * krb5_int32              for size of i_vector
      * krb5_int32              for KV5M_AUTH_CONTEXT
      */
     kret = EINVAL;
     if ((auth_context = (krb5_auth_context) arg)) {
-       required = sizeof(krb5_int32)*7;
+       required = sizeof(krb5_int32)*8;
 
        kret = 0;
        /* Calculate size required by i_vector - ptooey */
@@ -220,7 +221,9 @@ krb5_auth_context_externalize(kcontext, arg, buffer, lenremain)
                                       &bp, &remain);
            (void) krb5_ser_pack_int32(auth_context->local_seq_number,
                                       &bp, &remain);
-           (void) krb5_ser_pack_int32((krb5_int32) auth_context->cksumtype,
+           (void) krb5_ser_pack_int32((krb5_int32) auth_context->req_cksumtype,
+                                      &bp, &remain);
+           (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype,
                                       &bp, &remain);
 
            /* Now figure out the number of bytes for i_vector and write it */
@@ -382,9 +385,13 @@ krb5_auth_context_internalize(kcontext, argp, buffer, lenremain)
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            auth_context->local_seq_number = ibuf;
 
-           /* Get cksumtype */
+           /* Get req_cksumtype */
+           (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+           auth_context->req_cksumtype = (krb5_cksumtype) ibuf;
+
+           /* Get safe_cksumtype */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-           auth_context->cksumtype = (krb5_cksumtype) ibuf;
+           auth_context->safe_cksumtype = (krb5_cksumtype) ibuf;
 
            /* Get length of i_vector */
            (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain);
index 9fb5be9831785133524ded6775e969f1942c790c..2bdb1ad711df2fd704a3c5646ac16cd884e5f307 100644 (file)
@@ -109,17 +109,25 @@ krb5_context_size(kcontext, arg, sizep)
      * nktypes*sizeof(krb5_int32)      for in_tkt_ktypes.
      * krb5_int32                      for n_tgs_ktypes*sizeof(krb5_int32)
      * nktypes*sizeof(krb5_int32)      for tgs_ktypes.
+     *  krb5_int32                     for clockskew
+     *  krb5_int32                     for kdc_req_sumtype
+     *  krb5_int32                     for ap_req_sumtype
+     *  krb5_int32                     for safe_sumtype
+     *  krb5_int32                     for kdc_default_options
+     *  krb5_int32                     for library_options
+     *  krb5_int32                     for profile_secure
+     *         krb5_int32                      for fcc_default_format
+     *  krb5_int32                     for scc_default_format
+     *    <>                           for os_context
+     *    <>                           for db_context
+     *    <>                           for profile
      * krb5_int32                      for trailer.
      */
     kret = EINVAL;
     if ((context = (krb5_context) arg)) {
        /* Calculate base length */
-       required = (sizeof(krb5_int32) +
-                   sizeof(krb5_int32) +
-                   sizeof(krb5_int32) +
-                   sizeof(krb5_int32) +
+       required = (14 * sizeof(krb5_int32) +
                    (context->in_tkt_ktype_count * sizeof(krb5_int32)) +
-                   sizeof(krb5_int32) +
                    (context->tgs_ktype_count * sizeof(krb5_int32)));
 
        if (context->default_realm)
@@ -170,86 +178,159 @@ krb5_context_externalize(kcontext, arg, buffer, lenremain)
     required = 0;
     bp = *buffer;
     remain = *lenremain;
-    kret = EINVAL;
-    if ((context = (krb5_context) arg)) {
-       kret = ENOMEM;
-       if (!krb5_context_size(kcontext, arg, &required) &&
-           (required <= remain)) {
-           /* First write our magic number */
-           (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
-           
-           /* Now sizeof default realm */
-           (void) krb5_ser_pack_int32((context->default_realm) ?
-                                      (krb5_int32) strlen(context->
-                                                          default_realm) : 0,
-                                      &bp, &remain);
+    context = (krb5_context) arg;
+    if (!context)
+           return (EINVAL);
+    KRB5_VERIFY_MAGIC(context, KV5M_CONTEXT);
 
-           /* Now default_realm bytes */
-           if (context->default_realm)
-               (void) krb5_ser_pack_bytes((krb5_octet *) 
-                                          context->default_realm,
-                                          strlen(context->default_realm),
-                                          &bp, &remain);
+    if ((kret = krb5_context_size(kcontext, arg, &required)))
+       return (kret);
 
-           /* Now number of initial ticket ktypes */
-           (void) krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktype_count,
-                                      &bp, &remain);
+    if (required > remain)
+       return (ENOMEM);
+    
+    /* First write our magic number */
+    kret = krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
+    if (kret)
+       return (kret);
+    
+    /* Now sizeof default realm */
+    kret = krb5_ser_pack_int32((context->default_realm) ?
+                              (krb5_int32) strlen(context->default_realm) : 0,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+    
+    /* Now default_realm bytes */
+    if (context->default_realm) {
+       kret = krb5_ser_pack_bytes((krb5_octet *) context->default_realm,
+                                  strlen(context->default_realm), 
+                                  &bp, &remain);
+       if (kret)
+           return (kret);
+    }
 
-           /* Now serialize ktypes */
-           for (i=0; i<context->in_tkt_ktype_count; i++)
-               (void) krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktypes[i],
-                                          &bp, &remain);
-           kret = 0;
+    /* Now number of initial ticket ktypes */
+    kret = krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktype_count,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+    
+    /* Now serialize ktypes */
+    for (i=0; i<context->in_tkt_ktype_count; i++) {
+       kret = krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktypes[i],
+                                  &bp, &remain);
+       if (kret)
+           return (kret);
+    }
+    
+    /* Now number of default ktypes */
+    kret = krb5_ser_pack_int32((krb5_int32) context->tgs_ktype_count,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+       
+    /* Now serialize ktypes */
+    for (i=0; i<context->tgs_ktype_count; i++) {
+       kret = krb5_ser_pack_int32((krb5_int32) context->tgs_ktypes[i],
+                                  &bp, &remain);
+       if (kret)
+           return (kret);
+    }
+       
+    /* Now allowable clockskew */
+    kret = krb5_ser_pack_int32((krb5_int32) context->clockskew,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+       
+    /* Now kdc_req_sumtype */
+    kret = krb5_ser_pack_int32((krb5_int32) context->kdc_req_sumtype,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+       
+    /* Now default ap_req_sumtype */
+    kret = krb5_ser_pack_int32((krb5_int32) context->default_ap_req_sumtype,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
 
-           /* Now number of default ktypes */
-           (void) krb5_ser_pack_int32((krb5_int32) context->tgs_ktype_count,
-                                      &bp, &remain);
+    /* Now default safe_sumtype */
+    kret = krb5_ser_pack_int32((krb5_int32) context->default_safe_sumtype,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
 
-           /* Now serialize ktypes */
-           for (i=0; i<context->tgs_ktype_count; i++)
-               (void) krb5_ser_pack_int32((krb5_int32) context->tgs_ktypes[i],
-                                          &bp, &remain);
-           kret = 0;
+    /* Now kdc_default_options */
+    kret = krb5_ser_pack_int32((krb5_int32) context->kdc_default_options,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
 
-           /* Now handle os_context, if appropriate */
-           if (context->os_context)
-               kret = krb5_externalize_opaque(kcontext,
-                                              KV5M_OS_CONTEXT,
-                                              (krb5_pointer)
-                                              context->os_context,
-                                              &bp,
-                                              &remain);
-
-           /* Now handle database context, if appropriate */
-           if (!kret && context->db_context)
-               kret = krb5_externalize_opaque(kcontext,
-                                              KV5M_DB_CONTEXT,
-                                              (krb5_pointer)
-                                              context->db_context,
-                                              &bp,
-                                              &remain);
-
-           /* Finally, handle profile, if appropriate */
-           if (!kret && context->profile)
-               kret = krb5_externalize_opaque(kcontext,
-                                              PROF_MAGIC_PROFILE,
-                                              (krb5_pointer)
-                                              context->profile,
-                                              &bp,
-                                              &remain);
-           /*
-            * If we were successful, write trailer then update the pointer and
-            * remaining length;
-            */
-           if (!kret) {
-               /* Write our trailer */
-               (void) krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
-               *buffer = bp;
-               *lenremain = remain;
-           }
-       }
+    /* Now library_options */
+    kret = krb5_ser_pack_int32((krb5_int32) context->library_options,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+       
+    /* Now profile_secure */
+    kret = krb5_ser_pack_int32((krb5_int32) context->profile_secure,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+
+    /* Now fcc_default_format */
+    kret = krb5_ser_pack_int32((krb5_int32) context->fcc_default_format,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+
+    /* Now scc_default_format */
+    kret = krb5_ser_pack_int32((krb5_int32) context->scc_default_format,
+                              &bp, &remain);
+    if (kret)
+       return (kret);
+
+    /* Now handle os_context, if appropriate */
+    if (context->os_context) {
+       kret = krb5_externalize_opaque(kcontext, KV5M_OS_CONTEXT,
+                                      (krb5_pointer) context->os_context,
+                                      &bp, &remain);
+       if (kret)
+           return (kret);
     }
-    return(kret);
+       
+    /* Now handle database context, if appropriate */
+    if (context->db_context) {
+       kret = krb5_externalize_opaque(kcontext, KV5M_DB_CONTEXT,
+                                      (krb5_pointer) context->db_context,
+                                      &bp, &remain);
+       if (kret)
+           return (kret);
+    }
+
+    /* Finally, handle profile, if appropriate */
+    if (context->profile) {
+       kret = krb5_externalize_opaque(kcontext, PROF_MAGIC_PROFILE,
+                                      (krb5_pointer) context->profile,
+                                      &bp, &remain);
+       if (kret)
+           return (kret);
+    }
+       
+    /*
+     * If we were successful, write trailer then update the pointer and
+     * remaining length;
+     */
+    kret = krb5_ser_pack_int32(KV5M_CONTEXT, &bp, &remain);
+    if (kret)
+       return (kret);
+    
+    *buffer = bp;
+    *lenremain = remain;
+
+    return (0);
 }
 \f
 /*
@@ -271,123 +352,163 @@ krb5_context_internalize(kcontext, argp, buffer, lenremain)
 
     bp = *buffer;
     remain = *lenremain;
-    kret = EINVAL;
+
     /* Read our magic number */
-    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
-       ibuf = 0;
-    if (ibuf == KV5M_CONTEXT) {
-       kret = ENOMEM;
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       return (EINVAL);
 
-       /* Get memory for the context */
-       if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
-           (context = (krb5_context) malloc(sizeof(struct _krb5_context)))) {
-           memset(context, 0, sizeof(struct _krb5_context));
-
-           if (!ibuf ||
-               (context->default_realm = (char *) malloc((size_t) ibuf+1))) {
-               /* Copy in the default realm */
-               if (ibuf) {
-                   (void) krb5_ser_unpack_bytes((krb5_octet *)
-                                                context->default_realm,
-                                                (size_t) ibuf,
-                                                &bp, &remain);
-                   context->default_realm[ibuf] = '\0';
-               }
-
-               /* Get the number of in_tkt_ktypes */
-               if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
-                   /* Reduce it to a count */
-                   context->in_tkt_ktype_count = (int) ibuf;
-                   if ((context->in_tkt_ktypes = (krb5_enctype *)
-                        malloc(sizeof(krb5_enctype) *
-                               (context->in_tkt_ktype_count+1)))) {
-                       memset(context->in_tkt_ktypes,
-                              0,
-                              sizeof(krb5_enctype) *
-                              (context->in_tkt_ktype_count + 1));
-                       for (i=0; i<context->in_tkt_ktype_count; i++) {
-                           if ((kret = krb5_ser_unpack_int32(&ibuf,
-                                                             &bp, &remain)))
-                               break;
-                           context->in_tkt_ktypes[i] = (krb5_enctype) ibuf;
-                       }
-                   }
-               }
-
-               /* Get the number of tgs_ktypes */
-               if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
-                   /* Reduce it to a count */
-                   context->tgs_ktype_count = (int) ibuf;
-                   if ((context->tgs_ktypes = (krb5_enctype *)
-                        malloc(sizeof(krb5_enctype) *
-                               (context->tgs_ktype_count+1)))) {
-                       memset(context->tgs_ktypes,
-                              0,
-                              sizeof(krb5_enctype) *
-                              (context->tgs_ktype_count + 1));
-                       for (i=0; i<context->tgs_ktype_count; i++) {
-                           if ((kret = krb5_ser_unpack_int32(&ibuf,
-                                                             &bp, &remain)))
-                               break;
-                           context->tgs_ktypes[i] = (krb5_enctype) ibuf;
-                       }
-                   }
-               }
-
-               /* Attempt to read in the os_context */
-               if (!kret) {
-                   kret = krb5_internalize_opaque(kcontext,
-                                                  KV5M_OS_CONTEXT,
-                                                  (krb5_pointer *)
-                                                  &context->os_context,
-                                                  &bp,
-                                                  &remain);
-                   if ((kret == EINVAL) || (kret == ENOENT))
-                       kret = 0;
-               }
-
-               /* Attempt to read in the db_context */
-               if (!kret) {
-                   kret = krb5_internalize_opaque(kcontext,
-                                                  KV5M_DB_CONTEXT,
-                                                  (krb5_pointer *)
-                                                  &context->db_context,
-                                                  &bp,
-                                                  &remain);
-                   if ((kret == EINVAL) || (kret == ENOENT))
-                       kret = 0;
-               }
-
-               /* Attempt to read in the profile */
-               if (!kret) {
-                   kret = krb5_internalize_opaque(kcontext,
-                                                  PROF_MAGIC_PROFILE,
-                                                  (krb5_pointer *)
-                                                  &context->profile,
-                                                  &bp,
-                                                  &remain);
-                   if ((kret == EINVAL) || (kret == ENOENT))
-                       kret = 0;
-               }
-
-               /* Finally, find the trailer */
-               if (!kret) {
-                   kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
-                   if (!kret && (ibuf == KV5M_CONTEXT))
-                       context->magic = KV5M_CONTEXT;
-                   else
-                       kret = EINVAL;
-               }
-           }
-           if (!kret) {
-               *buffer = bp;
-               *lenremain = remain;
-               *argp = (krb5_pointer) context;
-           }
-           else
-               krb5_free_context(context);
+    if (ibuf != KV5M_CONTEXT)
+       return (EINVAL);
+
+    /* Get memory for the context */
+    context = (krb5_context) malloc(sizeof(struct _krb5_context));
+    if (!context)
+       return (ENOMEM);
+    memset(context, 0, sizeof(struct _krb5_context));
+
+    /* Get the size of the default realm */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+
+    if (ibuf) {
+       context->default_realm = (char *) malloc((size_t) ibuf+1);
+       if (!context->default_realm) {
+           kret = ENOMEM;
+           goto cleanup;
        }
+
+       kret = krb5_ser_unpack_bytes((krb5_octet *) context->default_realm,
+                                    (size_t) ibuf, &bp, &remain);
+       if (kret)
+           goto cleanup;
+       
+       context->default_realm[ibuf] = '\0';
+    }
+       
+    /* Get the number of in_tkt_ktypes */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    
+    context->in_tkt_ktype_count = (int) ibuf;
+    context->in_tkt_ktypes = (krb5_enctype *) malloc(sizeof(krb5_enctype) *
+                                    (context->in_tkt_ktype_count+1));
+    if (!context->in_tkt_ktypes) {
+       kret = ENOMEM;
+       goto cleanup;
+    }
+    memset(context->in_tkt_ktypes, 0, (sizeof(krb5_enctype) *
+                                      (context->in_tkt_ktype_count + 1)));
+    
+    for (i=0; i<context->in_tkt_ktype_count; i++) {
+       if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+           goto cleanup;
+       context->in_tkt_ktypes[i] = (krb5_enctype) ibuf;
     }
+
+    /* Get the number of tgs_ktypes */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    
+    context->tgs_ktype_count = (int) ibuf;
+    context->tgs_ktypes = (krb5_enctype *) malloc(sizeof(krb5_enctype) *
+                                 (context->tgs_ktype_count+1));
+    if (!context->tgs_ktypes) {
+       kret = ENOMEM;
+       goto cleanup;
+    }
+    memset(context->tgs_ktypes, 0, (sizeof(krb5_enctype) *
+                                   (context->tgs_ktype_count + 1)));
+    for (i=0; i<context->tgs_ktype_count; i++) {
+       if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+           goto cleanup;
+       context->tgs_ktypes[i] = (krb5_enctype) ibuf;
+    }
+
+    /* Allowable checksum */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->clockskew = (krb5_deltat) ibuf;
+    
+    /* kdc_req_sumtype */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->kdc_req_sumtype = (krb5_cksumtype) ibuf;
+    
+    /* default ap_req_sumtype */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->default_ap_req_sumtype = (krb5_cksumtype) ibuf;
+    
+    /* default_safe_sumtype */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->default_safe_sumtype = (krb5_cksumtype) ibuf;
+
+    /* kdc_default_options */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->kdc_default_options = (krb5_flags) ibuf;
+
+    /* library_options */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->library_options = (krb5_flags) ibuf;
+
+    /* profile_secure */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->profile_secure = (krb5_boolean) ibuf;
+
+    /* fcc_default_format */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->fcc_default_format = (int) ibuf;
+
+    /* scc_default_format */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+    context->scc_default_format = (int) ibuf;
+    
+    /* Attempt to read in the os_context */
+    kret = krb5_internalize_opaque(kcontext, KV5M_OS_CONTEXT,
+                                  (krb5_pointer *) &context->os_context,
+                                  &bp, &remain);
+    if (kret && (kret != EINVAL) && (kret != ENOENT))
+       goto cleanup;
+
+    /* Attempt to read in the db_context */
+    kret = krb5_internalize_opaque(kcontext, KV5M_DB_CONTEXT,
+                                  (krb5_pointer *) &context->db_context,
+                                  &bp, &remain);
+    if (kret && (kret != EINVAL) && (kret != ENOENT))
+       goto cleanup;
+    
+    /* Attempt to read in the profile */
+    kret = krb5_internalize_opaque(kcontext, PROF_MAGIC_PROFILE,
+                                  (krb5_pointer *) &context->profile,
+                                  &bp, &remain);
+    if (kret && (kret != EINVAL) && (kret != ENOENT))
+       goto cleanup;
+    
+    /* Finally, find the trailer */
+    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
+       goto cleanup;
+
+    if (ibuf != KV5M_CONTEXT) {
+       kret = EINVAL;
+       goto cleanup;
+    }
+
+    context->magic = KV5M_CONTEXT;
+    *buffer = bp;
+    *lenremain = remain;
+    *argp = (krb5_pointer) context;
+
+    return 0;
+
+cleanup:
+    if (context)
+       krb5_free_context(context);
     return(kret);
 }
 \f