Exemple #1
0
static kadm5_ret_t
kadm5_log_flush (kadm5_log_context *log_context,
		 krb5_storage *sp)
{
    krb5_data data;
    size_t len;
    int ret;

    krb5_storage_to_data(sp, &data);
    len = data.length;
    ret = write (log_context->log_fd, data.data, len);
    if (ret != len) {
	krb5_data_free(&data);
	return errno;
    }
    if (fsync (log_context->log_fd) < 0) {
	krb5_data_free(&data);
	return errno;
    }
    /*
     * Try to send a signal to any running `ipropd-master'
     */
    sendto (log_context->socket_fd,
	    (void *)&log_context->version,
	    sizeof(log_context->version),
	    0,
	    (struct sockaddr *)&log_context->socket_name,
	    sizeof(log_context->socket_name));

    krb5_data_free(&data);
    return 0;
}
Exemple #2
0
krb5_error_code
hdb_entry2string (krb5_context context, hdb_entry *ent, char **str)
{
    krb5_error_code ret;
    krb5_data data;
    krb5_storage *sp;

    sp = krb5_storage_emem();
    if(sp == NULL) {
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
	return ENOMEM;
    }

    ret = entry2string_int(context, sp, ent);
    if(ret) {
	krb5_storage_free(sp);
	return ret;
    }

    krb5_storage_write(sp, "\0", 1);
    krb5_storage_to_data(sp, &data);
    krb5_storage_free(sp);
    *str = data.data;
    return 0;
}
static krb5_error_code
kcm_send_request(krb5_context context,
		 krb5_storage *request,
		 krb5_data *response_data)
{
    static heim_base_once_t init_once = HEIM_BASE_ONCE_INIT;
    krb5_error_code ret = 0;
    krb5_data request_data;

    heim_base_once_f(&init_once, NULL, kcm_init_ipc);

    if (kcm_ipc == NULL) {
	krb5_set_error_message(context, ENOENT, "Failed to open kcm init");
	return ENOENT;
    }

    ret = krb5_storage_to_data(request, &request_data);
    if (ret) {
	krb5_clear_error_message(context);
	return KRB5_CC_NOMEM;
    }

    ret = heim_ipc_call(kcm_ipc, &request_data, response_data, NULL);
    krb5_data_free(&request_data);

    if (ret) {
	krb5_clear_error_message(context);
	ret = KRB5_CC_NOSUPP;
    }

    return ret;
}
Exemple #4
0
static krb5_error_code
kcm_send_request(krb5_context context,
		 krb5_storage *request,
		 krb5_data *response_data)
{
    krb5_error_code ret = 0;
    krb5_data request_data;

    HEIMDAL_MUTEX_lock(&kcm_mutex);
    if (kcm_ipc == NULL)
	ret = heim_ipc_init_context(kcm_ipc_name, &kcm_ipc);
    HEIMDAL_MUTEX_unlock(&kcm_mutex);
    if (ret)
	return KRB5_CC_NOSUPP;

    ret = krb5_storage_to_data(request, &request_data);
    if (ret) {
	krb5_clear_error_message(context);
	return KRB5_CC_NOMEM;
    }

    ret = heim_ipc_call(kcm_ipc, &request_data, response_data, NULL);
    krb5_data_free(&request_data);

    if (ret) {
	krb5_clear_error_message(context);
	ret = KRB5_CC_NOSUPP;
    }

    return ret;
}
Exemple #5
0
static int
make_result (krb5_data *data,
             uint16_t result_code,
             const char *expl)
{
    krb5_error_code ret;
    krb5_storage *sp;

    sp = krb5_storage_emem();
    if (sp == NULL) goto out;
    ret = krb5_store_uint16(sp, result_code);
    if (ret) goto out;
    ret = krb5_store_stringz(sp, expl);
    if (ret) goto out;
    ret = krb5_storage_to_data(sp, data);
    if (ret) goto out;
    krb5_storage_free(sp);

    return 0;
out:
    if (sp)
        krb5_storage_free(sp);

    krb5_warnx (context, "Out of memory generating error reply");
    return 1;
}
Exemple #6
0
static krb5_error_code
encode_creds(krb5_context context, krb5_creds *creds, krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(data);
    sp = krb5_storage_emem();
    if (sp == NULL)
	return krb5_enomem(context);

    ret = krb5_store_creds(sp, creds);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to store credential in scache", ""));
	krb5_storage_free(sp);
	return ret;
    }

    ret = krb5_storage_to_data(sp, data);
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_message(context, ret,
			       N_("Failed to encode credential in scache", ""));
    return ret;
}
Exemple #7
0
static krb5_error_code
encode_creds(krb5_context context, krb5_creds *creds, krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_set_error_message(context, ENOMEM,
			       N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    ret = krb5_store_creds(sp, creds);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to store credential in scache", ""));
	krb5_storage_free(sp);
	return ret;
    }

    ret = krb5_storage_to_data(sp, data);
    krb5_storage_free(sp);
    if (ret)
	krb5_set_error_message(context, ret,
			       N_("Failed to encode credential in scache", ""));
    return ret;
}
static OM_uint32
get_service_keyblock
        (OM_uint32 *minor_status,
	 gsskrb5_ctx ctx,
	 gss_buffer_set_t *data_set)
{
    krb5_storage *sp = NULL;
    krb5_data data;
    OM_uint32 maj_stat = GSS_S_COMPLETE;
    krb5_error_code ret = EINVAL;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	_gsskrb5_clear_status();
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
    if (ctx->service_keyblock == NULL) {
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	_gsskrb5_set_status(EINVAL, "No service keyblock on gssapi context");
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    krb5_data_zero(&data);

    ret = krb5_store_keyblock(sp, *ctx->service_keyblock);

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    if (ret)
	goto out;

    ret = krb5_storage_to_data(sp, &data);
    if (ret)
	goto out;

    {
	gss_buffer_desc value;
	
	value.length = data.length;
	value.value = data.data;
	
	maj_stat = gss_add_buffer_set_member(minor_status,
					     &value,
					     data_set);
    }

out:
    krb5_data_free(&data);
    if (sp)
	krb5_storage_free(sp);
    if (ret) {
	*minor_status = ret;
	maj_stat = GSS_S_FAILURE;
    }
    return maj_stat;
}
Exemple #9
0
krb5_error_code
kcm_dispatch(krb5_context context,
	     kcm_client *client,
	     krb5_data *req_data,
	     krb5_data *resp_data)
{
    krb5_error_code ret;
    kcm_method method;
    krb5_storage *req_sp = NULL;
    krb5_storage *resp_sp = NULL;
    u_int16_t opcode;

    resp_sp = krb5_storage_emem();
    if (resp_sp == NULL) {
	return ENOMEM;
    }

    if (client->pid == -1) {
	kcm_log(0, "Client had invalid process number");
	ret = KRB5_FCC_INTERNAL;
	goto out;
    }

    req_sp = krb5_storage_from_data(req_data);
    if (req_sp == NULL) {
	kcm_log(0, "Process %d: failed to initialize storage from data",
		client->pid);
	ret = KRB5_CC_IO;
	goto out;
    }

    krb5_ret_int16(req_sp, &opcode);

    if (opcode >= sizeof(kcm_ops)/sizeof(kcm_ops[0])) {
	kcm_log(0, "Process %d: invalid operation code %d",
		client->pid, opcode);
	ret = KRB5_FCC_INTERNAL;
	goto out;
    }
    method = kcm_ops[opcode].method;

    /* seek past place for status code */
    krb5_storage_seek(resp_sp, 4, SEEK_SET);

    ret = (*method)(context, client, opcode, req_sp, resp_sp);

out:
    if (req_sp != NULL) {
	krb5_storage_free(req_sp);
    }

    krb5_storage_seek(resp_sp, 0, SEEK_SET);
    krb5_store_int32(resp_sp, ret);

    ret = krb5_storage_to_data(resp_sp, resp_data);
    krb5_storage_free(resp_sp);

    return ret;
}
Exemple #10
0
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;
}
Exemple #11
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_s4u2self_to_checksumdata(krb5_context context,
			       const PA_S4U2Self *self,
			       krb5_data *data)
{
    krb5_error_code ret;
    krb5_ssize_t ssize;
    krb5_storage *sp;
    size_t size;
    size_t i;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	krb5_clear_error_message(context);
	return ENOMEM;
    }
    krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);
    ret = krb5_store_int32(sp, self->name.name_type);
    if (ret)
	goto out;
    for (i = 0; i < self->name.name_string.len; i++) {
	size = strlen(self->name.name_string.val[i]);
	ssize = krb5_storage_write(sp, self->name.name_string.val[i], size);
	if (ssize != (krb5_ssize_t)size) {
	    ret = ENOMEM;
	    goto out;
	}
    }
    size = strlen(self->realm);
    ssize = krb5_storage_write(sp, self->realm, size);
    if (ssize != (krb5_ssize_t)size) {
	ret = ENOMEM;
	goto out;
    }
    size = strlen(self->auth);
    ssize = krb5_storage_write(sp, self->auth, size);
    if (ssize != (krb5_ssize_t)size) {
	ret = ENOMEM;
	goto out;
    }

    ret = krb5_storage_to_data(sp, data);
    krb5_storage_free(sp);
    return ret;

out:
    krb5_clear_error_message(context);
    return ret;
}
Exemple #12
0
OM_uint32
gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, 
				gss_cred_id_t cred,
				OM_uint32 num_enctypes,
				int32_t *enctypes)
{
    krb5_error_code ret;
    OM_uint32 maj_status;
    gss_buffer_desc buffer;
    krb5_storage *sp;
    krb5_data data;
    int i;

    sp = krb5_storage_emem();
    if (sp == NULL) {
	*minor_status = ENOMEM;
	maj_status = GSS_S_FAILURE;
	goto out;
    }

    for (i = 0; i < num_enctypes; i++) {
	ret = krb5_store_int32(sp, enctypes[i]);
	if (ret) {
	    *minor_status = ret;
	    maj_status = GSS_S_FAILURE;
	    goto out;
	}
    }

    ret = krb5_storage_to_data(sp, &data);
    if (ret) {
	*minor_status = ret;
	maj_status = GSS_S_FAILURE;
	goto out;
    }

    buffer.value = data.data;
    buffer.length = data.length;

    maj_status = gss_set_cred_option(minor_status,
				     &cred,
				     GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X,
				     &buffer);
    krb5_data_free(&data);
out:
    if (sp)
	krb5_storage_free(sp);
    return maj_status;
}
Exemple #13
0
kadm5_ret_t
_kadm5_marshal_params(krb5_context context,
		      kadm5_config_params *params,
		      krb5_data *out)
{
    krb5_storage *sp = krb5_storage_emem();

    krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM));
	
    if(params->mask & KADM5_CONFIG_REALM)
	krb5_store_string(sp, params->realm);
    krb5_storage_to_data(sp, out);
    krb5_storage_free(sp);

    return 0;
}
Exemple #14
0
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;
}
Exemple #15
0
static int
compare(const char *name, krb5_storage *sp, void *expected, size_t len)
{
    int ret = 0;
    krb5_data data;
    if (krb5_storage_to_data(sp, &data))
	errx(1, "krb5_storage_to_data failed");
    krb5_storage_free(sp);
    if(data.length != len || memcmp(data.data, expected, len) != 0) {
	printf("%s mismatch\n", name);
	printf("  Expected: ");
	print_data(expected, len);
	printf("  Actual:   ");
	print_data(data.data, data.length);
	ret++;
    }
    krb5_data_free(&data);
    return ret;
}
Exemple #16
0
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;
}
Exemple #17
0
static kadm5_ret_t
kadm5_log_flush (kadm5_log_context *log_context,
		 krb5_storage *sp)
{
    krb5_data data;
    size_t len;
    ssize_t ret;

    krb5_storage_to_data(sp, &data);
    len = data.length;
    ret = write (log_context->log_fd, data.data, len);
    if (ret < 0 || (size_t)ret != len) {
	krb5_data_free(&data);
	return errno;
    }
    if (fsync (log_context->log_fd) < 0) {
	krb5_data_free(&data);
	return errno;
    }

    /*
     * Try to send a signal to any running `ipropd-master'
     */
#ifndef NO_UNIX_SOCKETS
    sendto (log_context->socket_fd,
	    (void *)&log_context->version,
	    sizeof(log_context->version),
	    0,
	    (struct sockaddr *)&log_context->socket_name,
	    sizeof(log_context->socket_name));
#else
    sendto (log_context->socket_fd,
	    (void *)&log_context->version,
	    sizeof(log_context->version),
	    0,
	    log_context->socket_info->ai_addr,
	    log_context->socket_info->ai_addrlen);
#endif

    krb5_data_free(&data);
    return 0;
}
Exemple #18
0
/*
 * Create an error `reply´ using for the packet `hdr' with the error
 * `error´ code.
 */
static void
make_error_reply (struct rx_header *hdr,
		  uint32_t error,
		  krb5_data *reply)

{
    struct rx_header reply_hdr;
    krb5_error_code ret;
    krb5_storage *sp;

    init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST);
    sp = krb5_storage_emem();
    if (sp == NULL)
	return;
    ret = encode_rx_header (&reply_hdr, sp);
    if (ret)
	return;
    krb5_store_int32(sp, error);
    krb5_storage_to_data (sp, reply);
    krb5_storage_free (sp);
}
Exemple #19
0
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);
}
Exemple #20
0
static krb5_error_code
storage_to_etext(krb5_context context,
		 krb5_storage *sp,
		 const krb5_keyblock *key, 
		 krb5_data *enc_data)
{
    krb5_error_code ret;
    krb5_crypto crypto;
    krb5_ssize_t size;
    krb5_data data;

    /* multiple of eight bytes */

    size = krb5_storage_seek(sp, 0, SEEK_END);
    if (size < 0)
	return EINVAL;
    size = 8 - (size & 7);

    ret = krb5_storage_write(sp, eightzeros, size);
    if (ret != size)
	return EINVAL;

    ret = krb5_storage_to_data(sp, &data);
    if (ret)
	return ret;

    ret = krb5_crypto_init(context, key, ETYPE_DES_PCBC_NONE, &crypto);
    if (ret) {
	krb5_data_free(&data);
	return ret;
    }

    ret = krb5_encrypt(context, crypto, 0, data.data, data.length, enc_data);

    krb5_data_free(&data);
    krb5_crypto_destroy(context, crypto);

    return ret;
}
Exemple #21
0
krb5_error_code
_kadm5_xdr_store_gcred(struct _kadm5_xdr_gcred *gcred, krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp;

    krb5_data_zero(data);

    sp = krb5_storage_emem();
    INSIST(sp != NULL);

    CHECK(krb5_store_uint32(sp, gcred->version));
    CHECK(krb5_store_uint32(sp, gcred->proc));
    CHECK(krb5_store_uint32(sp, gcred->seq_num));
    CHECK(krb5_store_uint32(sp, gcred->service));
    CHECK(_kadm5_xdr_store_data_xdr(sp, gcred->handle));

    ret = krb5_storage_to_data(sp, data);
    krb5_storage_free(sp);

    return ret;
}
Exemple #22
0
static krb5_error_code
kcm_send_request(krb5_context context,
		 krb5_kcmcache *k,
		 krb5_storage *request,
		 krb5_data *response_data)
{
    krb5_error_code ret;
    krb5_data request_data;
    int i;

    response_data->data = NULL;
    response_data->length = 0;

    ret = krb5_storage_to_data(request, &request_data);
    if (ret) {
	krb5_clear_error_string(context);
	return KRB5_CC_NOMEM;
    }

    ret = KRB5_CC_IO;

    for (i = 0; i < context->max_retries; i++) {
	ret = try_door(context, k, &request_data, response_data);
	if (ret == 0 && response_data->length != 0)
	    break;
	ret = try_unix_socket(context, k, &request_data, response_data);
	if (ret == 0 && response_data->length != 0)
	    break;
    }

    krb5_data_free(&request_data);

    if (ret) {
	krb5_clear_error_string(context);
	ret = KRB5_CC_IO;
    }

    return ret;
}
Exemple #23
0
static krb5_error_code
write_storage(krb5_context context, krb5_storage *sp, int fd)
{
    krb5_error_code ret;
    krb5_data data;
    ssize_t sret;

    ret = krb5_storage_to_data(sp, &data);
    if (ret) {
	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
	return ret;
    }
    sret = write(fd, data.data, data.length);
    ret = (sret != data.length);
    krb5_data_free(&data);
    if (ret) {
	ret = errno;
	krb5_set_error_message(context, ret,
			       N_("Failed to write FILE credential data", ""));
	return ret;
    }
    return 0;
}
Exemple #24
0
krb5_error_code
_kdc_do_524(krb5_context context,
	    krb5_kdc_configuration *config,
	    const Ticket *t, krb5_data *reply,
	    const char *from, struct sockaddr *addr)
{
    krb5_error_code ret = 0;
    krb5_crypto crypto;
    hdb_entry_ex *server = NULL;
    Key *skey;
    krb5_data et_data;
    EncTicketPart et;
    EncryptedData ticket;
    krb5_storage *sp;
    char *spn = NULL;
    unsigned char buf[MAX_KTXT_LEN + 4 * 4];
    size_t len;
    int kvno = 0;

    if(!config->enable_524) {
	ret = KRB5KDC_ERR_POLICY;
	kdc_log(context, config, 0,
		"Rejected ticket conversion request from %s", from);
	goto out;
    }

    ret = fetch_server (context, config, t, &spn, &server, from);
    if (ret) {
	goto out;
    }

    ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey);
    if(ret){
	kdc_log(context, config, 0,
		"No suitable key found for server (%s) from %s", spn, from);
	goto out;
    }
    ret = krb5_crypto_init(context, &skey->key, 0, &crypto);
    if (ret) {
	kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
		krb5_get_err_text(context, ret));
	goto out;
    }
    ret = krb5_decrypt_EncryptedData (context,
				      crypto,
				      KRB5_KU_TICKET,
				      &t->enc_part,
				      &et_data);
    krb5_crypto_destroy(context, crypto);
    if(ret){
	kdc_log(context, config, 0,
		"Failed to decrypt ticket from %s for %s", from, spn);
	goto out;
    }
    ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
				    &et, &len);
    krb5_data_free(&et_data);
    if(ret){
	kdc_log(context, config, 0,
		"Failed to decode ticket from %s for %s", from, spn);
	goto out;
    }

    ret = log_524 (context, config, &et, from, spn);
    if (ret) {
	free_EncTicketPart(&et);
	goto out;
    }

    ret = verify_flags (context, config, &et, spn);
    if (ret) {
	free_EncTicketPart(&et);
	goto out;
    }

    ret = set_address (context, config, &et, addr, from);
    if (ret) {
	free_EncTicketPart(&et);
	goto out;
    }

    ret = encode_524_response(context, config, spn, et, t,
			      server, &ticket, &kvno);
    free_EncTicketPart(&et);

 out:
    /* make reply */
    memset(buf, 0, sizeof(buf));
    sp = krb5_storage_from_mem(buf, sizeof(buf));
    if (sp) {
	krb5_store_int32(sp, ret);
	if(ret == 0){
	    krb5_store_int32(sp, kvno);
	    krb5_store_data(sp, ticket.cipher);
	    /* Aargh! This is coded as a KTEXT_ST. */
	    krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
	    krb5_store_int32(sp, 0); /* mbz */
	    free_EncryptedData(&ticket);
	}
	ret = krb5_storage_to_data(sp, reply);
	reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
	krb5_storage_free(sp);
    } else
	krb5_data_zero(reply);
    if(spn)
	free(spn);
    if(server)
	_kdc_free_ent (context, server);
    return ret;
}
Exemple #25
0
static krb5_error_code
create_reply_ticket (krb5_context context,
		     struct rx_header *hdr,
		     Key *skey,
		     char *name, char *instance, char *realm,
		     struct sockaddr_in *addr,
		     int life,
		     int kvno,
		     int32_t max_seq_len,
		     const char *sname, const char *sinstance,
		     uint32_t challenge,
		     const char *label,
		     krb5_keyblock *key,
		     krb5_data *reply)
{
    krb5_error_code ret;
    krb5_data ticket;
    krb5_keyblock session;
    krb5_storage *sp;
    krb5_data enc_data;
    struct rx_header reply_hdr;
    char zero[8];
    size_t pad;
    unsigned fyrtiosjuelva;

    /* create the ticket */

    krb5_generate_random_keyblock(context, ETYPE_DES_PCBC_NONE, &session);

    _krb5_krb_create_ticket(context,
			    0,
			    name,
			    instance,
			    realm,
			    addr->sin_addr.s_addr,
			    &session,
			    life,
			    kdc_time,
			    sname,
			    sinstance,
			    &skey->key,
			    &ticket);

    /* create the encrypted part of the reply */
    sp = krb5_storage_emem ();
    krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva));
    fyrtiosjuelva &= 0xffffffff;
    krb5_store_int32 (sp, fyrtiosjuelva);
    krb5_store_int32 (sp, challenge);
    krb5_storage_write  (sp, session.keyvalue.data, 8);
    krb5_free_keyblock_contents(context, &session);
    krb5_store_int32 (sp, kdc_time);
    krb5_store_int32 (sp, kdc_time + _krb5_krb_life_to_time (0, life));
    krb5_store_int32 (sp, kvno);
    krb5_store_int32 (sp, ticket.length);
    krb5_store_stringz (sp, name);
    krb5_store_stringz (sp, instance);
#if 1 /* XXX - Why shouldn't the realm go here? */
    krb5_store_stringz (sp, "");
#else
    krb5_store_stringz (sp, realm);
#endif
    krb5_store_stringz (sp, sname);
    krb5_store_stringz (sp, sinstance);
    krb5_storage_write (sp, ticket.data, ticket.length);
    krb5_storage_write (sp, label, strlen(label));

    /* pad to DES block */
    memset (zero, 0, sizeof(zero));
    pad = (8 - krb5_storage_seek (sp, 0, SEEK_CUR) % 8) % 8;
    krb5_storage_write (sp, zero, pad);

    krb5_storage_to_data (sp, &enc_data);
    krb5_storage_free (sp);

    if (enc_data.length > max_seq_len) {
	krb5_data_free (&enc_data);
	make_error_reply (hdr, KAANSWERTOOLONG, reply);
	return 0;
    }

    /* encrypt it */
    {
        DES_key_schedule schedule;
	DES_cblock deskey;
	
	memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
	DES_set_key_unchecked (&deskey, &schedule);
	DES_pcbc_encrypt (enc_data.data,
			  enc_data.data,
			  enc_data.length,
			  &schedule,
			  &deskey,
			  DES_ENCRYPT);
	memset (&schedule, 0, sizeof(schedule));
	memset (&deskey, 0, sizeof(deskey));
    }

    /* create the reply packet */
    init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST);
    sp = krb5_storage_emem ();
    ret = encode_rx_header (&reply_hdr, sp);
    krb5_store_int32 (sp, max_seq_len);
    krb5_store_xdr_data (sp, enc_data);
    krb5_data_free (&enc_data);
    krb5_storage_to_data (sp, reply);
    krb5_storage_free (sp);
    return 0;
}
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_sec_context (
    OM_uint32 * minor_status,
    gss_ctx_id_t * context_handle,
    gss_buffer_t interprocess_token
)
{
    krb5_context context;
    const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
    krb5_storage *sp;
    krb5_auth_context ac;
    OM_uint32 ret = GSS_S_COMPLETE;
    krb5_data data;
    gss_buffer_desc buffer;
    int flags;
    OM_uint32 minor;
    krb5_error_code kret;

    GSSAPI_KRB5_INIT (&context);

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = 0;
        return GSS_S_UNAVAILABLE;
    }

    sp = krb5_storage_emem ();
    if (sp == NULL) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }
    ac = ctx->auth_context;

    /* flagging included fields */

    flags = 0;
    if (ac->local_address)
        flags |= SC_LOCAL_ADDRESS;
    if (ac->remote_address)
        flags |= SC_REMOTE_ADDRESS;
    if (ac->keyblock)
        flags |= SC_KEYBLOCK;
    if (ac->local_subkey)
        flags |= SC_LOCAL_SUBKEY;
    if (ac->remote_subkey)
        flags |= SC_REMOTE_SUBKEY;

    kret = krb5_store_int32 (sp, flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    /* marshall auth context */

    kret = krb5_store_int32 (sp, ac->flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    if (ac->local_address) {
        kret = krb5_store_address (sp, *ac->local_address);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->remote_address) {
        kret = krb5_store_address (sp, *ac->remote_address);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    kret = krb5_store_int16 (sp, ac->local_port);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int16 (sp, ac->remote_port);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    if (ac->keyblock) {
        kret = krb5_store_keyblock (sp, *ac->keyblock);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->local_subkey) {
        kret = krb5_store_keyblock (sp, *ac->local_subkey);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->remote_subkey) {
        kret = krb5_store_keyblock (sp, *ac->remote_subkey);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    kret = krb5_store_int32 (sp, ac->local_seqnumber);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ac->remote_seqnumber);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_store_int32 (sp, ac->keytype);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ac->cksumtype);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    /* names */

    ret = _gsskrb5_export_name (minor_status,
                                (gss_name_t)ctx->source, &buffer);
    if (ret)
        goto failure;
    data.data   = buffer.value;
    data.length = buffer.length;
    kret = krb5_store_data (sp, data);
    _gsskrb5_release_buffer (&minor, &buffer);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    ret = _gsskrb5_export_name (minor_status,
                                (gss_name_t)ctx->target, &buffer);
    if (ret)
        goto failure;
    data.data   = buffer.value;
    data.length = buffer.length;

    ret = GSS_S_FAILURE;

    kret = krb5_store_data (sp, data);
    _gsskrb5_release_buffer (&minor, &buffer);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_store_int32 (sp, ctx->flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ctx->more_flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ctx->lifetime);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = _gssapi_msg_order_export(sp, ctx->order);
    if (kret ) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_storage_to_data (sp, &data);
    krb5_storage_free (sp);
    if (kret) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = kret;
        return GSS_S_FAILURE;
    }
    interprocess_token->length = data.length;
    interprocess_token->value  = data.data;
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
                                       GSS_C_NO_BUFFER);
    if (ret != GSS_S_COMPLETE)
        _gsskrb5_release_buffer (NULL, interprocess_token);
    *minor_status = 0;
    return ret;
failure:
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    krb5_storage_free (sp);
    return ret;
}
Exemple #27
0
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;
}
Exemple #28
0
krb5_error_code
_krb5_pac_sign(krb5_context context,
	       krb5_pac p,
	       time_t authtime,
	       krb5_principal principal,
	       const krb5_keyblock *server_key,
	       const krb5_keyblock *priv_key,
	       krb5_data *data)
{
    krb5_error_code ret;
    krb5_storage *sp = NULL, *spdata = NULL;
    uint32_t end;
    size_t server_size, priv_size;
    uint32_t server_offset = 0, priv_offset = 0;
    uint32_t server_cksumtype = 0, priv_cksumtype = 0;
    int i, num = 0;
    krb5_data logon, d;

    krb5_data_zero(&logon);

    if (p->logon_name == NULL)
	num++;
    if (p->server_checksum == NULL)
	num++;
    if (p->privsvr_checksum == NULL)
	num++;

    if (num) {
	void *ptr;

	ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1)));
	if (ptr == NULL)
	    return krb5_enomem(context);

	p->pac = ptr;

	if (p->logon_name == NULL) {
	    p->logon_name = &p->pac->buffers[p->pac->numbuffers++];
	    memset(p->logon_name, 0, sizeof(*p->logon_name));
	    p->logon_name->type = PAC_LOGON_NAME;
	}
	if (p->server_checksum == NULL) {
	    p->server_checksum = &p->pac->buffers[p->pac->numbuffers++];
	    memset(p->server_checksum, 0, sizeof(*p->server_checksum));
	    p->server_checksum->type = PAC_SERVER_CHECKSUM;
	}
	if (p->privsvr_checksum == NULL) {
	    p->privsvr_checksum = &p->pac->buffers[p->pac->numbuffers++];
	    memset(p->privsvr_checksum, 0, sizeof(*p->privsvr_checksum));
	    p->privsvr_checksum->type = PAC_PRIVSVR_CHECKSUM;
	}
    }

    /* Calculate LOGON NAME */
    ret = build_logon_name(context, authtime, principal, &logon);
    if (ret)
	goto out;

    /* Set lengths for checksum */
    ret = pac_checksum(context, server_key, &server_cksumtype, &server_size);
    if (ret)
	goto out;
    ret = pac_checksum(context, priv_key, &priv_cksumtype, &priv_size);
    if (ret)
	goto out;

    /* Encode PAC */
    sp = krb5_storage_emem();
    if (sp == NULL)
	return krb5_enomem(context);

    krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);

    spdata = krb5_storage_emem();
    if (spdata == NULL) {
	krb5_storage_free(sp);
	return krb5_enomem(context);
    }
    krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE);

    CHECK(ret, krb5_store_uint32(sp, p->pac->numbuffers), out);
    CHECK(ret, krb5_store_uint32(sp, p->pac->version), out);

    end = PACTYPE_SIZE + (PAC_INFO_BUFFER_SIZE * p->pac->numbuffers);

    for (i = 0; i < p->pac->numbuffers; i++) {
	uint32_t len;
	size_t sret;
	void *ptr = NULL;

	/* store data */

	if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) {
	    len = server_size + 4;
	    server_offset = end + 4;
	    CHECK(ret, krb5_store_uint32(spdata, server_cksumtype), out);
	    CHECK(ret, fill_zeros(context, spdata, server_size), out);
	} else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) {
	    len = priv_size + 4;
	    priv_offset = end + 4;
	    CHECK(ret, krb5_store_uint32(spdata, priv_cksumtype), out);
	    CHECK(ret, fill_zeros(context, spdata, priv_size), out);
	} else if (p->pac->buffers[i].type == PAC_LOGON_NAME) {
	    len = krb5_storage_write(spdata, logon.data, logon.length);
	    if (logon.length != len) {
		ret = EINVAL;
		goto out;
	    }
	} else {
	    len = p->pac->buffers[i].buffersize;
	    ptr = (char *)p->data.data + p->pac->buffers[i].offset_lo;

	    sret = krb5_storage_write(spdata, ptr, len);
	    if (sret != len) {
		ret = krb5_enomem(context);
		goto out;
	    }
	    /* XXX if not aligned, fill_zeros */
	}

	/* write header */
	CHECK(ret, krb5_store_uint32(sp, p->pac->buffers[i].type), out);
	CHECK(ret, krb5_store_uint32(sp, len), out);
	CHECK(ret, krb5_store_uint32(sp, end), out);
	CHECK(ret, krb5_store_uint32(sp, 0), out);

	/* advance data endpointer and align */
	{
	    int32_t e;

	    end += len;
	    e = ((end + PAC_ALIGNMENT - 1) / PAC_ALIGNMENT) * PAC_ALIGNMENT;
	    if (end != e) {
		CHECK(ret, fill_zeros(context, spdata, e - end), out);
	    }
	    end = e;
	}

    }

    /* assert (server_offset != 0 && priv_offset != 0); */

    /* export PAC */
    ret = krb5_storage_to_data(spdata, &d);
    if (ret) {
	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
	goto out;
    }
    ret = krb5_storage_write(sp, d.data, d.length);
    if (ret != d.length) {
	krb5_data_free(&d);
	ret = krb5_enomem(context);
	goto out;
    }
    krb5_data_free(&d);

    ret = krb5_storage_to_data(sp, &d);
    if (ret) {
	ret = krb5_enomem(context);
	goto out;
    }

    /* sign */
    ret = create_checksum(context, server_key, server_cksumtype,
			  d.data, d.length,
			  (char *)d.data + server_offset, server_size);
    if (ret) {
	krb5_data_free(&d);
	goto out;
    }
    ret = create_checksum(context, priv_key, priv_cksumtype,
			  (char *)d.data + server_offset, server_size,
			  (char *)d.data + priv_offset, priv_size);
    if (ret) {
	krb5_data_free(&d);
	goto out;
    }

    /* done */
    *data = d;

    krb5_data_free(&logon);
    krb5_storage_free(sp);
    krb5_storage_free(spdata);

    return 0;
out:
    krb5_data_free(&logon);
    if (sp)
	krb5_storage_free(sp);
    if (spdata)
	krb5_storage_free(spdata);
    return ret;
}
Exemple #29
0
static krb5_error_code
build_logon_name(krb5_context context,
		 time_t authtime,
		 krb5_const_principal principal,
		 krb5_data *logon)
{
    krb5_error_code ret;
    krb5_storage *sp;
    uint64_t t;
    char *s, *s2;
    size_t i, len;

    t = unix2nttime(authtime);

    krb5_data_zero(logon);

    sp = krb5_storage_emem();
    if (sp == NULL)
	return krb5_enomem(context);

    krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE);

    CHECK(ret, krb5_store_uint32(sp, t & 0xffffffff), out);
    CHECK(ret, krb5_store_uint32(sp, t >> 32), out);

    ret = krb5_unparse_name_flags(context, principal,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &s);
    if (ret)
	goto out;

    len = strlen(s);

    CHECK(ret, krb5_store_uint16(sp, len * 2), out);

#if 1 /* cheat for now */
    s2 = malloc(len * 2);
    if (s2 == NULL) {
	ret = krb5_enomem(context);
	free(s);
	goto out;
    }
    for (i = 0; i < len; i++) {
	s2[i * 2] = s[i];
	s2[i * 2 + 1] = 0;
    }
    free(s);
#else
    /* write libwind code here */
#endif

    ret = krb5_storage_write(sp, s2, len * 2);
    free(s2);
    if (ret != len * 2) {
	ret = krb5_enomem(context);
	goto out;
    }
    ret = krb5_storage_to_data(sp, logon);
    if (ret)
	goto out;
    krb5_storage_free(sp);

    return 0;
out:
    krb5_storage_free(sp);
    return ret;
}
Exemple #30
0
static krb5_error_code
write_v4_cc(krb5_context context, const char *tkfile, 
	    krb5_storage *sp, int append)
{
    krb5_error_code ret;
    struct stat sb;
    krb5_data data;
    char *path;
    int fd, i;

    ret = get_krb4_cc_name(tkfile, &path);
    if (ret) {
	krb5_set_error_string(context, 
			      "krb5_krb_tf_setup: failed getting "
			      "the krb4 credentials cache name"); 
	return ret;
    }

    fd = open(path, O_WRONLY|O_CREAT, 0600);
    if (fd < 0) {
	ret = errno;
	krb5_set_error_string(context, 
			      "krb5_krb_tf_setup: error opening file %s", 
			      path);
	free(path);
	return ret;
    }

    if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) {
	krb5_set_error_string(context, 
			      "krb5_krb_tf_setup: tktfile %s is not a file",
			      path);
	free(path);
	close(fd);
	return KRB5_FCC_PERM;
    }

    for (i = 0; i < KRB5_TF_LCK_RETRY_COUNT; i++) {
	if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
	    sleep(KRB5_TF_LCK_RETRY);
	} else
	    break;
    }
    if (i == KRB5_TF_LCK_RETRY_COUNT) {
	krb5_set_error_string(context,
			      "krb5_krb_tf_setup: failed to lock %s",
			      path);
	free(path);
	close(fd);
	return KRB5_FCC_PERM;
    }

    if (!append) {
	ret = ftruncate(fd, 0);
	if (ret < 0) {
	    flock(fd, LOCK_UN);
	    krb5_set_error_string(context,
				  "krb5_krb_tf_setup: failed to truncate %s",
				  path);
	    free(path);
	    close(fd);
	    return KRB5_FCC_PERM;
	}
    }
    ret = lseek(fd, 0L, SEEK_END);
    if (ret < 0) {
	ret = errno;
	flock(fd, LOCK_UN);
	free(path);
	close(fd);
	return ret;
    }

    krb5_storage_to_data(sp, &data);

    ret = write(fd, data.data, data.length);
    if (ret != data.length)
	ret = KRB5_CC_IO;

    krb5_free_data_contents(context, &data);

    flock(fd, LOCK_UN);
    free(path);
    close(fd);

    return 0;
}