Example #1
0
krb5_error_code
krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn)
{
    krb5_int16 rc_vno = htons(KRB5_RC_VNO);
    krb5_error_code retval = 0;
    int flags, do_not_unlink = 0;
    char *dir;
    size_t dirlen;

    GETDIR;
    if (fn && *fn) {
        if (asprintf(&d->fn, "%s%s%s", dir, PATH_SEPARATOR, *fn) < 0)
            return KRB5_RC_IO_MALLOC;
        d->fd = -1;
        do {
            if (unlink(d->fn) == -1 && errno != ENOENT)
                break;
            flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY;
            d->fd = THREEPARAMOPEN(d->fn, flags, 0600);
        } while (d->fd == -1 && errno == EEXIST);
    } else {
        retval = krb5_rc_io_mkstemp(context, d, dir);
        if (retval)
            goto cleanup;
        if (d->fd != -1 && fn) {
            *fn = strdup(d->fn + dirlen);
            if (*fn == NULL) {
                free(d->fn);
                return KRB5_RC_IO_MALLOC;
            }
        }
    }
    if (d->fd == -1) {
        retval = rc_map_errno(context, errno, d->fn, "create");
        if (retval == KRB5_RC_IO_PERM)
            do_not_unlink = 1;
        goto cleanup;
    }
    set_cloexec_fd(d->fd);
    retval = krb5_rc_io_write(context, d, (krb5_pointer)&rc_vno,
                              sizeof(rc_vno));
    if (retval)
        goto cleanup;

    retval = krb5_rc_io_sync(context, d);

cleanup:
    if (retval) {
        if (d->fn) {
            if (!do_not_unlink)
                (void) unlink(d->fn);
            free(d->fn);
            d->fn = NULL;
        }
        if (d->fd != -1) {
            (void) close(d->fd);
        }
    }
    return retval;
}
Example #2
0
static krb5_error_code
krb5_rc_io_store(krb5_context context, struct dfl_data *t,
		 krb5_donot_replay *rep)
{
    unsigned int clientlen, serverlen, len;
    char *buf, *ptr;
    krb5_error_code ret;

    clientlen = strlen(rep->client) + 1;
    serverlen = strlen(rep->server) + 1;
    len = sizeof(clientlen) + clientlen + sizeof(serverlen) + serverlen +
	sizeof(rep->cusec) + sizeof(rep->ctime);
    buf = malloc(len);
    if (buf == 0)
	return KRB5_RC_MALLOC;
    ptr = buf;
    memcpy(ptr, &clientlen, sizeof(clientlen)); ptr += sizeof(clientlen);
    memcpy(ptr, rep->client, clientlen); ptr += clientlen;
    memcpy(ptr, &serverlen, sizeof(serverlen)); ptr += sizeof(serverlen);
    memcpy(ptr, rep->server, serverlen); ptr += serverlen;
    memcpy(ptr, &rep->cusec, sizeof(rep->cusec)); ptr += sizeof(rep->cusec);
    memcpy(ptr, &rep->ctime, sizeof(rep->ctime)); ptr += sizeof(rep->ctime);

    ret = krb5_rc_io_write(context, &t->d, buf, len);
    free(buf);
    return ret;
}
Example #3
0
static krb5_error_code KRB5_CALLCONV
krb5_rc_dfl_init_locked(krb5_context context, krb5_rcache id, krb5_deltat lifespan)
{
    struct dfl_data *t = (struct dfl_data *)id->data;
    krb5_error_code retval;

    t->lifespan = lifespan ? lifespan : context->clockskew;
    /* default to clockskew from the context */
#ifndef NOIOSTUFF
    if ((retval = krb5_rc_io_creat(context, &t->d, &t->name))) {
        return retval;
    }
    if ((krb5_rc_io_write(context, &t->d,
                          (krb5_pointer) &t->lifespan, sizeof(t->lifespan))
         || krb5_rc_io_sync(context, &t->d))) {
        return KRB5_RC_IO;
    }
#endif
    return 0;
}
Example #4
0
static krb5_error_code
krb5_rc_io_store(krb5_context context, struct dfl_data *t,
                 krb5_donot_replay *rep)
{
    size_t clientlen, serverlen;
    unsigned int len;
    krb5_error_code ret;
    struct k5buf buf, extbuf;
    char *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);
        if (k5_buf_status(&extbuf) != 0)
            return KRB5_RC_MALLOC;
        extstr = extbuf.data;

        /*
         * 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));

    if (k5_buf_status(&buf) != 0)
        return KRB5_RC_MALLOC;

    ret = krb5_rc_io_write(context, &t->d, buf.data, buf.len);
    k5_buf_free(&buf);
    return ret;
}