krb5_error_code KRB5_LIB_FUNCTION _krb5_krb_create_ciph(krb5_context context, const krb5_keyblock *session, const char *service, const char *instance, const char *realm, uint32_t life, unsigned char kvno, const krb5_data *ticket, uint32_t kdc_time, const krb5_keyblock *key, krb5_data *enc_data) { krb5_error_code ret; krb5_storage *sp; krb5_data_zero(enc_data); sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); /* session key */ ret = krb5_storage_write(sp, session->keyvalue.data, session->keyvalue.length); if (ret != session->keyvalue.length) { ret = EINVAL; goto error; } RCHECK(ret, put_nir(sp, service, instance, realm), error); RCHECK(ret, krb5_store_int8(sp, life), error); RCHECK(ret, krb5_store_int8(sp, kvno), error); RCHECK(ret, krb5_store_int8(sp, ticket->length), error); ret = krb5_storage_write(sp, ticket->data, ticket->length); if (ret != ticket->length) { ret = EINVAL; goto error; } RCHECK(ret, krb5_store_int32(sp, kdc_time), error); ret = storage_to_etext(context, sp, key, enc_data); error: krb5_storage_free(sp); if (ret) krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); return ret; }
int krb_mk_req(KTEXT authent, char *service, char *instance, char *realm, int32_t checksum) #endif { CREDENTIALS cr; KTEXT_ST req; krb5_storage *sp; int code; /* XXX get user realm */ const char *myrealm = realm; krb5_data a; code = krb_get_cred(service, instance, realm, &cr); if(code || time(NULL) > krb_life_to_time(cr.issue_date, cr.lifetime)){ code = get_ad_tkt((char *)service, (char *)instance, (char *)realm, lifetime); if(code == KSUCCESS) code = krb_get_cred(service, instance, realm, &cr); } if(code) return code; sp = krb5_storage_emem(); krb5_store_int8(sp, KRB_PROT_VERSION); krb5_store_int8(sp, AUTH_MSG_APPL_REQUEST); krb5_store_int8(sp, cr.kvno); krb5_store_stringz(sp, realm); krb5_store_int8(sp, cr.ticket_st.length); build_request(&req, cr.pname, cr.pinst, myrealm, checksum); encrypt_ktext(&req, &cr.session, DES_ENCRYPT); krb5_store_int8(sp, req.length); krb5_storage_write(sp, cr.ticket_st.dat, cr.ticket_st.length); krb5_storage_write(sp, req.dat, req.length); krb5_storage_to_data(sp, &a); krb5_storage_free(sp); memcpy(authent->dat, a.data, a.length); authent->length = a.length; krb5_data_free(&a); memset(&cr, 0, sizeof(cr)); memset(&req, 0, sizeof(req)); return KSUCCESS; }
krb5_error_code KRB5_LIB_FUNCTION _krb5_krb_create_ticket(krb5_context context, unsigned char flags, const char *pname, const char *pinstance, const char *prealm, int32_t paddress, const krb5_keyblock *session, int16_t life, int32_t life_sec, const char *sname, const char *sinstance, const krb5_keyblock *key, krb5_data *enc_data) { krb5_error_code ret; krb5_storage *sp; krb5_data_zero(enc_data); sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); RCHECK(ret, krb5_store_int8(sp, flags), error); RCHECK(ret, put_nir(sp, pname, pinstance, prealm), error); RCHECK(ret, krb5_store_int32(sp, ntohl(paddress)), error); /* session key */ ret = krb5_storage_write(sp, session->keyvalue.data, session->keyvalue.length); if (ret != session->keyvalue.length) { ret = EINVAL; goto error; } RCHECK(ret, krb5_store_int8(sp, life), error); RCHECK(ret, krb5_store_int32(sp, life_sec), error); RCHECK(ret, put_nir(sp, sname, sinstance, NULL), error); ret = storage_to_etext(context, sp, key, enc_data); error: krb5_storage_free(sp); if (ret) krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); return ret; }
static krb5_error_code fcc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { krb5_fcache *f = FCACHE(id); int ret = 0; int fd; char *filename = f->filename; unlink (filename); ret = fcc_open(context, id, &fd, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600); if(ret) return ret; { krb5_storage *sp; sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); if(context->fcache_vno != 0) f->version = context->fcache_vno; else f->version = KRB5_FCC_FVNO_4; ret |= krb5_store_int8(sp, 5); ret |= krb5_store_int8(sp, f->version); storage_set_flags(context, sp, f->version); if(f->version == KRB5_FCC_FVNO_4 && ret == 0) { /* V4 stuff */ if (context->kdc_sec_offset) { ret |= krb5_store_int16 (sp, 12); /* length */ ret |= krb5_store_int16 (sp, FCC_TAG_DELTATIME); /* Tag */ ret |= krb5_store_int16 (sp, 8); /* length of data */ ret |= krb5_store_int32 (sp, context->kdc_sec_offset); ret |= krb5_store_int32 (sp, context->kdc_usec_offset); } else { ret |= krb5_store_int16 (sp, 0); } } ret |= krb5_store_principal(sp, primary_principal); ret |= write_storage(context, sp, fd); krb5_storage_free(sp); } fcc_unlock(context, fd); if (close(fd) < 0) if (ret == 0) { ret = errno; krb5_set_error_message (context, ret, N_("close %s: %s", ""), FILENAME(id), strerror(ret)); } return ret; }
static krb5_error_code KRB5_CALLCONV fkt_setup_keytab(krb5_context context, krb5_keytab id, krb5_storage *sp) { krb5_error_code ret; ret = krb5_store_int8(sp, 5); if(ret) return ret; if(id->version == 0) id->version = KRB5_KT_VNO; return krb5_store_int8 (sp, id->version); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_store_creds(krb5_storage *sp, krb5_creds *creds) { int ret; ret = krb5_store_principal(sp, creds->client); if(ret) return ret; ret = krb5_store_principal(sp, creds->server); if(ret) return ret; ret = krb5_store_keyblock(sp, creds->session); if(ret) return ret; ret = krb5_store_times(sp, creds->times); if(ret) return ret; ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ if(ret) return ret; ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); if(ret) return ret; ret = krb5_store_addrs(sp, creds->addresses); if(ret) return ret; ret = krb5_store_authdata(sp, creds->authdata); if(ret) return ret; ret = krb5_store_data(sp, creds->ticket); if(ret) return ret; ret = krb5_store_data(sp, creds->second_ticket); return ret; }
krb5_error_code KRB5_LIB_FUNCTION _krb5_krb_create_auth_reply(krb5_context context, const char *pname, const char *pinst, const char *prealm, int32_t time_ws, int n, uint32_t x_date, unsigned char kvno, const krb5_data *cipher, krb5_data *data) { krb5_error_code ret; krb5_storage *sp; krb5_data_zero(data); sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error); RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_KDC_REPLY), error); RCHECK(ret, put_nir(sp, pname, pinst, prealm), error); RCHECK(ret, krb5_store_int32(sp, time_ws), error); RCHECK(ret, krb5_store_int8(sp, n), error); RCHECK(ret, krb5_store_int32(sp, x_date), error); RCHECK(ret, krb5_store_int8(sp, kvno), error); RCHECK(ret, krb5_store_int16(sp, cipher->length), error); ret = krb5_storage_write(sp, cipher->data, cipher->length); if (ret != cipher->length) { ret = EINVAL; goto error; } ret = krb5_storage_to_data(sp, data); error: krb5_storage_free(sp); if (ret) krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); return ret; }
/* * Request: * NameZ * * Request: * NameZ * ClientPrincipal * ServerPrincipalPresent * ServerPrincipal OPTIONAL * Password * * Repsonse: * */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL _krb5_kcm_get_initial_ticket(krb5_context context, krb5_ccache id, krb5_principal client, krb5_principal server, const char *password) { krb5_kcmcache *k = KCMCACHE(id); krb5_error_code ret; krb5_storage *request; if (id->ops != &krb5_kcm_ops && id->ops != &krb5_akcm_ops) { krb5_set_error_message(context, EINVAL, "Cache is not a KCM cache"); return EINVAL; } ret = krb5_kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request); if (ret) return ret; ret = krb5_store_stringz(request, k->name); if (ret) { krb5_storage_free(request); return ret; } ret = krb5_store_principal(request, client); if (ret) { krb5_storage_free(request); return ret; } ret = krb5_store_int8(request, (server == NULL) ? 0 : 1); if (ret) { krb5_storage_free(request); return ret; } if (server != NULL) { ret = krb5_store_principal(request, server); if (ret) { krb5_storage_free(request); return ret; } } ret = krb5_store_stringz(request, password); if (ret) { krb5_storage_free(request); return ret; } ret = krb5_kcm_call(context, request, NULL, NULL); krb5_storage_free(request); return ret; }
krb5_error_code KRB5_LIB_FUNCTION _krb5_krb_cr_err_reply(krb5_context context, const char *name, const char *inst, const char *realm, uint32_t time_ws, uint32_t e, const char *e_string, krb5_data *data) { krb5_error_code ret; krb5_storage *sp; krb5_data_zero(data); if (name == NULL) name = ""; if (inst == NULL) inst = ""; if (realm == NULL) realm = ""; if (e_string == NULL) e_string = ""; sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error); RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error); RCHECK(ret, put_nir(sp, name, inst, realm), error); RCHECK(ret, krb5_store_int32(sp, time_ws), error); RCHECK(ret, krb5_store_int32(sp, e), error); RCHECK(ret, krb5_store_stringz(sp, e_string), error); ret = krb5_storage_to_data(sp, data); error: krb5_storage_free(sp); if (ret) krb5_set_error_string(context, "Failed to encode kerberos 4 error"); return 0; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_kcm_storage_request(krb5_context context, uint16_t opcode, krb5_storage **storage_p) { krb5_storage *sp; krb5_error_code ret; *storage_p = NULL; sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } /* Send MAJOR | VERSION | OPCODE */ ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR); if (ret) goto fail; ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR); if (ret) goto fail; ret = krb5_store_int16(sp, opcode); if (ret) goto fail; *storage_p = sp; fail: if (ret) { krb5_set_error_message(context, ret, N_("Failed to encode KCM request", "")); krb5_storage_free(sp); } return ret; }
static krb5_error_code kcm_storage_request(krb5_context context, kcm_operation opcode, krb5_storage **storage_p) { krb5_storage *sp; krb5_error_code ret; *storage_p = NULL; sp = krb5_storage_emem(); if (sp == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return KRB5_CC_NOMEM; } /* Send MAJOR | VERSION | OPCODE */ ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MAJOR); if (ret) goto fail; ret = krb5_store_int8(sp, KCM_PROTOCOL_VERSION_MINOR); if (ret) goto fail; ret = krb5_store_int16(sp, opcode); if (ret) goto fail; *storage_p = sp; fail: if (ret) { krb5_set_error_string(context, "Failed to encode request"); krb5_storage_free(sp); } return ret; }
/* * Request: * NameZ * ServerPrincipalPresent * ServerPrincipal OPTIONAL * Key * * Repsonse: * */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL _krb5_kcm_get_initial_ticket(krb5_context context, krb5_ccache id, krb5_principal server, krb5_keyblock *key) { krb5_kcmcache *k = KCMCACHE(id); krb5_error_code ret; krb5_storage *request; ret = krb5_kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request); if (ret) return ret; ret = krb5_store_stringz(request, k->name); if (ret) { krb5_storage_free(request); return ret; } ret = krb5_store_int8(request, (server == NULL) ? 0 : 1); if (ret) { krb5_storage_free(request); return ret; } if (server != NULL) { ret = krb5_store_principal(request, server); if (ret) { krb5_storage_free(request); return ret; } } ret = krb5_store_keyblock(request, *key); if (ret) { krb5_storage_free(request); return ret; } ret = krb5_kcm_call(context, request, NULL, NULL); krb5_storage_free(request); return ret; }
static void build_request(KTEXT req, const char *name, const char *inst, const char *realm, u_int32_t checksum) { struct timeval tv; krb5_storage *sp; krb5_data data; sp = krb5_storage_emem(); krb5_store_stringz(sp, name); krb5_store_stringz(sp, inst); krb5_store_stringz(sp, realm); krb5_store_int32(sp, checksum); gettimeofday(&tv, NULL); krb5_store_int8(sp, tv.tv_usec / 5000); krb5_store_int32(sp, tv.tv_sec); krb5_storage_to_data(sp, &data); krb5_storage_free(sp); memcpy(req->dat, data.data, data.length); req->length = (data.length + 7) & ~7; krb5_data_free(&data); }
static void test_int8(krb5_context context, krb5_storage *sp) { krb5_error_code ret; int i; int8_t val[] = { 0, 1, -1, 128, -127 }, v; krb5_storage_truncate(sp, 0); for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { ret = krb5_store_int8(sp, val[i]); if (ret) krb5_err(context, 1, ret, "krb5_store_int8"); krb5_storage_seek(sp, 0, SEEK_SET); ret = krb5_ret_int8(sp, &v); if (ret) krb5_err(context, 1, ret, "krb5_ret_int8"); if (v != val[i]) krb5_errx(context, 1, "store and ret mismatch"); } }
static krb5_error_code KRB5_CALLCONV fkt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { int ret; int fd; krb5_storage *sp; struct fkt_data *d = id->data; krb5_data keytab; int32_t len; fd = open (d->filename, O_RDWR | O_BINARY | O_CLOEXEC); if (fd < 0) { fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, 0600); if (fd < 0) { ret = errno; krb5_set_error_message(context, ret, N_("open(%s): %s", ""), d->filename, strerror(ret)); return ret; } rk_cloexec(fd); ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); return ret; } sp = krb5_storage_from_fd(fd); krb5_storage_set_eof_code(sp, KRB5_KT_END); ret = fkt_setup_keytab(context, id, sp); if(ret) { goto out; } storage_set_flags(context, sp, id->version); } else { int8_t pvno, tag; rk_cloexec(fd); ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); return ret; } sp = krb5_storage_from_fd(fd); krb5_storage_set_eof_code(sp, KRB5_KT_END); ret = krb5_ret_int8(sp, &pvno); if(ret) { /* we probably have a zero byte file, so try to set it up properly */ ret = fkt_setup_keytab(context, id, sp); if(ret) { krb5_set_error_message(context, ret, N_("%s: keytab is corrupted: %s", ""), d->filename, strerror(ret)); goto out; } storage_set_flags(context, sp, id->version); } else { if(pvno != 5) { ret = KRB5_KEYTAB_BADVNO; krb5_set_error_message(context, ret, N_("Bad version in keytab %s", ""), d->filename); goto out; } ret = krb5_ret_int8 (sp, &tag); if (ret) { krb5_set_error_message(context, ret, N_("failed reading tag from " "keytab %s", ""), d->filename); goto out; } id->version = tag; storage_set_flags(context, sp, id->version); } } { krb5_storage *emem; emem = krb5_storage_emem(); if(emem == NULL) { ret = krb5_enomem(context); goto out; } ret = krb5_kt_store_principal(context, emem, entry->principal); if(ret) { krb5_set_error_message(context, ret, N_("Failed storing principal " "in keytab %s", ""), d->filename); krb5_storage_free(emem); goto out; } ret = krb5_store_int32 (emem, entry->timestamp); if(ret) { krb5_set_error_message(context, ret, N_("Failed storing timpstamp " "in keytab %s", ""), d->filename); krb5_storage_free(emem); goto out; } ret = krb5_store_int8 (emem, entry->vno % 256); if(ret) { krb5_set_error_message(context, ret, N_("Failed storing kvno " "in keytab %s", ""), d->filename); krb5_storage_free(emem); goto out; } ret = krb5_kt_store_keyblock (context, d, emem, &entry->keyblock); if(ret) { krb5_storage_free(emem); goto out; } if ((d->flags & KRB5_KT_FL_JAVA) == 0) { ret = krb5_store_int32 (emem, entry->vno); if (ret) { krb5_set_error_message(context, ret, N_("Failed storing extended kvno " "in keytab %s", ""), d->filename); krb5_storage_free(emem); goto out; } ret = krb5_store_uint32 (emem, entry->flags); if (ret) { krb5_set_error_message(context, ret, N_("Failed storing extended kvno " "in keytab %s", ""), d->filename); krb5_storage_free(emem); goto out; } } ret = krb5_storage_to_data(emem, &keytab); krb5_storage_free(emem); if(ret) { krb5_set_error_message(context, ret, N_("Failed converting keytab entry " "to memory block for keytab %s", ""), d->filename); goto out; } } while(1) { ret = krb5_ret_int32(sp, &len); if(ret == KRB5_KT_END) { len = keytab.length; break; } if(len < 0) { len = -len; if(len >= (int)keytab.length) { krb5_storage_seek(sp, -4, SEEK_CUR); break; } } krb5_storage_seek(sp, len, SEEK_CUR); } ret = krb5_store_int32(sp, len); if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) { ret = errno; krb5_set_error_message(context, ret, N_("Failed writing keytab block " "in keytab %s: %s", ""), d->filename, strerror(ret)); } memset(keytab.data, 0, keytab.length); krb5_data_free(&keytab); out: krb5_storage_free(sp); _krb5_xunlock(context, fd); close(fd); return ret; }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_store_uint8(krb5_storage *sp, uint8_t value) { return krb5_store_int8(sp, (int8_t)value); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) { int ret; int32_t header = 0; if (creds->client) header |= SC_CLIENT_PRINCIPAL; if (creds->server) header |= SC_SERVER_PRINCIPAL; if (creds->session.keytype != ETYPE_NULL) header |= SC_SESSION_KEY; if (creds->ticket.data) header |= SC_TICKET; if (creds->second_ticket.length) header |= SC_SECOND_TICKET; if (creds->authdata.len) header |= SC_AUTHDATA; if (creds->addresses.len) header |= SC_ADDRESSES; ret = krb5_store_int32(sp, header); if (ret) return ret; if (creds->client) { ret = krb5_store_principal(sp, creds->client); if(ret) return ret; } if (creds->server) { ret = krb5_store_principal(sp, creds->server); if(ret) return ret; } if (creds->session.keytype != ETYPE_NULL) { ret = krb5_store_keyblock(sp, creds->session); if(ret) return ret; } ret = krb5_store_times(sp, creds->times); if(ret) return ret; ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ if(ret) return ret; ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); if(ret) return ret; if (creds->addresses.len) { ret = krb5_store_addrs(sp, creds->addresses); if(ret) return ret; } if (creds->authdata.len) { ret = krb5_store_authdata(sp, creds->authdata); if(ret) return ret; } if (creds->ticket.data) { ret = krb5_store_data(sp, creds->ticket); if(ret) return ret; } if (creds->second_ticket.data) { ret = krb5_store_data(sp, creds->second_ticket); if (ret) return ret; } return ret; }
static krb5_error_code fkt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) { int ret; int fd; krb5_storage *sp; struct fkt_data *d = id->data; krb5_data keytab; int32_t len; fd = open (d->filename, O_RDWR | O_BINARY); if (fd < 0) { fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); if (fd < 0) { ret = errno; krb5_set_error_string(context, "open(%s): %s", d->filename, strerror(ret)); return ret; } ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); return ret; } sp = krb5_storage_from_fd(fd); krb5_storage_set_eof_code(sp, KRB5_KT_END); ret = fkt_setup_keytab(context, id, sp); if(ret) { goto out; } storage_set_flags(context, sp, id->version); } else { int8_t pvno, tag; ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); return ret; } sp = krb5_storage_from_fd(fd); krb5_storage_set_eof_code(sp, KRB5_KT_END); ret = krb5_ret_int8(sp, &pvno); if(ret) { /* we probably have a zero byte file, so try to set it up properly */ ret = fkt_setup_keytab(context, id, sp); if(ret) { krb5_set_error_string(context, "%s: keytab is corrupted: %s", d->filename, strerror(ret)); goto out; } storage_set_flags(context, sp, id->version); } else { if(pvno != 5) { ret = KRB5_KEYTAB_BADVNO; krb5_set_error_string(context, "%s: %s", d->filename, strerror(ret)); goto out; } ret = krb5_ret_int8 (sp, &tag); if (ret) { krb5_set_error_string(context, "%s: reading tag: %s", d->filename, strerror(ret)); goto out; } id->version = tag; storage_set_flags(context, sp, id->version); } } { krb5_storage *emem; emem = krb5_storage_emem(); if(emem == NULL) { ret = ENOMEM; krb5_set_error_string (context, "malloc: out of memory"); goto out; } ret = krb5_kt_store_principal(context, emem, entry->principal); if(ret) { krb5_storage_free(emem); goto out; } ret = krb5_store_int32 (emem, entry->timestamp); if(ret) { krb5_storage_free(emem); goto out; } ret = krb5_store_int8 (emem, entry->vno % 256); if(ret) { krb5_storage_free(emem); goto out; } ret = krb5_kt_store_keyblock (context, emem, &entry->keyblock); if(ret) { krb5_storage_free(emem); goto out; } if ((d->flags & KRB5_KT_FL_JAVA) == 0) { ret = krb5_store_int32 (emem, entry->vno); if (ret) { krb5_storage_free(emem); goto out; } } ret = krb5_storage_to_data(emem, &keytab); krb5_storage_free(emem); if(ret) goto out; } while(1) { ret = krb5_ret_int32(sp, &len); if(ret == KRB5_KT_END) { len = keytab.length; break; } if(len < 0) { len = -len; if(len >= keytab.length) { krb5_storage_seek(sp, -4, SEEK_CUR); break; } } krb5_storage_seek(sp, len, SEEK_CUR); } ret = krb5_store_int32(sp, len); if(krb5_storage_write(sp, keytab.data, keytab.length) < 0) ret = errno; memset(keytab.data, 0, keytab.length); krb5_data_free(&keytab); out: krb5_storage_free(sp); _krb5_xunlock(context, fd); close(fd); return ret; }