Beispiel #1
0
static krb5_error_code
mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
{
    struct mcache_iter *iter = cursor;
    krb5_error_code ret;
    krb5_mcache *m;

    if (iter->cache == NULL)
	return KRB5_CC_END;

    HEIMDAL_MUTEX_lock(&mcc_mutex);
    m = iter->cache;
    if (m->next)
	m->next->refcnt++;
    iter->cache = m->next;
    HEIMDAL_MUTEX_unlock(&mcc_mutex);

    ret = _krb5_cc_allocate(context, &krb5_mcc_ops, id);
    if (ret)
	return ret;

    (*id)->data.data = m;
    (*id)->data.length = sizeof(*m);

    return 0;
}
Beispiel #2
0
static krb5_error_code
mcc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
    krb5_mcache *m;

    HEIMDAL_MUTEX_lock(&mcc_mutex);
    for (m = mcc_head; m != NULL; m = m->next)
	if (strcmp(m->name, res) == 0)
	    break;
    HEIMDAL_MUTEX_unlock(&mcc_mutex);

    if (m != NULL) {
	m->refcnt++;
	(*id)->data.data = m;
	(*id)->data.length = sizeof(*m);
	return 0;
    }

    m = mcc_alloc(res);
    if (m == NULL) {
	krb5_set_error_string (context, "malloc: out of memory");
	return KRB5_CC_NOMEM;
    }
    
    (*id)->data.data = m;
    (*id)->data.length = sizeof(*m);

    return 0;
}
Beispiel #3
0
static krb5_error_code
mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
    krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to);
    struct link *creds;
    krb5_principal principal;
    krb5_mcache **n;

    HEIMDAL_MUTEX_lock(&mcc_mutex);

    /* drop the from cache from the linked list to avoid lookups */
    for(n = &mcc_head; n && *n; n = &(*n)->next) {
	if(mfrom == *n) {
	    *n = mfrom->next;
	    break;
	}
    }

    /* swap creds */
    creds = mto->creds;
    mto->creds = mfrom->creds;
    mfrom->creds = creds;
    /* swap principal */
    principal = mto->primary_principal;
    mto->primary_principal = mfrom->primary_principal;
    mfrom->primary_principal = principal;

    HEIMDAL_MUTEX_unlock(&mcc_mutex);
    mcc_destroy(context, from);

    return 0;
}
Beispiel #4
0
OM_uint32 gss_context_time
           (OM_uint32 * minor_status,
            const gss_ctx_id_t context_handle,
            OM_uint32 * time_rec
           )
{
    OM_uint32 lifetime;
    OM_uint32 major_status;

    GSSAPI_KRB5_INIT ();

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    lifetime = context_handle->lifetime;
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    major_status = gssapi_lifetime_left(minor_status, lifetime, time_rec);
    if (major_status != GSS_S_COMPLETE)
	return major_status;

    *minor_status = 0;

    if (*time_rec == 0)
	return GSS_S_CONTEXT_EXPIRED;
	
    return GSS_S_COMPLETE;
}
Beispiel #5
0
krb5_error_code
kcm_ccache_resolve_by_uuid(krb5_context context,
			   kcmuuid_t uuid,
			   kcm_ccache *ccache)
{
    kcm_ccache p;
    krb5_error_code ret;

    *ccache = NULL;

    ret = KRB5_FCC_NOFILE;

    HEIMDAL_MUTEX_lock(&ccache_mutex);

    for (p = ccache_head; p != NULL; p = p->next) {
	if ((p->flags & KCM_FLAGS_VALID) == 0)
	    continue;
	if (memcmp(p->uuid, uuid, sizeof(uuid)) == 0) {
	    ret = 0;
	    break;
	}
    }

    if (ret == 0) {
	kcm_retain_ccache(context, p);
	*ccache = p;
    }

    HEIMDAL_MUTEX_unlock(&ccache_mutex);

    return ret;
}
Beispiel #6
0
OM_uint32 gss_release_cred
           (OM_uint32 * minor_status,
            gss_cred_id_t * cred_handle
           )
{
    *minor_status = 0;

    if (*cred_handle == GSS_C_NO_CREDENTIAL) {
        return GSS_S_COMPLETE;
    }

    GSSAPI_KRB5_INIT ();

    HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex);

    if ((*cred_handle)->principal != NULL)
        krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
    if ((*cred_handle)->keytab != NULL)
	krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
    if ((*cred_handle)->ccache != NULL) {
	const krb5_cc_ops *ops;
	ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache);
	if (ops == &krb5_mcc_ops)
	    krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache);
	else 
	    krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache);
    }
    gss_release_oid_set(NULL, &(*cred_handle)->mechanisms);
    HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex);
    HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex);
    memset(*cred_handle, 0, sizeof(**cred_handle));
    free(*cred_handle);
    *cred_handle = GSS_C_NO_CREDENTIAL;
    return GSS_S_COMPLETE;
}
Beispiel #7
0
krb5_error_code
kcm_remove_event(krb5_context context,
		 kcm_event *event)
{
    krb5_error_code ret;
    kcm_event **e;
    int found = 0;

    log_event(event, "removing");

    HEIMDAL_MUTEX_lock(&events_mutex);
    for (e = &events_head; *e != NULL; e = &(*e)->next) {
	if (event == *e) {
	    *e = event->next;
	    found++;
	    break;
	}
    }

    if (!found) {
	ret = KRB5_CC_NOTFOUND;
	goto out;
    }

    ret = kcm_remove_event_internal(context, &event);

out:
    HEIMDAL_MUTEX_unlock(&events_mutex);

    return ret;
}
Beispiel #8
0
krb5_error_code
kcm_ccache_get_uuids(krb5_context context, kcm_client *client, kcm_operation opcode, krb5_storage *sp)
{
    krb5_error_code ret;
    kcm_ccache p;

    ret = KRB5_FCC_NOFILE;

    HEIMDAL_MUTEX_lock(&ccache_mutex);

    for (p = ccache_head; p != NULL; p = p->next) {
	if ((p->flags & KCM_FLAGS_VALID) == 0)
	    continue;
	ret = kcm_access(context, client, opcode, p);
	if (ret) {
	    ret = 0;
	    continue;
	}
	krb5_storage_write(sp, p->uuid, sizeof(p->uuid));
    }

    HEIMDAL_MUTEX_unlock(&ccache_mutex);

    return ret;
}
Beispiel #9
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_import_sec_context (
            OM_uint32 * minor_status,
            const gss_buffer_t interprocess_token,
            gss_ctx_id_t *context_handle
           )
{
    OM_uint32 ret, minor;
    gss_ctx_id_t context;
    gssspnego_ctx ctx;

    ret = _gss_spnego_alloc_sec_context(minor_status, &context);
    if (ret != GSS_S_COMPLETE) {
	return ret;
    }
    ctx = (gssspnego_ctx)context;

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    ret = gss_import_sec_context(minor_status,
				 interprocess_token,
				 &ctx->negotiated_ctx_id);
    if (ret != GSS_S_COMPLETE) {
	_gss_spnego_internal_delete_sec_context(&minor, context_handle, GSS_C_NO_BUFFER);
	return ret;
    }

    ctx->open = 1;
    /* don't bother filling in the rest of the fields */

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    *context_handle = (gss_ctx_id_t)ctx;

    return GSS_S_COMPLETE;
}
Beispiel #10
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_init_context_flags(unsigned int flags, krb5_context *context)
{
    static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT;
    krb5_context p;
    krb5_error_code ret;
    char **files = NULL;

    *context = NULL;

    p = calloc(1, sizeof(*p));
    if (!p)
        return ENOMEM;

    p->mutex = malloc(sizeof(HEIMDAL_MUTEX));
    if (p->mutex == NULL) {
        free(p);
        return ENOMEM;
    }
    HEIMDAL_MUTEX_init(p->mutex);

    HEIMDAL_MUTEX_lock(&homedir_mutex);
    if (allow_homedir)
        p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;
    HEIMDAL_MUTEX_unlock(&homedir_mutex);

    if ((flags & KRB5_CONTEXT_FLAG_NO_CONFIG) == 0) {
        ret = krb5_get_default_config_files(&files);
        if (ret)
            goto out;
    }
    ret = krb5_set_config_files(p, files);
    krb5_free_config_files(files);
    if (ret)
        goto out;

    heim_base_once_f(&init_context, p, init_context_once);

    /* init error tables */
    krb5_init_ets(p);
    cc_ops_register(p);
    kt_ops_register(p);

#ifdef PKINIT
    ret = hx509_context_init(&p->hx509ctx);
    if (ret)
        goto out;
#endif
    if (rk_SOCK_INIT())
        p->flags |= KRB5_CTX_F_SOCKETS_INITIALIZED;

out:
    if (ret) {
        krb5_free_context(p);
        p = NULL;
    }

    *context = p;
    return ret;
}
Beispiel #11
0
OM_uint32
_gsskrb5_verify_mic_internal
           (OM_uint32 * minor_status,
            const gsskrb5_ctx ctx,
	    krb5_context context,
            const gss_buffer_t message_buffer,
            const gss_buffer_t token_buffer,
            gss_qop_t * qop_state,
	    const char * type
	    )
{
    krb5_keyblock *key;
    OM_uint32 ret;

    if (ctx->more_flags & IS_CFX)
        return _gssapi_verify_mic_cfx (minor_status, ctx,
				       context, message_buffer, token_buffer,
				       qop_state);

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
    ret = _gsskrb5i_get_token_key(ctx, context, &key);
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }
    *minor_status = 0;

    switch (key->keytype) {
    case KRB5_ENCTYPE_DES_CBC_CRC :
    case KRB5_ENCTYPE_DES_CBC_MD4 :
    case KRB5_ENCTYPE_DES_CBC_MD5 :
#ifdef HEIM_WEAK_CRYPTO
	ret = verify_mic_des (minor_status, ctx, context,
			      message_buffer, token_buffer, qop_state, key,
			      type);
#else
      ret = GSS_S_FAILURE;
#endif
	break;
    case KRB5_ENCTYPE_DES3_CBC_MD5 :
    case KRB5_ENCTYPE_DES3_CBC_SHA1 :
	ret = verify_mic_des3 (minor_status, ctx, context,
			       message_buffer, token_buffer, qop_state, key,
			       type);
	break;
    case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
    case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
	ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
					  context,
					  message_buffer, token_buffer,
					  qop_state, key, type);
	break;
    default :
        abort();
    }
    krb5_free_keyblock (context, key);

    return ret;
}
Beispiel #12
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_context_time
           (OM_uint32 * minor_status,
            const gss_ctx_id_t context_handle,
            OM_uint32 * time_rec
           )
{
    krb5_context context;
    OM_uint32 lifetime;
    OM_uint32 major_status;
    const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;

    GSSAPI_KRB5_INIT (&context);

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
    lifetime = ctx->lifetime;
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    major_status = _gsskrb5_lifetime_left(minor_status, context,
					  lifetime, time_rec);
    if (major_status != GSS_S_COMPLETE)
	return major_status;

    *minor_status = 0;

    if (*time_rec == 0)
	return GSS_S_CONTEXT_EXPIRED;
	
    return GSS_S_COMPLETE;
}
Beispiel #13
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_process_context_token
           (OM_uint32 *minor_status,
            const gss_ctx_id_t context_handle,
            const gss_buffer_t token_buffer
           )
{
    gss_ctx_id_t context ;
    gssspnego_ctx ctx;
    OM_uint32 ret;

    if (context_handle == GSS_C_NO_CONTEXT)
	return GSS_S_NO_CONTEXT;

    context = context_handle;
    ctx = (gssspnego_ctx)context_handle;

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    ret = gss_process_context_token(minor_status,
				    ctx->negotiated_ctx_id,
				    token_buffer);
    if (ret != GSS_S_COMPLETE) {
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	return ret;
    }

    ctx->negotiated_ctx_id = GSS_C_NO_CONTEXT;

    return _gss_spnego_internal_delete_sec_context(minor_status,
					   &context,
					   GSS_C_NO_BUFFER);
}
Beispiel #14
0
krb5_error_code
kcm_ccache_resolve(krb5_context context,
		   const char *name,
		   kcm_ccache *ccache)
{
    kcm_ccache p;
    krb5_error_code ret;

    *ccache = NULL;

    ret = KRB5_FCC_NOFILE;

    HEIMDAL_MUTEX_lock(&ccache_mutex);

    for (p = ccache_head; p != NULL; p = p->next) {
	if ((p->flags & KCM_FLAGS_VALID) == 0)
	    continue;
	if (strcmp(p->name, name) == 0) {
	    ret = 0;
	    break;
	}
    }

    if (ret == 0) {
	kcm_retain_ccache(context, p);
	*ccache = p;
    }

    HEIMDAL_MUTEX_unlock(&ccache_mutex);

    return ret;
}
static OM_uint32 inquire_sec_context_has_updated_spnego
           (OM_uint32 *minor_status,
            const gsskrb5_ctx context_handle,
            gss_buffer_set_t *data_set)
{
    int is_updated = 0;

    *minor_status = 0;
    *data_set = GSS_C_NO_BUFFER_SET;

    /*
     * For Windows SPNEGO implementations, both the initiator and the
     * acceptor are assumed to have been updated if a "newer" [CLAR] or
     * different enctype is negotiated for use by the Kerberos GSS-API
     * mechanism.
     */
    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
    _gsskrb5i_is_cfx(context_handle, &is_updated);
    if (is_updated == 0) {
	krb5_keyblock *acceptor_subkey;

	if (context_handle->more_flags & LOCAL)
	    acceptor_subkey = context_handle->auth_context->remote_subkey;
	else
	    acceptor_subkey = context_handle->auth_context->local_subkey;

	if (acceptor_subkey != NULL)
	    is_updated = (acceptor_subkey->keytype !=
			  context_handle->auth_context->keyblock->keytype);
    }
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);

    return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE;
}
Beispiel #16
0
/** heim_db_register
 * @brief Registers a DB type for use with heim_db_create().
 *
 * @param dbtype Name of DB type
 * @param data   Private data argument to the dbtype's openf method
 * @param plugin Structure with DB type methods (function pointers)
 *
 * Backends that provide begin/commit/rollback methods must provide ACID
 * semantics.
 *
 * The registered DB type will have ACID semantics for backends that do
 * not provide begin/commit/rollback methods but do provide lock/unlock
 * and rdjournal/wrjournal methods (using a replay log journalling
 * scheme).
 *
 * If the registered DB type does not natively provide read vs. write
 * transaction isolation but does provide a lock method then the DB will
 * provide read/write transaction isolation.
 *
 * @return ENOMEM on failure, else 0.
 *
 * @addtogroup heimbase
 */
int
heim_db_register(const char *dbtype,
		 void *data,
		 struct heim_db_type *plugin)
{
    heim_dict_t plugins;
    heim_string_t s;
    db_plugin plug, plug2;
    int ret = 0;

    if ((plugin->beginf != NULL && plugin->commitf == NULL) ||
	(plugin->beginf != NULL && plugin->rollbackf == NULL) ||
	(plugin->lockf != NULL && plugin->unlockf == NULL) ||
	plugin->copyf == NULL)
	heim_abort("Invalid DB plugin; make sure methods are paired");

    /* Initialize */
    plugins = heim_dict_create(11);
    if (plugins == NULL)
	return ENOMEM;
    heim_base_once_f(&db_plugin_init_once, plugins, db_init_plugins_once);
    heim_release(plugins);
    heim_assert(db_plugins != NULL, "heim_db plugin table initialized");

    s = heim_string_create(dbtype);
    if (s == NULL)
	return ENOMEM;

    plug = heim_alloc(sizeof (*plug), "db_plug", plugin_dealloc);
    if (plug == NULL) {
	heim_release(s);
	return ENOMEM;
    }

    plug->name = heim_retain(s);
    plug->openf = plugin->openf;
    plug->clonef = plugin->clonef;
    plug->closef = plugin->closef;
    plug->lockf = plugin->lockf;
    plug->unlockf = plugin->unlockf;
    plug->syncf = plugin->syncf;
    plug->beginf = plugin->beginf;
    plug->commitf = plugin->commitf;
    plug->rollbackf = plugin->rollbackf;
    plug->copyf = plugin->copyf;
    plug->setf = plugin->setf;
    plug->delf = plugin->delf;
    plug->iterf = plugin->iterf;
    plug->data = data;

    HEIMDAL_MUTEX_lock(&db_type_mutex);
    plug2 = heim_dict_get_value(db_plugins, s);
    if (plug2 == NULL)
	ret = heim_dict_set_value(db_plugins, s, plug);
    HEIMDAL_MUTEX_unlock(&db_type_mutex);
    heim_release(plug);
    heim_release(s);

    return ret;
}
Beispiel #17
0
krb5_error_code
kcm_chown(krb5_context context,
	  kcm_client *client,
	  kcm_ccache ccache,
	  uid_t uid,
	  gid_t gid)
{
    KCM_ASSERT_VALID(ccache);

    /* System cache owner can only be set at startup */
    if (ccache->flags & KCM_FLAGS_OWNER_IS_SYSTEM)
	return KRB5_FCC_PERM;

    if (ccache->uid != client->uid)
	return KRB5_FCC_PERM;

    if (ccache->gid != client->gid)
	return KRB5_FCC_PERM;

    HEIMDAL_MUTEX_lock(&ccache->mutex);

    ccache->uid = uid;
    ccache->gid = gid;

    HEIMDAL_MUTEX_unlock(&ccache->mutex);

    return 0;
}
Beispiel #18
0
krb5_error_code
kcm_chmod(krb5_context context,
	  kcm_client *client,
	  kcm_ccache ccache,
	  uint16_t mode)
{
    KCM_ASSERT_VALID(ccache);

    /* System cache mode can only be set at startup */
    if (ccache->flags & KCM_FLAGS_OWNER_IS_SYSTEM)
	return KRB5_FCC_PERM;

    if (ccache->uid != client->uid)
	return KRB5_FCC_PERM;

    if (ccache->gid != client->gid)
	return KRB5_FCC_PERM;

    HEIMDAL_MUTEX_lock(&ccache->mutex);

    ccache->mode = mode;

    HEIMDAL_MUTEX_unlock(&ccache->mutex);

    return 0;
}
Beispiel #19
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;
}
Beispiel #20
0
static krb5_error_code
kcm_op_get_kdc_offset(krb5_context context,
		      kcm_client *client,
		      kcm_operation opcode,
		      krb5_storage *request,
		      krb5_storage *response)
{
    krb5_error_code ret;
    kcm_ccache ccache;
    char *name;

    ret = krb5_ret_stringz(request, &name);
    if (ret)
	return ret;

    KCM_LOG_REQUEST_NAME(context, client, opcode, name);

    ret = kcm_ccache_resolve_client(context, client, opcode, name, &ccache);
    free(name);
    if (ret)
	return ret;

    HEIMDAL_MUTEX_lock(&ccache->mutex);
    ret = krb5_store_int32(response, ccache->kdc_offset);
    HEIMDAL_MUTEX_unlock(&ccache->mutex);

    kcm_release_ccache(context, ccache);

    return ret;
}
Beispiel #21
0
krb5_error_code
kcm_ccache_destroy(krb5_context context, const char *name)
{
    kcm_ccache *p, ccache;
    krb5_error_code ret;

    ret = KRB5_FCC_NOFILE;

    HEIMDAL_MUTEX_lock(&ccache_mutex);
    for (p = &ccache_head; *p != NULL; p = &(*p)->next) {
	if (((*p)->flags & KCM_FLAGS_VALID) == 0)
	    continue;
	if (strcmp((*p)->name, name) == 0) {
	    ret = 0;
	    break;
	}
    }
    if (ret)
	goto out;

    if ((*p)->refcnt != 1) {
	ret = EAGAIN;
	goto out;
    }

    ccache = *p;
    *p = (*p)->next;
    kcm_free_ccache_data_internal(context, ccache);
    free(ccache);

out:
    HEIMDAL_MUTEX_unlock(&ccache_mutex);

    return ret;
}
Beispiel #22
0
OM_uint32 _gsskrb5_unwrap
           (OM_uint32 * minor_status,
            const gss_ctx_id_t context_handle,
            const gss_buffer_t input_message_buffer,
            gss_buffer_t output_message_buffer,
            int * conf_state,
            gss_qop_t * qop_state
           )
{
  krb5_keyblock *key;
  krb5_context context;
  OM_uint32 ret;
  krb5_keytype keytype;
  gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;

  output_message_buffer->value = NULL;
  output_message_buffer->length = 0;

  GSSAPI_KRB5_INIT (&context);

  if (qop_state != NULL)
      *qop_state = GSS_C_QOP_DEFAULT;
  HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
  ret = _gsskrb5i_get_token_key(ctx, context, &key);
  HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
  if (ret) {
      *minor_status = ret;
      return GSS_S_FAILURE;
  }
  krb5_enctype_to_keytype (context, key->keytype, &keytype);

  *minor_status = 0;

  switch (keytype) {
  case KEYTYPE_DES :
      ret = unwrap_des (minor_status, ctx,
			input_message_buffer, output_message_buffer,
			conf_state, qop_state, key);
      break;
  case KEYTYPE_DES3 :
      ret = unwrap_des3 (minor_status, ctx, context,
			 input_message_buffer, output_message_buffer,
			 conf_state, qop_state, key);
      break;
  case KEYTYPE_ARCFOUR:
  case KEYTYPE_ARCFOUR_56:
      ret = _gssapi_unwrap_arcfour (minor_status, ctx, context,
				    input_message_buffer, output_message_buffer,
				    conf_state, qop_state, key);
      break;
  default :
      ret = _gssapi_unwrap_cfx (minor_status, ctx, context,
				input_message_buffer, output_message_buffer,
				conf_state, qop_state, key);
      break;
  }
  krb5_free_keyblock (context, key);
  return ret;
}
void
_krb5_unload_plugins(krb5_context context, const char *name)
{
    HEIMDAL_MUTEX_lock(&plugin_mutex);
    heim_release(modules);
    modules = NULL;
    HEIMDAL_MUTEX_unlock(&plugin_mutex);
}
Beispiel #24
0
OM_uint32
_gsskrb5_register_acceptor_identity(OM_uint32 *min_stat, const char *identity)
{
    krb5_context context;
    krb5_error_code ret;

    *min_stat = 0;

    ret = _gsskrb5_init(&context);
    if(ret)
	return GSS_S_FAILURE;

    HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);

    if(_gsskrb5_keytab != NULL) {
	krb5_kt_close(context, _gsskrb5_keytab);
	_gsskrb5_keytab = NULL;
    }
    if (identity == NULL) {
	ret = krb5_kt_default(context, &_gsskrb5_keytab);
    } else {
	/*
	 * First check if we can the keytab as is and if it has content...
	 */
	ret = validate_keytab(context, identity, &_gsskrb5_keytab);
	/*
	 * if it doesn't, lets prepend FILE: and try again
	 */
	if (ret) {
	    char *p = NULL;
	    ret = asprintf(&p, "FILE:%s", identity);
	    if(ret < 0 || p == NULL) {
		HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
		return GSS_S_FAILURE;
	    }
	    ret = validate_keytab(context, p, &_gsskrb5_keytab);
	    free(p);
	}
    }
    HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
    if(ret) {
	*min_stat = ret;
	return GSS_S_FAILURE;
    }
    return GSS_S_COMPLETE;
}
Beispiel #25
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred_by_oid
	   (OM_uint32 * minor_status,
	    const gss_cred_id_t cred_handle,
	    const gss_OID desired_object,
	    gss_buffer_set_t *data_set)
{
    krb5_context context;
    gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
    krb5_error_code ret;
    gss_buffer_desc buffer;
    char *str;

    GSSAPI_KRB5_INIT (&context);

    if (gss_oid_equal(desired_object, GSS_KRB5_COPY_CCACHE_X) == 0) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_lock(&cred->cred_id_mutex);

    if (cred->ccache == NULL) {
	HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    ret = krb5_cc_get_full_name(context, cred->ccache, &str);
    HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex);
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    buffer.value = str;
    buffer.length = strlen(str);

    ret = gss_add_buffer_set_member(minor_status, &buffer, data_set);
    if (ret != GSS_S_COMPLETE)
	_gsskrb5_clear_status ();

    free(str);

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Beispiel #26
0
void KRB5_LIB_FUNCTION
krb5_free_error_string(krb5_context context, char *str)
{
    HEIMDAL_MUTEX_lock(context->mutex);
    if (str != context->error_buf)
	free(str);
    HEIMDAL_MUTEX_unlock(context->mutex);
}
Beispiel #27
0
OM_uint32 GSSAPI_LIB_FUNCTION
gss_iter_creds_f(OM_uint32 *min_stat,
		 OM_uint32 flags,
		 gss_const_OID mech,
		 void * userctx,
		 void (*useriter)(void *, gss_iter_OID, gss_cred_id_t))
{
    struct _gss_iter *ctx;
    gss_OID_set mechs;
    gssapi_mech_interface m;
    size_t i;

    if (useriter == NULL)
	return GSS_S_CALL_INACCESSIBLE_READ;
    
    _gss_load_mech();
    
    /*
     * First make sure that at least one of the requested
     * mechanisms is one that we support.
     */
    mechs = _gss_mech_oids;
    
    ctx = malloc(sizeof(struct _gss_iter));
    if (ctx == NULL) {
	if (min_stat)
	    *min_stat = ENOMEM;
	return GSS_S_FAILURE;
    }
    
    HEIMDAL_MUTEX_init(&ctx->mutex);
    ctx->count = 1;
    ctx->userctx = userctx;
    ctx->iter = useriter;
    
    for (i = 0; i < mechs->count; i++) {
	
	if (mech && !gss_oid_equal(mech, &mechs->elements[i]))
	    continue;
	
	m = __gss_get_mechanism(&mechs->elements[i]);
	if (!m)
	    continue;
	
	if (m->gm_iter_creds == NULL)
	    continue;
	
	HEIMDAL_MUTEX_lock(&ctx->mutex);
	ctx->count += 1;
	HEIMDAL_MUTEX_unlock(&ctx->mutex);
	
	m->gm_iter_creds(flags, ctx, iterate);
    }
    
    iter_deref(ctx);
    
    return GSS_S_COMPLETE;
}
krb5_error_code
krb5_plugin_run_f(krb5_context context,
		  const char *module,
		  const char *name,
		  int min_version,
		  int flags,
		  void *userctx,
		  krb5_error_code (*func)(krb5_context, const void *, void *, void *))
{
    heim_string_t m = heim_string_create(module);
    heim_dict_t dict;
    struct iter_ctx s;

    HEIMDAL_MUTEX_lock(&plugin_mutex);

    dict = heim_dict_copy_value(modules, m);
    heim_release(m);
    if (dict == NULL) {
	HEIMDAL_MUTEX_unlock(&plugin_mutex);
	return KRB5_PLUGIN_NO_HANDLE;
    }

    s.context = context;
    s.name = name;
    s.n = heim_string_create(name);
    s.min_version = min_version;
    s.result = heim_array_create();
    s.func = func;
    s.userctx = userctx;

    heim_dict_iterate_f(dict, search_modules, &s);

    heim_release(dict);

    HEIMDAL_MUTEX_unlock(&plugin_mutex);

    s.ret = KRB5_PLUGIN_NO_HANDLE;

    heim_array_iterate_f(s.result, &s, eval_results);

    heim_release(s.result);
    heim_release(s.n);

    return s.ret;
}
Beispiel #29
0
static krb5_error_code
mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
{
    struct mkt_data *d;

    HEIMDAL_MUTEX_lock(&mkt_mutex);

    for (d = mkt_head; d != NULL; d = d->next)
	if (strcmp(d->name, name) == 0)
	    break;
    if (d) {
	if (d->refcount < 1)
	    krb5_abortx(context, "Double close on memory keytab, "
			"refcount < 1 %d", d->refcount);
	d->refcount++;
	id->data = d;
	HEIMDAL_MUTEX_unlock(&mkt_mutex);
	return 0;
    }

    d = calloc(1, sizeof(*d));
    if(d == NULL) {
	HEIMDAL_MUTEX_unlock(&mkt_mutex);
	krb5_set_error_message(context, ENOMEM,
			       N_("malloc: out of memory", ""));
	return ENOMEM;
    }
    d->name = strdup(name);
    if (d->name == NULL) {
	HEIMDAL_MUTEX_unlock(&mkt_mutex);
	free(d);
	krb5_set_error_message(context, ENOMEM,
			       N_("malloc: out of memory", ""));
	return ENOMEM;
    }
    d->entries = NULL;
    d->num_entries = 0;
    d->refcount = 1;
    d->next = mkt_head;
    mkt_head = d;
    HEIMDAL_MUTEX_unlock(&mkt_mutex);
    id->data = d;
    return 0;
}
Beispiel #30
0
krb5_error_code
kcm_run_events(krb5_context context,
	       time_t now)
{
    krb5_error_code ret;
    kcm_event **e;

    HEIMDAL_MUTEX_lock(&events_mutex);

    /* Only run event queue every N seconds */
    if (now < last_run + KCM_EVENT_QUEUE_INTERVAL) {
	HEIMDAL_MUTEX_unlock(&events_mutex);
	return 0;
    }

    /* go through events list, fire and expire */
    for (e = &events_head; *e != NULL; e = &(*e)->next) {
	if ((*e)->valid == 0)
	    continue;

	if (now >= (*e)->fire_time) {
	    ret = kcm_fire_event(context, e);
	    if (ret) {
		kcm_log(1, "Could not fire event for cache %s: %s",
			(*e)->ccache->name, krb5_get_err_text(context, ret));
	    }
	} else if ((*e)->expire_time && now >= (*e)->expire_time) {
	    ret = kcm_remove_event_internal(context, e);
	    if (ret) {
		kcm_log(1, "Could not expire event for cache %s: %s",
			(*e)->ccache->name, krb5_get_err_text(context, ret));
	    }
	}

	if (*e == NULL)
	    break;
    }

    last_run = now;

    HEIMDAL_MUTEX_unlock(&events_mutex);

    return 0;
}