Exemplo n.º 1
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;
}
Exemplo n.º 2
0
krb5_error_code
_gsskrb5_init (krb5_context *context)
{
    static heim_base_once_t once;
    krb5_error_code ret = 0;

    heim_base_once_f(&once, NULL, once_func);

    *context = HEIMDAL_getspecific(context_key);
    if (*context == NULL) {

	ret = krb5_init_context(context);
	if (ret == 0) {
	    HEIMDAL_setspecific(context_key, *context, ret);
	    if (ret) {
		krb5_free_context(*context);
		*context = NULL;
	    }
	}
    } else {
	krb5_reload_config(*context, 0, NULL);
    }

    return ret;
}
Exemplo n.º 3
0
Arquivo: db.c Projeto: InvLim/heimdal
/** 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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
Arquivo: json.c Projeto: kaduk/heimdal
heim_object_t
heim_json_create_with_bytes(const void *data, size_t length, size_t max_depth,
			    heim_json_flags_t flags, heim_error_t *error)
{
    struct parse_ctx ctx;
    heim_object_t o;

    heim_base_once_f(&heim_json_once, NULL, json_init_once);

    ctx.lineno = 1;
    ctx.p = data;
    ctx.pstart = data;
    ctx.pend = ((uint8_t *)data) + length;
    ctx.error = NULL;
    ctx.flags = flags;
    ctx.depth = max_depth;

    o = parse_value(&ctx);

    if (o == NULL && error) {
	*error = ctx.error;
    } else if (ctx.error) {
	heim_release(ctx.error);
    }

    return o;
}
Exemplo n.º 6
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_init_context(krb5_context *context)
{
    static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT;
    krb5_context p;
    krb5_error_code ret;
    char **files;

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

    p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;

    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;

    /* done enough to load plugins */
    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;
}
Exemplo n.º 7
0
static const hc_EVP_CIPHER *
get_EVP_CIPHER(heim_base_once_t *once, hc_EVP_CIPHER *hc_memoize,
               const hc_EVP_CIPHER **hc_memoizep,
               const hc_EVP_CIPHER *fallback,
               unsigned long flags, int nid)
{
    struct once_init_cipher_ctx arg;

    arg.flags = flags;
    arg.hc_memoizep = hc_memoizep;
    arg.hc_memoize = hc_memoize;
    arg.fallback = fallback;
    arg.nid = nid;
    heim_base_once_f(once, &arg, get_EVP_CIPHER_once_cb);
    return *hc_memoizep; /* May be NULL */
}
Exemplo n.º 8
0
Arquivo: json.c Projeto: kaduk/heimdal
static int
heim_base2json(heim_object_t obj, void *ctx, heim_json_flags_t flags,
	       void (*out)(void *, const char *))
{
    struct twojson j;

    if (flags & HEIM_JSON_F_STRICT_STRINGS)
	return ENOTSUP; /* Sorry, not yet! */

    heim_base_once_f(&heim_json_once, NULL, json_init_once);

    j.indent = 0;
    j.ctx = ctx;
    j.out = out;
    j.flags = flags;
    j.ret = 0;
    j.first = 1;

    return base2json(obj, &j);
}
Exemplo n.º 9
0
Arquivo: string.c Projeto: lha/heimdal
heim_string_t
__heim_string_constant(const char *_str)
{
    static HEIMDAL_MUTEX mutex = HEIMDAL_MUTEX_INITIALIZER;
    static heim_base_once_t once;
    static heim_dict_t dict = NULL;
    heim_string_t s, s2;

    heim_base_once_f(&once, &dict, init_string);
    s = heim_string_create(_str);

    HEIMDAL_MUTEX_lock(&mutex);
    s2 = heim_dict_get_value(dict, s);
    if (s2) {
	heim_release(s);
	s = s2;
    } else {
	_heim_make_permanent(s);
	heim_dict_set_value(dict, s, s);
    }
    HEIMDAL_MUTEX_unlock(&mutex);

    return s;
}
Exemplo n.º 10
0
static krb5_error_code
an2ln_def_plug_an2ln(void *plug_ctx, krb5_context context,
		     const char *rule,
		     krb5_const_principal aname,
		     set_result_f set_res_f, void *set_res_ctx)
{
    krb5_error_code ret;
    const char *an2ln_db_fname;
    heim_db_t dbh = NULL;
    heim_dict_t db_options;
    heim_data_t k, v;
    heim_error_t error;
    char *unparsed = NULL;
    char *value = NULL;

    _krb5_load_db_plugins(context);
    heim_base_once_f(&sorted_text_db_init_once, NULL, sorted_text_db_init_f);

    if (strncmp(rule, "DB:", strlen("DB:") != 0))
	return KRB5_PLUGIN_NO_HANDLE;

    an2ln_db_fname = &rule[strlen("DB:")];
    if (!*an2ln_db_fname)
	return KRB5_PLUGIN_NO_HANDLE;

    ret = krb5_unparse_name(context, aname, &unparsed);
    if (ret)
	return ret;

    db_options = heim_dict_create(11);
    if (db_options != NULL)
	heim_dict_set_value(db_options, HSTR("read-only"),
			    heim_number_create(1));
    dbh = heim_db_create(NULL, an2ln_db_fname, db_options, &error);
    if (dbh == NULL) {
	krb5_set_error_message(context, heim_error_get_code(error),
			       N_("Couldn't open aname2lname-text-db", ""));
	ret = KRB5_PLUGIN_NO_HANDLE;
	goto cleanup;
    }

    /* Binary search; file should be sorted (in C locale) */
    k = heim_data_ref_create(unparsed, strlen(unparsed), NULL);
    if (k == NULL)
	return krb5_enomem(context);
    v = heim_db_copy_value(dbh, NULL, k, &error);
    heim_release(k);
    if (v == NULL && error != NULL) {
	krb5_set_error_message(context, heim_error_get_code(error),
			       N_("Lookup in aname2lname-text-db failed", ""));
	ret = heim_error_get_code(error);
	goto cleanup;
    } else if (v == NULL) {
	ret = KRB5_PLUGIN_NO_HANDLE;
	goto cleanup;
    } else {
	/* found */
	if (heim_data_get_length(v) == 0) {
	    krb5_set_error_message(context, ret,
				   N_("Principal mapped to empty username", ""));
	    ret = KRB5_NO_LOCALNAME;
	    goto cleanup;
	}
	ret = set_res_f(set_res_ctx, heim_data_get_ptr(v));
	heim_release(v);
    }

cleanup:
    heim_release(dbh);
    free(unparsed);
    free(value);
    return ret;
}
Exemplo n.º 11
0
/**
 * Map a principal name to a local username.
 *
 * Returns 0 on success, KRB5_NO_LOCALNAME if no mapping was found, or
 * some Kerberos or system error.
 *
 * Inputs:
 *
 * @param context    A krb5_context
 * @param aname      A principal name
 * @param lnsize     The size of the buffer into which the username will be written
 * @param lname      The buffer into which the username will be written
 *
 * @ingroup krb5_support
 */
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_aname_to_localname(krb5_context context,
			krb5_const_principal aname,
			size_t lnsize,
			char *lname)
{
    static heim_base_once_t reg_def_plugins = HEIM_BASE_ONCE_INIT;
    krb5_error_code ret;
    size_t i;
    char **rules = NULL;
    char *rule;

    if (lnsize)
	lname[0] = '\0';

    heim_base_once_f(&reg_def_plugins, context, reg_def_plugins_once);

    /* Try MIT's auth_to_local_names config first */
    ret = an2ln_local_names(context, aname, lnsize, lname);
    if (ret != KRB5_PLUGIN_NO_HANDLE)
	return ret;

    rules = krb5_config_get_strings(context, NULL, "realms", aname->realm,
				    "auth_to_local", NULL);
    if (!rules) {
	/* Heimdal's default rule */
	ret = an2ln_default(context, "HEIMDAL_DEFAULT", aname, lnsize, lname);
	if (ret == KRB5_PLUGIN_NO_HANDLE)
	    return KRB5_NO_LOCALNAME;
	return ret;
    }

    /*
     * MIT rules.
     *
     * Note that RULEs and DBs only have white-list functionality,
     * thus RULEs and DBs that we don't understand we simply ignore.
     *
     * This means that plugins that implement black-lists are
     * dangerous: if a black-list plugin isn't found, the black-list
     * won't be enforced.  But black-lists are dangerous anyways.
     */
    for (ret = KRB5_PLUGIN_NO_HANDLE, i = 0; rules[i]; i++) {
	rule = rules[i];

	/* Try NONE, DEFAULT, and HEIMDAL_DEFAULT rules */
	ret = an2ln_default(context, rule, aname, lnsize, lname);
	if (ret == KRB5_PLUGIN_NO_HANDLE)
	    /* Try DB, RULE, ... plugins */
	    ret = an2ln_plugin(context, rule, aname, lnsize, lname);

	if (ret == 0 && lnsize && !lname[0])
	    continue; /* Success but no lname?!  lies! */
	else if (ret != KRB5_PLUGIN_NO_HANDLE)
	    break;
    }

    if (ret == KRB5_PLUGIN_NO_HANDLE) {
	if (lnsize)
	    lname[0] = '\0';
	ret = KRB5_NO_LOCALNAME;
    }

    krb5_config_free_strings(rules);
    return ret;
}
Exemplo n.º 12
0
void
_krb5_load_db_plugins(krb5_context context)
{
    heim_base_once_f(&db_plugins_once, context, db_plugins_init);
}
Exemplo n.º 13
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_init_context(krb5_context *context)
{
    static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT;
    krb5_context p;
    krb5_error_code ret;
    char **files;
    uint8_t rnd;

    *context = NULL;

    /**
     * krb5_init_context() will get one random byte to make sure our
     * random is alive.  Assumption is that once the non blocking
     * source allows us to pull bytes, its all seeded and allows us to
     * pull more bytes.
     *
     * Most Kerberos users calls krb5_init_context(), so this is
     * useful point where we can do the checking.
     */
    ret = krb5_generate_random(&rnd, sizeof(rnd));
    if (ret)
	return ret;

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

    p->flags |= KRB5_CTX_F_HOMEDIR_ACCESS;

    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;

    /* done enough to load plugins */
    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;
}
Exemplo n.º 14
0
KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
_krb5_kuserok(krb5_context context,
	      krb5_principal principal,
	      const char *luser,
	      krb5_boolean an2ln_ok)
{
    static heim_base_once_t reg_def_plugins = HEIM_BASE_ONCE_INIT;
    krb5_error_code ret;
    struct plctx ctx;
    char **rules;

    /*
     * XXX we should have a struct with a krb5_context field and a
     * krb5_error_code fied and pass the address of that as the ctx
     * argument of heim_base_once_f().  For now we use a static to
     * communicate failures.  Actually, we ignore failures anyways,
     * since we can't return them.
     */
    heim_base_once_f(&reg_def_plugins, context, reg_def_plugins_once);

    ctx.flags = 0;
    ctx.luser = luser;
    ctx.principal = principal;
    ctx.result = FALSE;

    ctx.k5login_dir = krb5_config_get_string(context, NULL, "libdefaults",
					     "k5login_directory", NULL);

    if (an2ln_ok)
	ctx.flags |= KUSEROK_ANAME_TO_LNAME_OK;

    if (krb5_config_get_bool_default(context, NULL, FALSE, "libdefaults",
				     "k5login_authoritative", NULL))
	ctx.flags |= KUSEROK_K5LOGIN_IS_AUTHORITATIVE;

    if ((ctx.flags & KUSEROK_K5LOGIN_IS_AUTHORITATIVE) && plugin_reg_ret)
	return plugin_reg_ret; /* fail safe */

    rules = krb5_config_get_strings(context, NULL, "libdefaults",
				    "kuserok", NULL);
    if (rules == NULL) {
	/* Default: check ~/.k5login */
	ctx.rule = "USER-K5LOGIN";

	ret = plcallback(context, &kuserok_user_k5login_plug, NULL, &ctx);
	if (ret == 0)
	    goto out;

	ctx.rule = "SIMPLE";
	ret = plcallback(context, &kuserok_simple_plug, NULL, &ctx);
	if (ret == 0)
	    goto out;

	ctx.result = FALSE;
    } else {
	size_t n;

	for (n = 0; rules[n]; n++) {
	    ctx.rule = rules[n];

	    ret = _krb5_plugin_run_f(context, "krb5", KRB5_PLUGIN_KUSEROK,
				     KRB5_PLUGIN_KUSEROK_VERSION_0, 0,
				     &ctx, plcallback);
	    if (ret != KRB5_PLUGIN_NO_HANDLE) 
		goto out;
	}
    }

out:
    krb5_config_free_strings(rules);

    return ctx.result;
}
Exemplo n.º 15
0
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
_krb5_load_db_plugins(krb5_context context)
{
    heim_base_once_f(&db_plugins_once, context, db_plugins_init);
}