static void
search_modules(heim_dict_t dict, heim_object_t key, heim_object_t value, void *ctx)
{
    struct iter_ctx *s = ctx;
    struct plugin2 *p = value;
    struct plug *pl = heim_dict_copy_value(p->names, s->n);
    struct common_plugin_method *cpm;

    if (pl == NULL) {
	if (p->dsohandle == NULL)
	    return;

	pl = heim_uniq_alloc(sizeof(*pl), "struct-plug", plug_free);

	cpm = pl->dataptr = dlsym(p->dsohandle, s->name);
	if (cpm) {
	    int ret;

	    ret = cpm->init(s->context, &pl->ctx);
	    if (ret)
		cpm = pl->dataptr = NULL;
	}
	heim_dict_add_value(p->names, s->n, pl);
    } else {
	cpm = pl->dataptr;
    }

    if (cpm && cpm->version >= s->min_version)
	heim_array_append_value(s->result, pl);

    heim_release(pl);
}
Example #2
0
int
hx509_certs_init(hx509_context context,
		 const char *name, int flags,
		 hx509_lock lock, hx509_certs *certs)
{
    struct hx509_keyset_ops *ops;
    const char *residue;
    hx509_certs c;
    char *type;
    int ret;

    *certs = NULL;

    residue = strchr(name, ':');
    if (residue) {
	type = malloc(residue - name + 1);
	if (type)
	    strlcpy(type, name, residue - name + 1);
	residue++;
	if (residue[0] == '\0')
	    residue = NULL;
    } else {
	type = strdup("MEMORY");
	residue = name;
    }
    if (type == NULL) {
	hx509_clear_error_string(context);
	return ENOMEM;
    }

    ops = _hx509_ks_type(context, type);
    if (ops == NULL) {
	hx509_set_error_string(context, 0, ENOENT,
			       "Keyset type %s is not supported", type);
	free(type);
	return ENOENT;
    }
    free(type);

    c = heim_uniq_alloc(sizeof(*c), "hx509-certs", dealloc_cert);
    if (c == NULL) {
	hx509_clear_error_string(context);
	return ENOMEM;
    }

    c->ops = ops;

    ret = (*ops->init)(context, c, &c->ops_data, flags, residue, lock);
    if (ret) {
	heim_release(c);
	return ret;
    }

    *certs = c;
    return 0;
}
Example #3
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_tkt_creds_init(krb5_context context,
		    krb5_ccache ccache,
                    krb5_creds *in_cred,
		    krb5_flags options,
                    krb5_tkt_creds_context *pctx)
{
    krb5_tkt_creds_context ctx;
    krb5_error_code ret;

    *pctx = NULL;

    ctx = heim_uniq_alloc(sizeof(*ctx), "tkt-ctx", tkt_release);
    if (ctx == NULL)
	return ENOMEM;

    ctx->context = context;
    ctx->state = tkt_init;
    ctx->options = options;
    ctx->ccache = ccache;

    if (ctx->options & KRB5_GC_FORWARDABLE)
	ctx->req_kdc_flags.b.forwardable = 1;
    if (ctx->options & KRB5_GC_USER_USER) {
	ctx->req_kdc_flags.b.enc_tkt_in_skey = 1;
	ctx->options |= KRB5_GC_NO_STORE;
    }
    if (options & KRB5_GC_CANONICALIZE)
	ctx->req_kdc_flags.b.canonicalize = 1;

    ret = krb5_copy_creds(context, in_cred, &ctx->in_cred);
    if (ret) {
	heim_release(ctx);
	return ret;
    }

    ret = krb5_unparse_name(context, ctx->in_cred->server, &ctx->server_name);
    if (ret) {
	heim_release(ctx);
	return ret;
    }

    *pctx = ctx;

    return 0;
}
void
krb5_load_plugins(krb5_context context, const char *name, const char **paths)
{
#ifdef HAVE_DLOPEN
    heim_string_t s = heim_string_create(name);
    heim_dict_t module;
    struct dirent *entry;
    krb5_error_code ret;
    const char **di;
    DIR *d;

    HEIMDAL_MUTEX_lock(&plugin_mutex);

    if (modules == NULL) {
	modules = heim_dict_create(11);
	if (modules == NULL) {
	    HEIMDAL_MUTEX_unlock(&plugin_mutex);
	    return;
	}
    }

    module = heim_dict_copy_value(modules, s);
    if (module == NULL) {
	module = heim_dict_create(11);
	if (module == NULL) {
	    HEIMDAL_MUTEX_unlock(&plugin_mutex);
	    heim_release(s);
	    return;
	}
	heim_dict_add_value(modules, s, module);
    }
    heim_release(s);

    for (di = paths; *di != NULL; di++) {
	d = opendir(*di);
	if (d == NULL)
	    continue;
	rk_cloexec_dir(d);

	while ((entry = readdir(d)) != NULL) {
	    char *n = entry->d_name;
	    char *path = NULL;
	    heim_string_t spath;
	    struct plugin2 *p;

	    /* skip . and .. */
	    if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0')))
		continue;

	    ret = 0;
#ifdef __APPLE__
	    { /* support loading bundles on MacOS */
		size_t len = strlen(n);
		if (len > 7 && strcmp(&n[len - 7],  ".bundle") == 0)
		    ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n);
	    }
#endif
	    if (ret < 0 || path == NULL)
		ret = asprintf(&path, "%s/%s", *di, n);

	    if (ret < 0 || path == NULL)
		continue;

	    spath = heim_string_create(n);
	    if (spath == NULL) {
		free(path);
		continue;
	    }

	    /* check if already cached */
	    p = heim_dict_copy_value(module, spath);
	    if (p == NULL) {
		p = heim_uniq_alloc(sizeof(*p), "krb5-plugin", plug_dealloc);
		if (p)
		    p->dsohandle = dlopen(path, RTLD_LOCAL|RTLD_LAZY);

		if (p && p->dsohandle) {
		    p->path = heim_retain(spath);
		    p->names = heim_dict_create(11);
		    heim_dict_add_value(module, spath, p);
		}
	    }
	    heim_release(spath);
	    heim_release(p);
	    free(path);
	}
	closedir(d);
    }
    heim_release(module);
    HEIMDAL_MUTEX_unlock(&plugin_mutex);
#endif /* HAVE_DLOPEN */
}