Exemplo n.º 1
0
/* Called with the mutex already locked.  */
krb5_error_code
krb5_rc_dfl_close_no_free(krb5_context context, krb5_rcache id)
{
    struct dfl_data *t = (struct dfl_data *)id->data;
    struct authlist *q;

    FREE(t->h);
    if (t->name)
	FREE(t->name);
    while ((q = t->a))
    {
	t->a = q->na;
	FREE(q->rep.client);
	FREE(q->rep.server);
	FREE(q);
    }
#ifndef NOIOSTUFF
    (void) krb5_rc_io_close(context, &t->d);
#endif
    FREE(t);
    return 0;
}
Exemplo n.º 2
0
static krb5_error_code
krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id)
{
#ifdef NOIOSTUFF
    return KRB5_RC_NOIO;
#else

    struct dfl_data *t = (struct dfl_data *)id->data;
    krb5_donot_replay *rep = 0;
    krb5_error_code retval;
    long max_size;
    int expired_entries = 0;
    krb5_int32 now;

    if ((retval = krb5_rc_io_open(context, &t->d, t->name))) {
        return retval;
    }

    t->recovering = 1;

    max_size = krb5_rc_io_size(context, &t->d);

    rep = NULL;
    if (krb5_rc_io_read(context, &t->d, (krb5_pointer) &t->lifespan,
                        sizeof(t->lifespan))) {
        retval = KRB5_RC_IO;
        goto io_fail;
    }

    if (!(rep = (krb5_donot_replay *) malloc(sizeof(krb5_donot_replay)))) {
        retval = KRB5_RC_MALLOC;
        goto io_fail;
    }
    rep->client = rep->server = rep->msghash = NULL;

    if (krb5_timeofday(context, &now))
        now = 0;

    /* now read in each auth_replay and insert into table */
    for (;;) {
        if (krb5_rc_io_mark(context, &t->d)) {
            retval = KRB5_RC_IO;
            goto io_fail;
        }

        retval = krb5_rc_io_fetch(context, t, rep, (int) max_size);

        if (retval == KRB5_RC_IO_EOF)
            break;
        else if (retval != 0)
            goto io_fail;

        if (alive(now, rep, t->lifespan) != CMP_EXPIRED) {
            if (rc_store(context, id, rep, now, TRUE) == CMP_MALLOC) {
                retval = KRB5_RC_MALLOC; goto io_fail;
            }
        } else {
            expired_entries++;
        }

        /*
         *  free fields allocated by rc_io_fetch
         */
        free(rep->server);
        free(rep->client);
        if (rep->msghash)
            free(rep->msghash);
        rep->client = rep->server = rep->msghash = NULL;
    }
    retval = 0;
    krb5_rc_io_unmark(context, &t->d);
    /*
     *  An automatic expunge here could remove the need for
     *  mark/unmark but that would be inefficient.
     */
io_fail:
    krb5_rc_free_entry(context, &rep);
    if (retval)
        krb5_rc_io_close(context, &t->d);
    else if (expired_entries > EXCESSREPS)
        retval = krb5_rc_dfl_expunge_locked(context, id);
    t->recovering = 0;
    return retval;

#endif
}
Exemplo n.º 3
0
krb5_error_code
krb5_rc_io_move(krb5_context context, krb5_rc_iostuff *new1,
                krb5_rc_iostuff *old)
{
#if defined(_WIN32) || defined(__CYGWIN__)
    char *new_fn = NULL;
    char *old_fn = NULL;
    off_t offset = 0;
    krb5_error_code retval = 0;
    /*
     * Initial work around provided by Tom Sanfilippo to work around
     * poor Windows emulation of POSIX functions.  Rename and dup has
     * different semantics!
     *
     * Additional fixes and explanation provided by [email protected]:
     *
     * First, we save the offset of "old".  Then, we close and remove
     * the "new" file so we can do the rename.  We also close "old" to
     * make sure the rename succeeds (though that might not be
     * necessary on some systems).
     *
     * Next, we do the rename.  If all goes well, we seek the "new"
     * file to the position "old" was at.
     *
     * --- WARNING!!! ---
     *
     * Since "old" is now gone, we mourn its disappearance, but we
     * cannot emulate that Unix behavior...  THIS BEHAVIOR IS
     * DIFFERENT FROM UNIX.  However, it is ok because this function
     * gets called such that "old" gets closed right afterwards.
     */
    offset = lseek(old->fd, 0, SEEK_CUR);

    new_fn = new1->fn;
    new1->fn = NULL;
    close(new1->fd);
    new1->fd = -1;

    unlink(new_fn);

    old_fn = old->fn;
    old->fn = NULL;
    close(old->fd);
    old->fd = -1;

    if (rename(old_fn, new_fn) == -1) { /* MUST be atomic! */
        retval = KRB5_RC_IO_UNKNOWN;
        goto cleanup;
    }

    retval = krb5_rc_io_open_internal(context, new1, 0, new_fn);
    if (retval)
        goto cleanup;

    if (lseek(new1->fd, offset, SEEK_SET) == -1) {
        retval = KRB5_RC_IO_UNKNOWN;
        goto cleanup;
    }

cleanup:
    free(new_fn);
    free(old_fn);
    return retval;
#else
    char *fn = NULL;
    if (rename(old->fn, new1->fn) == -1) /* MUST be atomic! */
        return KRB5_RC_IO_UNKNOWN;
    fn = new1->fn;
    new1->fn = NULL;            /* avoid clobbering */
    (void) krb5_rc_io_close(context, new1);
    new1->fn = fn;
    new1->fd = dup(old->fd);
    set_cloexec_fd(new1->fd);
    return 0;
#endif
}