static krb5_error_code read_principal(krb5_context context, krb5_ccache id, krb5_principal *princ) { krb5_error_code ret; struct k5buf buf; size_t maxsize; unsigned char *bytes; *princ = NULL; k5_cc_mutex_assert_locked(context, &((fcc_data *)id->data)->lock); k5_buf_init_dynamic(&buf); /* Read the principal representation into memory. */ ret = get_size(context, id, &maxsize); if (ret) goto cleanup; ret = load_principal(context, id, maxsize, &buf); if (ret) goto cleanup; bytes = (unsigned char *)k5_buf_data(&buf); if (bytes == NULL) { ret = ENOMEM; goto cleanup; } /* Unmarshal it from buf into princ. */ ret = k5_unmarshal_princ(bytes, k5_buf_len(&buf), version(id), princ); cleanup: k5_free_buf(&buf); return ret; }
/* Get the next credential from the cache file. */ static krb5_error_code KRB5_CALLCONV fcc_next_cred(krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, krb5_creds *creds) { krb5_error_code ret; krb5_fcc_cursor *fcursor = *cursor; fcc_data *data = id->data; struct k5buf buf; size_t maxsize; unsigned char *bytes; memset(creds, 0, sizeof(*creds)); k5_cc_mutex_lock(context, &data->lock); MAYBE_OPEN(context, id, FCC_OPEN_RDONLY); k5_buf_init_dynamic(&buf); if (fcc_lseek(data, fcursor->pos, SEEK_SET) == -1) { ret = interpret_errno(context, errno); goto cleanup; } /* Load a marshalled cred into memory. */ ret = get_size(context, id, &maxsize); if (ret) return ret; ret = load_cred(context, id, maxsize, &buf); if (ret) goto cleanup; bytes = (unsigned char *)k5_buf_data(&buf); if (bytes == NULL) { ret = ENOMEM; goto cleanup; } /* Unmarshal it from buf into creds. */ fcursor->pos = fcc_lseek(data, 0, SEEK_CUR); ret = k5_unmarshal_cred(bytes, k5_buf_len(&buf), version(id), creds); cleanup: k5_free_buf(&buf); MAYBE_CLOSE(context, id, ret); k5_cc_mutex_unlock(context, &data->lock); return ret; }
static krb5_error_code krb5_rc_io_store(krb5_context context, struct dfl_data *t, krb5_donot_replay *rep) { size_t clientlen, serverlen; ssize_t buflen; unsigned int len; krb5_error_code ret; struct k5buf buf, extbuf; char *bufptr, *extstr; clientlen = strlen(rep->client); serverlen = strlen(rep->server); if (rep->msghash) { /* * Write a hash extension record, to be followed by a record * in regular format (without the message hash) for the * benefit of old implementations. */ /* Format the extension value so we know its length. */ k5_buf_init_dynamic(&extbuf); k5_buf_add_fmt(&extbuf, "HASH:%s %lu:%s %lu:%s", rep->msghash, (unsigned long)clientlen, rep->client, (unsigned long)serverlen, rep->server); extstr = k5_buf_data(&extbuf); if (!extstr) return KRB5_RC_MALLOC; /* * Put the extension value into the server field of a * regular-format record, with an empty client field. */ k5_buf_init_dynamic(&buf); len = 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, "", 1); len = strlen(extstr) + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, extstr, len); k5_buf_add_len(&buf, (char *)&rep->cusec, sizeof(rep->cusec)); k5_buf_add_len(&buf, (char *)&rep->ctime, sizeof(rep->ctime)); free(extstr); } else /* No extension record needed. */ k5_buf_init_dynamic(&buf); len = clientlen + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, rep->client, len); len = serverlen + 1; k5_buf_add_len(&buf, (char *)&len, sizeof(len)); k5_buf_add_len(&buf, rep->server, len); k5_buf_add_len(&buf, (char *)&rep->cusec, sizeof(rep->cusec)); k5_buf_add_len(&buf, (char *)&rep->ctime, sizeof(rep->ctime)); bufptr = k5_buf_data(&buf); buflen = k5_buf_len(&buf); if (bufptr == NULL || buflen < 0) return KRB5_RC_MALLOC; ret = krb5_rc_io_write(context, &t->d, bufptr, buflen); k5_free_buf(&buf); return ret; }