Esempio n. 1
0
static void
eval_object(heim_object_t o)
{
    heim_tid_t t = heim_get_tid(o);

    if (t == heim_array_get_type_id()) {
	heim_array_iterate_f(o, NULL, eval_array_element);
    } else if (t == heim_dict_get_type_id()) {
	const char *op = heim_dict_get_value(o, HSTR("op"));

	heim_assert(op != NULL, "op missing");

	if (strcmp(op, "repeat") == 0) {
	    eval_repeat(o);
	} else if (strcmp(op, "kinit") == 0) {
	    eval_kinit(o);
	} else if (strcmp(op, "kgetcred") == 0) {
	    eval_kgetcred(o);
	} else if (strcmp(op, "kdestroy") == 0) {
	    eval_kdestroy(o);
	} else {
	    errx(1, "unsupported ops %s", op);
	}

    } else
	errx(1, "unsupported");
}
Esempio n. 2
0
static int
base2json(heim_object_t obj, struct twojson *j)
{
    heim_tid_t type;

    if (obj == NULL) {
	indent(j);
	j->out(j->ctx, "<NULL>\n");
    }

    type = heim_get_tid(obj);
    switch (type) {
    case HEIM_TID_ARRAY:
	indent(j);
	j->out(j->ctx, "[\n");
	j->indent++;
	heim_array_iterate_f(obj, j, array2json);
	j->indent--;
	indent(j);
	j->out(j->ctx, "]\n");
	break;

    case HEIM_TID_DICT:
	indent(j);
	j->out(j->ctx, "{\n");
	j->indent++;
	heim_dict_iterate_f(obj, j, dict2json);
	j->indent--;
	indent(j);
	j->out(j->ctx, "}\n");
	break;

    case HEIM_TID_STRING:
	indent(j);
	j->out(j->ctx, "\"");
	j->out(j->ctx, heim_string_get_utf8(obj));
	j->out(j->ctx, "\"");
	break;

    case HEIM_TID_NUMBER: {
	char num[16];
	indent(j);
	snprintf(num, sizeof(num), "%d", heim_number_get_int(obj));
	j->out(j->ctx, num);
	break;
    }
    case HEIM_TID_NULL:
	indent(j);
	j->out(j->ctx, "null");
	break;
    case HEIM_TID_BOOL:
	indent(j);
	j->out(j->ctx, heim_bool_val(obj) ? "true" : "false");
	break;
    default:
	return 1;
    }
    return 0;
}
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;
}
Esempio n. 4
0
File: json.c Progetto: kaduk/heimdal
static int
base2json(heim_object_t obj, struct twojson *j)
{
    heim_tid_t type;
    int first = 0;

    if (obj == NULL) {
	if (j->flags & HEIM_JSON_F_CNULL2JSNULL) {
	    obj = heim_null_create();
	} else if (j->flags & HEIM_JSON_F_NO_C_NULL) {
	    return EINVAL;
	} else {
	    indent(j);
	    j->out(j->ctx, "<NULL>\n"); /* This is NOT valid JSON! */
	    return 0;
	}
    }

    type = heim_get_tid(obj);
    switch (type) {
    case HEIM_TID_ARRAY:
	indent(j);
	j->out(j->ctx, "[\n");
	j->indent++;
	first = j->first;
	j->first = 1;
	heim_array_iterate_f(obj, j, array2json);
	j->indent--;
	if (!j->first)
	    j->out(j->ctx, "\n");
	indent(j);
	j->out(j->ctx, "]\n");
	j->first = first;
	break;

    case HEIM_TID_DICT:
	indent(j);
	j->out(j->ctx, "{\n");
	j->indent++;
	first = j->first;
	j->first = 1;
	heim_dict_iterate_f(obj, j, dict2json);
	j->indent--;
	if (!j->first)
	    j->out(j->ctx, "\n");
	indent(j);
	j->out(j->ctx, "}\n");
	j->first = first;
	break;

    case HEIM_TID_STRING:
	indent(j);
	j->out(j->ctx, "\"");
	j->out(j->ctx, heim_string_get_utf8(obj));
	j->out(j->ctx, "\"");
	break;

    case HEIM_TID_DATA: {
	heim_dict_t d;
	heim_string_t v;
	const heim_octet_string *data;
	char *b64 = NULL;
	int ret;

	if (j->flags & HEIM_JSON_F_NO_DATA)
	    return EINVAL; /* JSON doesn't do binary */

	data = heim_data_get_data(obj);
	ret = base64_encode(data->data, data->length, &b64);
	if (ret < 0 || b64 == NULL)
	    return ENOMEM;

	if (j->flags & HEIM_JSON_F_NO_DATA_DICT) {
	    indent(j);
	    j->out(j->ctx, "\"");
	    j->out(j->ctx, b64); /* base64-encode; hope there's no aliasing */
	    j->out(j->ctx, "\"");
	    free(b64);
	} else {
	    /*
	     * JSON has no way to represent binary data, therefore the
	     * following is a Heimdal-specific convention.
	     *
	     * We encode binary data as a dict with a single very magic
	     * key with a base64-encoded value.  The magic key includes
	     * a uuid, so we're not likely to alias accidentally.
	     */
	    d = heim_dict_create(2);
	    if (d == NULL) {
		free(b64);
		return ENOMEM;
	    }
	    v = heim_string_ref_create(b64, free);
	    if (v == NULL) {
		free(b64);
		heim_release(d);
		return ENOMEM;
	    }
	    ret = heim_dict_set_value(d, heim_tid_data_uuid_key, v);
	    heim_release(v);
	    if (ret) {
		heim_release(d);
		return ENOMEM;
	    }
	    ret = base2json(d, j);
	    heim_release(d);
	    if (ret)
		return ret;
	}
	break;
    }

    case HEIM_TID_NUMBER: {
	char num[32];
	indent(j);
	snprintf(num, sizeof (num), "%d", heim_number_get_int(obj));
	j->out(j->ctx, num);
	break;
    }
    case HEIM_TID_NULL:
	indent(j);
	j->out(j->ctx, "null");
	break;
    case HEIM_TID_BOOL:
	indent(j);
	j->out(j->ctx, heim_bool_val(obj) ? "true" : "false");
	break;
    default:
	return 1;
    }
    return 0;
}
Esempio n. 5
0
/**
 * Run plugins for the given @module (e.g., "krb5") and @name (e.g.,
 * "kuserok").  Specifically, the @func is invoked once per-plugin with
 * four arguments: the @context, the plugin symbol value (a pointer to a
 * struct whose first three fields are the same as struct common_plugin_method),
 * a context value produced by the plugin's init method, and @userctx.
 *
 * @func should unpack arguments for a plugin function and invoke it
 * with arguments taken from @userctx.  @func should save plugin
 * outputs, if any, in @userctx.
 *
 * All loaded and registered plugins are invoked via @func until @func
 * returns something other than KRB5_PLUGIN_NO_HANDLE.  Plugins that
 * have nothing to do for the given arguments should return
 * KRB5_PLUGIN_NO_HANDLE.
 *
 * Inputs:
 *
 * @context     A krb5_context
 * @module      Name of module (typically "krb5")
 * @name        Name of pluggable interface (e.g., "kuserok")
 * @min_version Lowest acceptable plugin minor version number
 * @flags       Flags (none defined at this time)
 * @userctx     Callback data for the callback function @func
 * @func        A callback function, invoked once per-plugin
 *
 * Outputs: None, other than the return value and such outputs as are
 *          gathered by @func.
 */
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 (KRB5_LIB_CALL *func)(krb5_context, const void *, void *, void *))
{
    heim_string_t m = heim_string_create(module);
    heim_dict_t dict;
    void *plug_ctx;
    struct common_plugin_method *cpm;
    struct iter_ctx s;
    struct krb5_plugin *registered_plugins = NULL;
    struct krb5_plugin *p;

    /* Get registered plugins */
    (void) _krb5_plugin_find(context, SYMBOL, name, &registered_plugins);

    HEIMDAL_MUTEX_lock(&plugin_mutex);

    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;
    s.ret = KRB5_PLUGIN_NO_HANDLE;

    /* Get loaded plugins */
    dict = heim_dict_get_value(modules, m);
    heim_release(m);

    /* Add loaded plugins to s.result array */
    if (dict)
	heim_dict_iterate_f(dict, &s, search_modules);

    /* We don't need to hold plugin_mutex during plugin invocation */
    HEIMDAL_MUTEX_unlock(&plugin_mutex);

    /* Invoke registered plugins (old system) */
    for (p = registered_plugins; p; p = p->next) {
	/*
	 * XXX This is the wrong way to handle registered plugins, as we
	 * call init/fini on each invocation!  We do this because we
	 * have nowhere in the struct plugin registered list to store
	 * the context allocated by the plugin's init function.  (But at
	 * least we do call init/fini!)
	 *
	 * What we should do is adapt the old plugin system to the new
	 * one and change how we register plugins so that we use the new
	 * struct plug to keep track of their context structures, that
	 * way we can init once, invoke many times, then fini.
	 */
	cpm = (struct common_plugin_method *)p->symbol;
	s.ret = cpm->init(context, &plug_ctx);
	if (s.ret)
	    continue;
	s.ret = s.func(s.context, p->symbol, plug_ctx, s.userctx);
	cpm->fini(plug_ctx);
	if (s.ret != KRB5_PLUGIN_NO_HANDLE)
	    break;
    }
    _krb5_plugin_free(registered_plugins);

    /* Invoke loaded plugins (new system) */
    if (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;
}