Esempio n. 1
0
/*
 * Effects:
 * Destroys the contents of id. id is invalid after call.
 *
 * Errors:
 * system errors (locks related)
 */
krb5_error_code KRB5_CALLCONV
krb5_mcc_destroy(krb5_context context, krb5_ccache id)
{
    krb5_mcc_list_node **curr, *node;
    krb5_mcc_data *d;

    k5_cc_mutex_lock(context, &krb5int_mcc_mutex);

    d = (krb5_mcc_data *)id->data;
    for (curr = &mcc_head; *curr; curr = &(*curr)->next) {
        if ((*curr)->cache == d) {
            node = *curr;
            *curr = node->next;
            free(node);
            break;
        }
    }
    k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);

    k5_cc_mutex_lock(context, &d->lock);

    krb5_mcc_free(context, id);
    free(d->name);
    k5_cc_mutex_unlock(context, &d->lock);
    k5_cc_mutex_destroy(&d->lock);
    free(d);
    free(id);

    krb5_change_cache ();
    return KRB5_OK;
}
Esempio n. 2
0
/* Create or overwrite the cache file with a header and default principal. */
static krb5_error_code KRB5_CALLCONV
fcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ)
{
    krb5_error_code ret;
    fcc_data *data = id->data;
    int st = 0;

    k5_cc_mutex_lock(context, &data->lock);

    MAYBE_OPEN(context, id, FCC_OPEN_AND_ERASE);

#if defined(HAVE_FCHMOD) || defined(HAVE_CHMOD)
#ifdef HAVE_FCHMOD
    st = fchmod(data->fd, S_IRUSR | S_IWUSR);
#else
    st = chmod(data->filename, S_IRUSR | S_IWUSR);
#endif
    if (st == -1) {
        ret = interpret_errno(context, errno);
        MAYBE_CLOSE(context, id, ret);
        k5_cc_mutex_unlock(context, &data->lock);
        return ret;
    }
#endif
    ret = store_principal(context, id, princ);

    MAYBE_CLOSE(context, id, ret);
    k5_cc_mutex_unlock(context, &data->lock);
    krb5_change_cache();
    return ret;
}
Esempio n. 3
0
/*
 * Modifies:
 * id
 *
 * Effects:
 * Creates/refreshes the memory cred cache id.  If the cache exists, its
 * contents are destroyed.
 *
 * Errors:
 * system errors
 */
krb5_error_code KRB5_CALLCONV
krb5_mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ)
{
    krb5_os_context os_ctx = &context->os_context;
    krb5_error_code ret;
    krb5_mcc_data *d;

    d = (krb5_mcc_data *)id->data;
    k5_cc_mutex_lock(context, &d->lock);

    krb5_mcc_free(context, id);

    d = (krb5_mcc_data *)id->data;
    ret = krb5_copy_principal(context, princ,
                              &d->prin);
    update_mcc_change_time(d);

    if (os_ctx->os_flags & KRB5_OS_TOFFSET_VALID) {
        /* Store client time offsets in the cache */
        d->time_offset = os_ctx->time_offset;
        d->usec_offset = os_ctx->usec_offset;
    }

    k5_cc_mutex_unlock(context, &d->lock);
    if (ret == KRB5_OK)
        krb5_change_cache();
    return ret;
}
Esempio n. 4
0
/*
 * Effects:
 * Destroys the contents of id. id is invalid after call.
 */
krb5_error_code KRB5_CALLCONV
krb5_mcc_destroy(krb5_context context, krb5_ccache id)
{
    krb5_mcc_data *d = id->data;
    krb5_boolean removed_from_table = FALSE;

    /* Remove this node from the table if it is still present. */
    k5_cc_mutex_lock(context, &krb5int_mcc_mutex);
    if (k5_hashtab_remove(mcc_hashtab, d->name, strlen(d->name)))
        removed_from_table = TRUE;
    k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);

    /* Empty the cache and remove the reference for the table slot.  There will
     * always be at least one reference left for the handle being destroyed. */
    k5_cc_mutex_lock(context, &d->lock);
    empty_mcc_cache(context, d);
    if (removed_from_table)
        d->refcount--;
    k5_cc_mutex_unlock(context, &d->lock);

    /* Invalidate the handle, possibly removing the last reference to d and
     * freeing it. */
    krb5_mcc_close(context, id);

    krb5_change_cache ();
    return KRB5_OK;
}
Esempio n. 5
0
krb5_error_code KRB5_CALLCONV
krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
{
    krb5_ccache lid;
    char uniquename[8];
    krb5_error_code err;
    krb5_mcc_data *d;

    /* Allocate memory */
    lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
    if (lid == NULL)
        return KRB5_CC_NOMEM;

    lid->ops = &krb5_mcc_ops;

    err = k5_cc_mutex_lock(context, &krb5int_mcc_mutex);
    if (err) {
        free(lid);
        return err;
    }

    /* Check for uniqueness with mutex locked to avoid race conditions */
    while (1) {
        krb5_mcc_list_node *ptr;

        err = krb5int_random_string (context, uniquename, sizeof (uniquename));
        if (err) {
            k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
            free(lid);
            return err;
        }

        for (ptr = mcc_head; ptr; ptr=ptr->next) {
            if (!strcmp(ptr->cache->name, uniquename)) {
                break;  /* got a match, loop again */
            }
        }
        if (!ptr) break; /* got to the end without finding a match */
    }

    err = new_mcc_data(uniquename, &d);

    k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
    if (err) {
        free(lid);
        return err;
    }
    lid->data = d;
    *id = lid;
    krb5_change_cache ();
    return KRB5_OK;
}
Esempio n. 6
0
krb5_error_code KRB5_CALLCONV
krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
{
    krb5_ccache lid;
    char uniquename[8];
    krb5_error_code err;
    krb5_mcc_data *d;

    /* Allocate memory */
    lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
    if (lid == NULL)
        return KRB5_CC_NOMEM;

    lid->ops = &krb5_mcc_ops;

    k5_cc_mutex_lock(context, &krb5int_mcc_mutex);
    init_table(context);

    /* Check for uniqueness with mutex locked to avoid race conditions */
    while (1) {
        err = krb5int_random_string (context, uniquename, sizeof (uniquename));
        if (err) {
            k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
            free(lid);
            return err;
        }

        if (k5_hashtab_get(mcc_hashtab, uniquename,
                           strlen(uniquename)) == NULL)
            break;
    }

    err = new_mcc_data(uniquename, &d);

    k5_cc_mutex_unlock(context, &krb5int_mcc_mutex);
    if (err) {
        free(lid);
        return err;
    }
    lid->data = d;
    *id = lid;
    krb5_change_cache ();
    return KRB5_OK;
}
Esempio n. 7
0
/*
 * Modifies:
 * id
 *
 * Effects:
 * Creates/refreshes the memory cred cache id.  If the cache exists, its
 * contents are destroyed.
 *
 * Errors:
 * system errors
 */
krb5_error_code KRB5_CALLCONV
krb5_mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal princ)
{
    krb5_error_code ret;
    krb5_mcc_data *d;

    d = (krb5_mcc_data *)id->data;
    ret = k5_cc_mutex_lock(context, &d->lock);
    if (ret)
        return ret;

    krb5_mcc_free(context, id);

    d = (krb5_mcc_data *)id->data;
    ret = krb5_copy_principal(context, princ,
                              &d->prin);
    update_mcc_change_time(d);

    k5_cc_mutex_unlock(context, &d->lock);
    if (ret == KRB5_OK)
        krb5_change_cache();
    return ret;
}
Esempio n. 8
0
/* Destroy the cache file and release the handle. */
static krb5_error_code KRB5_CALLCONV
fcc_destroy(krb5_context context, krb5_ccache id)
{
    krb5_error_code ret = 0;
    fcc_data *data = id->data;
    int st, fd;
    struct stat buf;
    unsigned long i, size;
    unsigned int wlen;
    char zeros[BUFSIZ];

    k5_cc_mutex_lock(context, &data->lock);

    if (OPENCLOSE(id)) {
        invalidate_cache(data);
        fd = THREEPARAMOPEN(data->filename, O_RDWR | O_BINARY, 0);
        if (fd < 0) {
            ret = interpret_errno(context, errno);
            goto cleanup;
        }
        set_cloexec_fd(fd);
        data->fd = fd;
    } else {
        fcc_lseek(data, 0, SEEK_SET);
    }

#ifdef MSDOS_FILESYSTEM
    /*
     * "Disgusting bit of UNIX trivia" - that's how the writers of NFS describe
     * the ability of UNIX to still write to a file which has been unlinked.
     * Naturally, the PC can't do this.  As a result, we have to delete the
     * file after we wipe it clean, but that throws off all the error handling
     * code.  So we have do the work ourselves.
     */
    st = fstat(data->fd, &buf);
    if (st == -1) {
        ret = interpret_errno(context, errno);
        size = 0;               /* Nothing to wipe clean */
    } else {
        size = (unsigned long)buf.st_size;
    }

    memset(zeros, 0, BUFSIZ);
    while (size > 0) {
        wlen = (int)((size > BUFSIZ) ? BUFSIZ : size); /* How much to write */
        i = write(data->fd, zeros, wlen);
        if (i < 0) {
            ret = interpret_errno(context, errno);
            /* Don't jump to cleanup--we still want to delete the file. */
            break;
        }
        size -= i;
    }

    if (OPENCLOSE(id)) {
        (void)close(((fcc_data *)id->data)->fd);
        data->fd = -1;
    }

    st = unlink(data->filename);
    if (st < 0) {
        ret = interpret_errno(context, errno);
        goto cleanup;
    }

#else /* MSDOS_FILESYSTEM */

    st = unlink(data->filename);
    if (st < 0) {
        ret = interpret_errno(context, errno);
        if (OPENCLOSE(id)) {
            (void)close(data->fd);
            data->fd = -1;
        }
        goto cleanup;
    }

    st = fstat(data->fd, &buf);
    if (st < 0) {
        ret = interpret_errno(context, errno);
        if (OPENCLOSE(id)) {
            (void)close(data->fd);
            data->fd = -1;
        }
        goto cleanup;
    }

    /* XXX This may not be legal XXX */
    size = (unsigned long)buf.st_size;
    memset(zeros, 0, BUFSIZ);
    for (i = 0; i < size / BUFSIZ; i++) {
        if (write(data->fd, zeros, BUFSIZ) < 0) {
            ret = interpret_errno(context, errno);
            if (OPENCLOSE(id)) {
                (void)close(data->fd);
                data->fd = -1;
            }
            goto cleanup;
        }
    }

    wlen = size % BUFSIZ;
    if (write(data->fd, zeros, wlen) < 0) {
        ret = interpret_errno(context, errno);
        if (OPENCLOSE(id)) {
            (void)close(data->fd);
            data->fd = -1;
        }
        goto cleanup;
    }

    st = close(data->fd);
    data->fd = -1;

    if (st)
        ret = interpret_errno(context, errno);

#endif /* MSDOS_FILESYSTEM */

cleanup:
    k5_cc_mutex_unlock(context, &data->lock);
    dereference(context, data);
    free(id);

    krb5_change_cache();
    return ret;
}