예제 #1
0
파일: ser_cksum.c 프로젝트: Baalmart/krb5
/*
 * krb5_checksum_internalize()  - Internalize the krb5_checksum.
 */
static krb5_error_code
krb5_checksum_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code     kret;
    krb5_checksum       *checksum;
    krb5_int32          ibuf;
    krb5_octet          *bp;
    size_t              remain;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
        ibuf = 0;
    if (ibuf == KV5M_CHECKSUM) {
        kret = ENOMEM;

        /* Get a checksum */
        if ((remain >= (2*sizeof(krb5_int32))) &&
            (checksum = (krb5_checksum *) calloc(1, sizeof(krb5_checksum)))) {
            /* Get the checksum_type */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            checksum->checksum_type = (krb5_cksumtype) ibuf;

            /* Get the length */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            checksum->length = (int) ibuf;

            /* Get the string */
            if (!ibuf ||
                ((checksum->contents = (krb5_octet *)
                  malloc((size_t) (ibuf))) &&
                 !(kret = krb5_ser_unpack_bytes(checksum->contents,
                                                (size_t) ibuf,
                                                &bp, &remain)))) {

                /* Get the trailer */
                kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
                if (!kret && (ibuf == KV5M_CHECKSUM)) {
                    checksum->magic = KV5M_CHECKSUM;
                    *buffer = bp;
                    *lenremain = remain;
                    *argp = (krb5_pointer) checksum;
                }
                else
                    kret = EINVAL;
            }
            if (kret) {
                if (checksum->contents)
                    free(checksum->contents);
                free(checksum);
            }
        }
    }
    return(kret);
}
예제 #2
0
파일: ser_rc.c 프로젝트: Akasurde/krb5
/*
 * krb5_rcache_internalize()    - Internalize the krb5_rcache.
 */
static krb5_error_code
krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code     kret;
    krb5_rcache         rcache = NULL;
    krb5_int32          ibuf;
    krb5_octet          *bp;
    size_t              remain;
    char                *rcname = NULL;

    bp = *buffer;
    remain = *lenremain;

    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain) || ibuf != KV5M_RCACHE)
        return EINVAL;

    /* Get the length of the rcache name */
    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (kret)
        return kret;

    /* Get the rcache name. */
    rcname = malloc(ibuf + 1);
    if (!rcname)
        return ENOMEM;
    kret = krb5_ser_unpack_bytes((krb5_octet*)rcname, (size_t) ibuf,
                                 &bp, &remain);
    if (kret)
        goto cleanup;
    rcname[ibuf] = '\0';

    /* Resolve and recover the rcache. */
    kret = krb5_rc_resolve_full(kcontext, &rcache, rcname);
    if (kret)
        goto cleanup;
    krb5_rc_recover(kcontext, rcache);

    /* Read our magic number again. */
    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (kret)
        goto cleanup;
    if (ibuf != KV5M_RCACHE) {
        kret = EINVAL;
        goto cleanup;
    }

    *buffer = bp;
    *lenremain = remain;
    *argp = (krb5_pointer) rcache;
cleanup:
    free(rcname);
    if (kret != 0 && rcache)
        krb5_rc_close(kcontext, rcache);
    return kret;
}
예제 #3
0
파일: ser_adata.c 프로젝트: Brainiarc7/pbis
/*
 * krb5_authdata_internalize()  - Internalize the krb5_authdata.
 */
static krb5_error_code
krb5_authdata_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code     kret;
    krb5_authdata       *authdata;
    krb5_int32          ibuf;
    krb5_octet          *bp;
    size_t              remain;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
        ibuf = 0;
    if (ibuf == KV5M_AUTHDATA) {
        kret = ENOMEM;

        /* Get a authdata */
        if ((remain >= (2*sizeof(krb5_int32))) &&
            (authdata = (krb5_authdata *) calloc(1, sizeof(krb5_authdata)))) {

            /* Get the ad_type */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            authdata->ad_type = (krb5_authdatatype) ibuf;

            /* Get the length */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            authdata->length = (int) ibuf;

            /* Get the string */
            if ((authdata->contents = (krb5_octet *)
                 malloc((size_t) (ibuf))) &&
                !(kret = krb5_ser_unpack_bytes(authdata->contents,
                                               (size_t) ibuf,
                                               &bp, &remain))) {
                if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
                    ibuf = 0;
                if (ibuf == KV5M_AUTHDATA) {
                    authdata->magic = KV5M_AUTHDATA;
                    *buffer = bp;
                    *lenremain = remain;
                    *argp = (krb5_pointer) authdata;
                }
                else
                    kret = EINVAL;
            }
            if (kret) {
                if (authdata->contents)
                    free(authdata->contents);
                free(authdata);
            }
        }
    }
    return(kret);
}
예제 #4
0
파일: ser_key.c 프로젝트: Brainiarc7/pbis
/*
 * krb5_keyblock_internalize()  - Internalize the krb5_keyblock.
 */
static krb5_error_code
krb5_keyblock_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code     kret;
    krb5_keyblock       *keyblock;
    krb5_int32          ibuf;
    krb5_octet          *bp;
    size_t              remain;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
        ibuf = 0;
    if (ibuf == KV5M_KEYBLOCK) {
        kret = ENOMEM;

        /* Get a keyblock */
        if ((remain >= (3*sizeof(krb5_int32))) &&
            (keyblock = (krb5_keyblock *) calloc(1, sizeof(krb5_keyblock)))) {
            /* Get the enctype */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            keyblock->enctype = (krb5_enctype) ibuf;

            /* Get the length */
            (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
            keyblock->length = (int) ibuf;

            /* Get the string */
            if ((keyblock->contents = (krb5_octet *) malloc((size_t) (ibuf)))&&
                !(kret = krb5_ser_unpack_bytes(keyblock->contents,
                                               (size_t) ibuf,
                                               &bp, &remain))) {
                kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
                if (!kret && (ibuf == KV5M_KEYBLOCK)) {
                    kret = 0;
                    *buffer = bp;
                    *lenremain = remain;
                    keyblock->magic = KV5M_KEYBLOCK;
                    *argp = (krb5_pointer) keyblock;
                }
                else
                    kret = EINVAL;
            }
            if (kret) {
                if (keyblock->contents)
                    free(keyblock->contents);
                free(keyblock);
            }
        }
    }
    return(kret);
}
예제 #5
0
파일: ser_princ.c 프로젝트: aosm/Kerberos
/*
 * krb5_principal_internalize()	- Internalize the krb5_principal.
 */
static krb5_error_code
krb5_principal_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_principal	principal;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    char		*tmpname;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_PRINCIPAL) {
	kret = ENOMEM;

	/* See if we have enough data for the length */
	if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
	    /* Get the string */
	    if ((tmpname = (char *) malloc((size_t) (ibuf+1))) &&
		!(kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname,
					       (size_t) ibuf,
					       &bp, &remain))) {
		tmpname[ibuf] = '\0';

		/* Parse the name to a principal structure */
		principal = (krb5_principal) NULL;
		kret = krb5_parse_name(kcontext, tmpname, &principal);
		if (!kret) {
		    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
		    if (!kret && (ibuf == KV5M_PRINCIPAL)) {
			*buffer = bp;
			*lenremain = remain;
			*argp = principal;
		    }
		    else
			kret = EINVAL;
		}
		if (kret && principal)
		    krb5_free_principal(kcontext, principal);
		free(tmpname);
	    }
	}
    }
    return(kret);
}
예제 #6
0
파일: ser_rc.c 프로젝트: andreiw/polaris
/*
 * krb5_rcache_internalize()	- Internalize the krb5_rcache.
 */
static krb5_error_code
krb5_rcache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_rcache		rcache;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    char		*rcname;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_RCACHE) {
	kret = ENOMEM;

	/* Get the length of the rcache name */
	kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);

	if (!kret &&
	    (rcname = (char *) malloc((size_t) (ibuf+1))) &&
	    !(kret = krb5_ser_unpack_bytes((krb5_octet *) rcname,
					   (size_t) ibuf,
					   &bp, &remain))) {
	    rcname[ibuf] = '\0';
	    if (!(kret = krb5_rc_resolve_full(kcontext, &rcache, rcname))) {
		(void) krb5_rc_close(kcontext, rcache);
		(void) krb5_rc_recover(kcontext, rcache);
		if (!kret &&
		    !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) &&
		    (ibuf == KV5M_RCACHE)) {
		    *buffer = bp;
		    *lenremain = remain;
		    *argp = (krb5_pointer) rcache;
		}
		else
		    (void)krb5_rc_close(kcontext, rcache);
	    }
	    free(rcname);
	}
    }
    return(kret);
}
예제 #7
0
파일: ser_actx.c 프로젝트: OPSF/uClinux
/*
 * krb5_auth_context_internalize()	- Internalize the krb5_auth_context.
 */
static krb5_error_code
krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_auth_context	auth_context;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    krb5_int32		ivlen;
    krb5_int32		tag;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_AUTH_CONTEXT) {
	kret = ENOMEM;

	/* Get memory for the auth_context */
	if ((remain >= (5*sizeof(krb5_int32))) &&
	    (auth_context = (krb5_auth_context)
	     calloc(1, sizeof(struct _krb5_auth_context)))) {

	    /* Get auth_context_flags */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->auth_context_flags = ibuf;

	    /* Get remote_seq_number */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->remote_seq_number = ibuf;

	    /* Get local_seq_number */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->local_seq_number = ibuf;

	    /* 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->safe_cksumtype = (krb5_cksumtype) ibuf;

	    /* Get length of i_vector */
	    (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain);

	    if (ivlen) {
		if ((auth_context->i_vector =
		     (krb5_pointer) malloc((size_t)ivlen)))
		    kret = krb5_ser_unpack_bytes(auth_context->i_vector,
						 (size_t) ivlen,
						 &bp,
						 &remain);
		else
		    kret = ENOMEM;
	    }
	    else
		kret = 0;
	    
	    /* Peek at next token */
	    tag = 0;
	    if (!kret)
		kret = krb5_ser_unpack_int32(&tag, &bp, &remain);

	    /* This is the remote_addr */
	    if (!kret && (tag == TOKEN_RADDR)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     remote_addr,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the remote_port */
	    if (!kret && (tag == TOKEN_RPORT)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     remote_port,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the local_addr */
	    if (!kret && (tag == TOKEN_LADDR)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     local_addr,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the local_port */
	    if (!kret && (tag == TOKEN_LPORT)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     local_port,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the keyblock */
	    if (!kret && (tag == TOKEN_KEYBLOCK)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_KEYBLOCK,
						     (krb5_pointer *)
						     &auth_context->keyblock,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the send_subkey */
	    if (!kret && (tag == TOKEN_LSKBLOCK)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_KEYBLOCK,
						     (krb5_pointer *)
						     &auth_context->
						     send_subkey,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the recv_subkey */
	    if (!kret) {
		if (tag == TOKEN_RSKBLOCK) {
		    kret = krb5_internalize_opaque(kcontext,
						   KV5M_KEYBLOCK,
						   (krb5_pointer *)
						   &auth_context->
						   recv_subkey,
						   &bp,
						   &remain);
		}
		else {
		    /*
		     * We read the next tag, but it's not of any use here, so
		     * we effectively 'unget' it here.
		     */
		    bp -= sizeof(krb5_int32);
		    remain += sizeof(krb5_int32);
		}
	    }

	    /* Now find the authentp */
	    if (!kret) {
		if ((kret = krb5_internalize_opaque(kcontext,
						    KV5M_AUTHENTICATOR,
						    (krb5_pointer *)
						    &auth_context->authentp,
						    &bp,
						    &remain))) {
		    if (kret == EINVAL)
			kret = 0;
		}
	    }

	    /* Finally, find the trailer */
	    if (!kret) {
		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
		if (!kret && (ibuf != KV5M_AUTH_CONTEXT))
		    kret = EINVAL;
	    }
	    if (!kret) {
		*buffer = bp;
		*lenremain = remain;
		auth_context->magic = KV5M_AUTH_CONTEXT;
		*argp = (krb5_pointer) auth_context;
	    }
	    else
		krb5_auth_con_free(kcontext, auth_context);
	}
    }
    return(kret);
}
예제 #8
0
파일: ser_cc.c 프로젝트: Baalmart/krb5
/*
 * krb5_ccache_internalize()    - Internalize the krb5_ccache.
 */
static krb5_error_code
krb5_ccache_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code     kret;
    krb5_ccache         ccache;
    krb5_int32          ibuf;
    krb5_octet          *bp;
    size_t              remain;
    char                *ccname = NULL;

    *argp = NULL;

    bp = *buffer;
    remain = *lenremain;

    /* Read our magic number. */
    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (kret)
        return kret;
    if (ibuf != KV5M_CCACHE)
        return EINVAL;

    /* Unpack and validate the length of the ccache name. */
    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (kret)
        return kret;
    if (ibuf < 0 || (krb5_ui_4) ibuf > remain)
        return EINVAL;

    /* Allocate and unpack the name. */
    ccname = malloc(ibuf + 1);
    if (!ccname)
        return ENOMEM;
    kret = krb5_ser_unpack_bytes((krb5_octet *) ccname, (size_t) ibuf,
                                 &bp, &remain);
    if (kret)
        goto cleanup;
    ccname[ibuf] = '\0';

    /* Read the second magic number. */
    kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (kret)
        goto cleanup;
    if (ibuf != KV5M_CCACHE) {
        kret = EINVAL;
        goto cleanup;
    }

    /* Resolve the named credential cache. */
    kret = krb5_cc_resolve(kcontext, ccname, &ccache);
    if (kret)
        goto cleanup;

    *buffer = bp;
    *lenremain = remain;
    *argp = ccache;

cleanup:
    free(ccname);
    return(kret);
}
예제 #9
0
/*ARGSUSED*/
static krb5_error_code
krb5_address_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_address	*address;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_ADDRESS) {
	kret = ENOMEM;

	/* Get a address */
	if ((remain >= (2*sizeof(krb5_int32))) &&
	    (address = (krb5_address *) MALLOC(sizeof(krb5_address)))) {
	    (void) memset(address, 0, sizeof(krb5_address));

	    address->magic = KV5M_ADDRESS;

	    /* Get the addrtype */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    address->addrtype = (krb5_addrtype) ibuf;

	    /* Get the length */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    address->length = (int) ibuf;

	    /* Get the string */
	    /* Solaris Kerberos */
	    address->contents = (krb5_octet *) MALLOC((size_t) (ibuf));
	    if ((address->contents) &&
		!(kret = krb5_ser_unpack_bytes(address->contents,
					       (size_t) ibuf,
					       &bp, &remain))) {
		/* Get the trailer */
		if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
		    ibuf = 0;

		if (!kret && (ibuf == KV5M_ADDRESS)) {
		    address->magic = KV5M_ADDRESS;
		    *buffer = bp;
		    *lenremain = remain;
		    *argp = (krb5_pointer) address;
		}
		else
		    kret = EINVAL;
	    }
	    if (kret) {
		if (address->contents)
		    FREE(address->contents, address->length);
		FREE(address, sizeof (krb5_address));
	    }
	}
    }
    return(kret);
}
예제 #10
0
파일: ser_ctx.c 프로젝트: andreiw/polaris
/*
 * krb5_context_internalize()	- Internalize the krb5_context.
 */
static krb5_error_code
krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_context	context;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    int			i;

    bp = *buffer;
    remain = *lenremain;

    /* Read our magic number */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	return (EINVAL);

    if (ibuf != KV5M_CONTEXT)
	return (EINVAL);

    /* Get memory for the context */
    context = (krb5_context) MALLOC(sizeof(struct _krb5_context));
    if (!context)
	return (ENOMEM);
    (void) 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;
    }
    (void) 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;
    }
    (void) 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.  It's an array now, but
       we still treat it in most places as a separate object with
       a pointer.  */
    {
	krb5_os_context osp = 0;
	kret = krb5_internalize_opaque(kcontext, KV5M_OS_CONTEXT,
				       (krb5_pointer *) &osp,
				       &bp, &remain);
	if (kret && (kret != EINVAL) && (kret != ENOENT))
	    goto cleanup;
	/* Put the newly allocated data into the krb5_context
	   structure where we're really keeping it these days.  */
	if (osp)
	    *context->os_context = *osp;
	free(osp);
    }

    /* 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;
   
#ifndef _KERNEL 
    /* Attempt to read in the profile */
    kret = krb5_internalize_opaque(kcontext, PROF_MAGIC_PROFILE,
				   (krb5_pointer *) &context->profile,
				   &bp, &remain);
#endif
    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);
}