示例#1
0
文件: db.c 项目: abartlet/heimdal
static int
db_replay_log(heim_db_t db, heim_error_t *error)
{
    int ret;
    heim_string_t journal_fname = NULL;
    heim_object_t journal;
    size_t len;

    heim_assert(!db->in_transaction, "DB transaction not open");
    heim_assert(db->set_keys == NULL && db->set_keys == NULL, "DB transaction not open");

    if (error)
	*error = NULL;

    if (db->options == NULL)
	return 0;

    journal_fname = heim_dict_get_value(db->options, HSTR("journal-filename"));
    if (journal_fname == NULL)
	return 0;

    ret = read_json(heim_string_get_utf8(journal_fname), &journal, error);
    if (ret == ENOENT)
	return 0;
    if (ret == 0 && journal == NULL)
	return 0;
    if (ret != 0)
	return ret;

    if (heim_get_tid(journal) != HEIM_TID_ARRAY)
	return HEIM_ERROR(error, EINVAL,
			  (ret, N_("Invalid journal contents; delete journal",
				   "")));

    len = heim_array_get_length(journal);

    if (len > 0)
	db->set_keys = heim_array_get_value(journal, 0);
    if (len > 1)
	db->del_keys = heim_array_get_value(journal, 1);
    ret = db_do_log_actions(db, error);
    if (ret)
	return ret;

    /* Truncate replay log and we're done */
    ret = open_file(heim_string_get_utf8(journal_fname), 1, 0, NULL, error);
    if (ret)
	return ret;
    heim_release(db->set_keys);
    heim_release(db->del_keys);
    db->set_keys = NULL;
    db->del_keys = NULL;

    return 0;
}
示例#2
0
文件: db.c 项目: InvLim/heimdal
static heim_data_t
json_db_copy_value(void *db, heim_string_t table, heim_data_t key,
		  heim_error_t *error)
{
    json_db_t jsondb = db;
    heim_string_t key_string;
    const heim_octet_string *key_data = heim_data_get_data(key);
    struct stat st;
    heim_data_t result;

    if (error)
	*error = NULL;

    if (strnlen(key_data->data, key_data->length) != key_data->length) {
	HEIM_ERROR(error, EINVAL,
		   (EINVAL, N_("JSON DB requires keys that are actually "
			       "strings", "")));
	return NULL;
    }

    if (stat(heim_string_get_utf8(jsondb->dbname), &st) == -1) {
	HEIM_ERROR(error, errno,
		   (errno, N_("Could not stat JSON DB file", "")));
	return NULL;
    }

    if (st.st_mtime > jsondb->last_read_time ||
	st.st_ctime > jsondb->last_read_time) {
	heim_dict_t contents = NULL;
	int ret;

	/* Ignore file is gone (ENOENT) */
	ret = read_json(heim_string_get_utf8(jsondb->dbname),
		(heim_object_t *)&contents, error);
	if (ret)
	    return NULL;
	if (contents == NULL)
	    contents = heim_dict_create(29);
	heim_release(jsondb->dict);
	jsondb->dict = contents;
	jsondb->last_read_time = time(NULL);
    }

    key_string = heim_string_create_with_bytes(key_data->data,
					       key_data->length);
    if (key_string == NULL) {
	(void) HEIM_ENOMEM(error);
	return NULL;
    }

    result = heim_path_copy(jsondb->dict, error, table, key_string, NULL);
    heim_release(key_string);
    return result;
}
示例#3
0
文件: json.c 项目: kaduk/heimdal
static heim_dict_t
parse_dict(struct parse_ctx *ctx)
{
    heim_dict_t dict;
    size_t count = 0;
    int ret;

    heim_assert(*ctx->p == '{', "string doesn't start with {");

    dict = heim_dict_create(11);
    if (dict == NULL) {
	ctx->error = heim_error_create_enomem();
	return NULL;
    }

    ctx->p += 1; /* safe because parse_pair() calls white_spaces() first */

    while ((ret = parse_pair(dict, ctx)) > 0)
	count++;
    if (ret < 0) {
	heim_release(dict);
	return NULL;
    }
    if (count == 1 && !(ctx->flags & HEIM_JSON_F_NO_DATA_DICT)) {
	heim_object_t v = heim_dict_copy_value(dict, heim_tid_data_uuid_key);

	/*
	 * Binary data encoded as a dict with a single magic key with
	 * base64-encoded value?  Decode as heim_data_t.
	 */
	if (v != NULL && heim_get_tid(v) == HEIM_TID_STRING) {
	    void *buf;
	    size_t len;

	    buf = malloc(strlen(heim_string_get_utf8(v)));
	    if (buf == NULL) {
		heim_release(dict);
		heim_release(v);
		ctx->error = heim_error_create_enomem();
		return NULL;
	    }
	    len = base64_decode(heim_string_get_utf8(v), buf);
	    heim_release(v);
	    if (len == -1) {
		free(buf);
		return dict; /* assume aliasing accident */
	    }
	    heim_release(dict);
	    return (heim_dict_t)heim_data_ref_create(buf, len, free);
	}
    }
    return dict;
}
示例#4
0
static void
eval_kgetcred(heim_dict_t o)
{
    heim_string_t server, ccache;
    krb5_get_creds_opt opt;
    heim_bool_t nostore;
    krb5_error_code ret;
    krb5_ccache cc = NULL;
    krb5_principal s;
    krb5_creds *out = NULL;

    if (ptop)
	ptop->tgs_req++;

    server = heim_dict_get_value(o, HSTR("server"));
    if (server == NULL)
	krb5_errx(kdc_context, 1, "no server");

    ccache = heim_dict_get_value(o, HSTR("ccache"));
    if (ccache == NULL)
	krb5_errx(kdc_context, 1, "no ccache");

    nostore = heim_dict_get_value(o, HSTR("nostore"));
    if (nostore == NULL)
	nostore = heim_bool_create(1);

    ret = krb5_cc_resolve(kdc_context, heim_string_get_utf8(ccache), &cc);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");

    ret = krb5_parse_name(kdc_context, heim_string_get_utf8(server), &s);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_parse_name");

    ret = krb5_get_creds_opt_alloc(kdc_context, &opt);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_get_creds_opt_alloc");

    if (heim_bool_val(nostore))
	krb5_get_creds_opt_add_options(kdc_context, opt, KRB5_GC_NO_STORE);

    ret = krb5_get_creds(kdc_context, opt, cc, s, &out);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_get_creds");
    
    krb5_free_creds(kdc_context, out);
    krb5_free_principal(kdc_context, s);
    krb5_get_creds_opt_free(kdc_context, opt);
    krb5_cc_close(kdc_context, cc);
}
示例#5
0
文件: error.c 项目: lha/heimdal
char *
hx509_get_error_string(hx509_context context, int error_code)
{
    heim_error_t msg = context->error;
    heim_string_t s;
    char *str = NULL;

    if (msg == NULL || heim_error_get_code(msg) != error_code) {
	const char *cstr;

	cstr = com_right(context->et_list, error_code);
	if (cstr)
	    return strdup(cstr);
	cstr = strerror(error_code);
	if (cstr)
	    return strdup(cstr);
	if (asprintf(&str, "<unknown error: %d>", error_code) == -1)
	    return NULL;
	return str;
    }

    s = heim_error_copy_string(msg);
    if (s) {
	const char *cstr = heim_string_get_utf8(s);
	if (cstr)
	    str = strdup(cstr);
	heim_release(s);
    }
    return str;
}
示例#6
0
static krb5_error_code
an2ln_plugin(krb5_context context, const char *rule, krb5_const_principal aname,
	     size_t lnsize, char *lname)
{
    krb5_error_code ret;
    struct plctx ctx;

    ctx.rule = rule;
    ctx.aname = aname;
    ctx.luser = NULL;

    /*
     * Order of plugin invocation is non-deterministic, but there should
     * really be no more than one plugin that can handle any given kind
     * rule, so the effect should be deterministic anyways.
     */
    ret = _krb5_plugin_run_f(context, "krb5", KRB5_PLUGIN_AN2LN,
			     KRB5_PLUGIN_AN2LN_VERSION_0, 0, &ctx, plcallback);
    if (ret != 0) {
	heim_release(ctx.luser);
	return ret;
    }

    if (ctx.luser == NULL)
	return KRB5_PLUGIN_NO_HANDLE;

    if (strlcpy(lname, heim_string_get_utf8(ctx.luser), lnsize) >= lnsize)
	ret = KRB5_CONFIG_NOTENUFSPACE;

    heim_release(ctx.luser);
    return ret;
}
示例#7
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;
}
示例#8
0
文件: db.c 项目: InvLim/heimdal
/*
 * Helper to create a DB handle with the first registered DB type that
 * can open the given DB.  This is useful when the app doesn't know the
 * DB type a priori.  This assumes that DB types can "taste" DBs, either
 * from the filename extension or from the actual file contents.
 */
static void
dbtype_iter2create_f(heim_object_t dbtype, heim_object_t junk, void *arg)
{
    struct dbtype_iter *iter_ctx = arg;

    if (iter_ctx->db != NULL)
	return;
    iter_ctx->db = heim_db_create(heim_string_get_utf8(dbtype),
				  iter_ctx->dbname, iter_ctx->options,
				  iter_ctx->error);
}
示例#9
0
文件: db.c 项目: InvLim/heimdal
static void json_db_iter_f(heim_object_t key, heim_object_t value, void *arg)
{
    struct json_db_iter_ctx *ctx = arg;
    const char *key_string;
    heim_data_t key_data;

    key_string = heim_string_get_utf8((heim_string_t)key);
    key_data = heim_data_ref_create(key_string, strlen(key_string), NULL);
    ctx->iter_f(key_data, (heim_object_t)value, ctx->iter_ctx);
    heim_release(key_data);
}
示例#10
0
文件: db.c 项目: InvLim/heimdal
static
heim_data_t from_base64(heim_string_t s, heim_error_t *error)
{
    void *buf;
    size_t len;
    heim_data_t d;

    buf = malloc(strlen(heim_string_get_utf8(s)));
    if (buf == NULL)
	goto enomem;

    len = rk_base64_decode(heim_string_get_utf8(s), buf);
    d = heim_data_ref_create(buf, len, free);
    if (d == NULL)
	goto enomem;
    return d;

enomem:
    free(buf);
    if (error)
	*error = heim_error_create_enomem();
    return NULL;
}
示例#11
0
文件: db.c 项目: InvLim/heimdal
/**
 * Clone (duplicate) an open DB handle.
 *
 * This is useful for multi-threaded applications.  Applications must
 * synchronize access to any given DB handle.
 *
 * Returns EBUSY if there is an open transaction for the input db.
 *
 * @param db      Open DB handle
 * @param error   Output error object
 *
 * @return a DB handle
 *
 * @addtogroup heimbase
 */
heim_db_t
heim_db_clone(heim_db_t db, heim_error_t *error)
{
    heim_db_t result;
    int ret;

    if (heim_get_tid(db) != HEIM_TID_DB)
	heim_abort("Expected a database");
    if (db->in_transaction)
	heim_abort("DB handle is busy");

    if (db->plug->clonef == NULL) {
	return heim_db_create(heim_string_get_utf8(db->dbtype),
			      heim_string_get_utf8(db->dbname),
			      db->options, error);
    }

    result = _heim_alloc_object(&db_object, sizeof(*result));
    if (result == NULL) {
	if (error)
	    *error = heim_error_create_enomem();
	return NULL;
    }

    result->set_keys = NULL;
    result->del_keys = NULL;
    ret = db->plug->clonef(db->db_data, &result->db_data, error);
    if (ret) {
	heim_release(result);
	if (error && !*error)
	    *error = heim_error_create(ENOENT,
				       N_("Could not re-open DB while cloning", ""));
	return NULL;
    }
    db->db_data = NULL;
    return result;
}
示例#12
0
文件: db.c 项目: InvLim/heimdal
static int
json_db_unlock(void *db, heim_error_t *error)
{
    json_db_t jsondb = db;
    int ret = 0;

    heim_assert(jsondb->locked, "DB not locked when unlock attempted");
    if (jsondb->fd > -1)
	ret = close(jsondb->fd);
    jsondb->fd = -1;
    jsondb->read_only = 0;
    jsondb->locked = 0;
    if (jsondb->locked_needs_unlink)
	unlink(heim_string_get_utf8(jsondb->bkpname));
    jsondb->locked_needs_unlink = 0;
    return ret;
}
示例#13
0
static void
eval_kdestroy(heim_dict_t o)
{
    heim_string_t ccache = heim_dict_get_value(o, HSTR("ccache"));;
    krb5_error_code ret;
    const char *name;
    krb5_ccache cc;

    heim_assert(ccache != NULL, "ccache_missing");
	
    name = heim_string_get_utf8(ccache);

    ret = krb5_cc_resolve(kdc_context, name, &cc);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");

    krb5_cc_destroy(kdc_context, cc);
}
示例#14
0
文件: db.c 项目: InvLim/heimdal
static int
json_db_lock(void *db, int read_only, heim_error_t *error)
{
    json_db_t jsondb = db;
    int ret;

    heim_assert(jsondb->fd == -1 || (jsondb->read_only && !read_only),
		"DB locks are not recursive");

    jsondb->read_only = read_only ? 1 : 0;
    if (jsondb->fd > -1)
	return 0;

    ret = open_file(heim_string_get_utf8(jsondb->bkpname), 1, 1, &jsondb->fd, error);
    if (ret == 0) {
	jsondb->locked_needs_unlink = 1;
	jsondb->locked = 1;
    }
    return ret;
}
示例#15
0
文件: db.c 项目: InvLim/heimdal
/**
 * Commit an open transaction on the given db.
 *
 * @param db    Open DB handle
 * @param error Output error object
 *
 * @return 0 on success, system error otherwise
 *
 * @addtogroup heimbase
 */
int
heim_db_commit(heim_db_t db, heim_error_t *error)
{
    int ret, ret2;
    heim_string_t journal_fname = NULL;

    if (heim_get_tid(db) != HEIM_TID_DB)
	return EINVAL;
    if (!db->in_transaction)
	return 0;
    if (db->plug->commitf == NULL && db->plug->lockf == NULL)
	return EINVAL;

    if (db->plug->commitf != NULL) {
	ret = db->plug->commitf(db->db_data, error);
	if (ret)
	    (void) db->plug->rollbackf(db->db_data, error);

	db->in_transaction = 0;
	db->ro_tx = 0;
	return ret;
    }

    if (db->ro_tx) {
	ret = 0;
	goto done;
    }

    if (db->options == NULL)
	journal_fname = heim_dict_get_value(db->options, HSTR("journal-filename"));

    if (journal_fname != NULL) {
	heim_array_t a;
	heim_string_t journal_contents;
	size_t len, bytes;
	int save_errno;

	/* Create contents for replay log */
	ret = ENOMEM;
	a = heim_array_create();
	if (a == NULL)
	    goto err;
	ret = heim_array_append_value(a, db->set_keys);
	if (ret) {
	    heim_release(a);
	    goto err;
	}
	ret = heim_array_append_value(a, db->del_keys);
	if (ret) {
	    heim_release(a);
	    goto err;
	}
	journal_contents = heim_json_copy_serialize(a, 0, error);
	heim_release(a);

	/* Write replay log */
	if (journal_fname != NULL) {
	    int fd;

	    ret = open_file(heim_string_get_utf8(journal_fname), 1, 0, &fd, error);
	    if (ret) {
		heim_release(journal_contents);
		goto err;
	    }
	    len = strlen(heim_string_get_utf8(journal_contents));
	    bytes = write(fd, heim_string_get_utf8(journal_contents), len);
	    save_errno = errno;
	    heim_release(journal_contents);
	    ret = close(fd);
	    if (bytes != len) {
		/* Truncate replay log */
		(void) open_file(heim_string_get_utf8(journal_fname), 1, 0, NULL, error);
		ret = save_errno;
		goto err;
	    }
	    if (ret)
		goto err;
	}
    }

    /* Apply logged actions */
    ret = db_do_log_actions(db, error);
    if (ret)
	return ret;

    if (db->plug->syncf != NULL) {
	/* fsync() or whatever */
	ret = db->plug->syncf(db->db_data, error);
	if (ret)
	    return ret;
    }

    /* Truncate replay log and we're done */
    if (journal_fname != NULL) {
	int fd;

	ret2 = open_file(heim_string_get_utf8(journal_fname), 1, 0, &fd, error);
	if (ret2 == 0)
	    (void) close(fd);
    }

    /*
     * Clean up; if we failed to remore the replay log that's OK, we'll
     * handle that again in heim_db_commit()
     */
done:
    heim_release(db->set_keys);
    heim_release(db->del_keys);
    db->set_keys = NULL;
    db->del_keys = NULL;
    db->in_transaction = 0;
    db->ro_tx = 0;

    ret2 = db->plug->unlockf(db->db_data, error);
    if (ret == 0)
	ret = ret2;

    return ret;

err:
    return HEIM_ERROR(error, ret,
		      (ret, N_("Error while committing transaction: %s", ""),
		       strerror(ret)));
}
示例#16
0
文件: db.c 项目: InvLim/heimdal
static int
json_db_sync(void *db, heim_error_t *error)
{
    json_db_t jsondb = db;
    size_t len, bytes;
    heim_error_t e;
    heim_string_t json;
    const char *json_text = NULL;
    int ret = 0;
    int fd = -1;
#ifdef WIN32
    int tries = 3;
#endif

    heim_assert(jsondb->fd > -1, "DB not locked when sync attempted");

    json = heim_json_copy_serialize(jsondb->dict, 0, &e);
    if (json == NULL) {
	if (error)
	    *error = e;
	else
	    heim_release(e);
	return heim_error_get_code(e);
    }

    json_text = heim_string_get_utf8(json);
    len = strlen(json_text);
    errno = 0;

#ifdef WIN32
    while (tries--) {
	ret = open_file(heim_string_get_utf8(jsondb->dbname), 1, 0, &fd, error);
	if (ret == 0)
	    break;
	sleep(1);
    }
    if (ret) {
	heim_release(json);
	return ret;
    }
#else
    fd = jsondb->fd;
#endif /* WIN32 */

    bytes = write(fd, json_text, len);
    heim_release(json);
    if (bytes != len)
	return errno ? errno : EIO;
    ret = fsync(fd);
    if (ret)
	return ret;

#ifdef WIN32
    ret = close(fd);
    if (ret)
	return GetLastError();
#else
    ret = rename(heim_string_get_utf8(jsondb->bkpname), heim_string_get_utf8(jsondb->dbname));
    if (ret == 0) {
	jsondb->locked_needs_unlink = 0;
	return 0;
    }
#endif /* WIN32 */

    return errno;
}
示例#17
0
static void
eval_kinit(heim_dict_t o)
{
    heim_string_t user, password, keytab, fast_armor_cc, pk_user_id, ccache;
    krb5_get_init_creds_opt *opt;
    krb5_init_creds_context ctx;
    krb5_principal client;
    krb5_keytab ktmem = NULL;
    krb5_ccache fast_cc = NULL;
    krb5_error_code ret;

    if (ptop)
	ptop->as_req++;

    user = heim_dict_get_value(o, HSTR("client"));
    if (user == NULL)
	krb5_errx(kdc_context, 1, "no client");

    password = heim_dict_get_value(o, HSTR("password"));
    keytab = heim_dict_get_value(o, HSTR("keytab"));
    pk_user_id = heim_dict_get_value(o, HSTR("pkinit-user-cert-id"));
    if (password == NULL && keytab == NULL && pk_user_id == NULL)
	krb5_errx(kdc_context, 1, "password, keytab, nor PKINIT user cert ID");

    ccache = heim_dict_get_value(o, HSTR("ccache"));

    ret = krb5_parse_name(kdc_context, heim_string_get_utf8(user), &client);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_unparse_name");

    /* PKINIT parts */
    ret = krb5_get_init_creds_opt_alloc (kdc_context, &opt);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_get_init_creds_opt_alloc");

    if (pk_user_id) {
	heim_bool_t rsaobj = heim_dict_get_value(o, HSTR("pkinit-use-rsa"));
	int use_rsa = rsaobj ? heim_bool_val(rsaobj) : 0;

	ret = krb5_get_init_creds_opt_set_pkinit(kdc_context, opt,
						 client,
						 heim_string_get_utf8(pk_user_id),
						 NULL, NULL, NULL,
						 use_rsa ? 2 : 0,
						 NULL, NULL, NULL);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
    }

    ret = krb5_init_creds_init(kdc_context, client, NULL, NULL, 0, opt, &ctx);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_init_creds_init");

    fast_armor_cc = heim_dict_get_value(o, HSTR("fast-armor-cc"));
    if (fast_armor_cc) {

	ret = krb5_cc_resolve(kdc_context, heim_string_get_utf8(fast_armor_cc), &fast_cc);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");

	ret = krb5_init_creds_set_fast_ccache(kdc_context, ctx, fast_cc);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_init_creds_set_fast_ccache");
    }
    
    if (password) {
	ret = krb5_init_creds_set_password(kdc_context, ctx, 
					   heim_string_get_utf8(password));
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_init_creds_set_password");
    }
    if (keytab) {
	krb5_keytab kt = NULL;

	ret = krb5_kt_resolve(kdc_context, heim_string_get_utf8(keytab), &kt);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_kt_resolve");

	ret = krb5_kt_resolve(kdc_context, "MEMORY:keytab", &ktmem);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_kt_resolve(MEMORY)");

	ret = copy_keytab(kdc_context, kt, ktmem);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "copy_keytab");

	krb5_kt_close(kdc_context, kt);

	ret = krb5_init_creds_set_keytab(kdc_context, ctx, ktmem);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_init_creds_set_keytab");
    }

    ret = krb5_init_creds_get(kdc_context, ctx);
    if (ret)
	krb5_err(kdc_context, 1, ret, "krb5_init_creds_get");

    if (ccache) {
	const char *name = heim_string_get_utf8(ccache);
	krb5_creds cred;
	krb5_ccache cc;

	ret = krb5_init_creds_get_creds(kdc_context, ctx, &cred);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_init_creds_get_creds");

	ret = krb5_cc_resolve(kdc_context, name, &cc);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_cc_resolve");

	krb5_init_creds_store(kdc_context, ctx, cc);

	ret = krb5_cc_close(kdc_context, cc);
	if (ret)
	    krb5_err(kdc_context, 1, ret, "krb5_cc_close");

	krb5_free_cred_contents(kdc_context, &cred);
    }

    krb5_init_creds_free(kdc_context, ctx);

    if (ktmem)
	krb5_kt_close(kdc_context, ktmem);
    if (fast_cc)
	krb5_cc_close(kdc_context, fast_cc);
}
示例#18
0
文件: json.c 项目: kaduk/heimdal
static heim_string_t
parse_string(struct parse_ctx *ctx)
{
    const uint8_t *start;
    int quote = 0;

    if (ctx->flags & HEIM_JSON_F_STRICT_STRINGS) {
	ctx->error = heim_error_create(EINVAL, "Strict JSON string encoding "
				       "not yet supported");
	return NULL;
    }

    if (*ctx->p != '"') {
	ctx->error = heim_error_create(EINVAL, "Expected a JSON string but "
				       "found something else at line %lu",
				       ctx->lineno);
	return NULL;
    }
    start = ++ctx->p;

    while (ctx->p < ctx->pend) {
	if (*ctx->p == '\n') {
	    ctx->lineno++;
	} else if (*ctx->p == '\\') {
	    if (ctx->p + 1 == ctx->pend)
		goto out;
	    ctx->p++;
	    quote = 1;
	} else if (*ctx->p == '"') {
	    heim_object_t o;

	    if (quote) {
		char *p0, *p;
		p = p0 = malloc(ctx->p - start);
		if (p == NULL)
		    goto out;
		while (start < ctx->p) {
		    if (*start == '\\') {
			start++;
			/* XXX validate quoted char */
		    }
		    *p++ = *start++;
		}
		o = heim_string_create_with_bytes(p0, p - p0);
		free(p0);
	    } else {
		o = heim_string_create_with_bytes(start, ctx->p - start);
		if (o == NULL) {
		    ctx->error = heim_error_create_enomem();
		    return NULL;
		}

		/* If we can decode as base64, then let's */
		if (ctx->flags & HEIM_JSON_F_TRY_DECODE_DATA) {
		    void *buf;
		    size_t len;
		    const char *s;

		    s = heim_string_get_utf8(o);
		    len = strlen(s);

		    if (len >= 4 && strspn(s, base64_chars) >= len - 2) {
			buf = malloc(len);
			if (buf == NULL) {
			    heim_release(o);
			    ctx->error = heim_error_create_enomem();
			    return NULL;
			}
			len = base64_decode(s, buf);
			if (len == -1) {
			    free(buf);
			    return o;
			}
			heim_release(o);
			o = heim_data_ref_create(buf, len, free);
		    }
		}
	    }
	    ctx->p += 1;

	    return o;
	}
	ctx->p += 1;
    }
    out:
    ctx->error = heim_error_create(EINVAL, "ran out of string");
    return NULL;
}
示例#19
0
文件: json.c 项目: 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;
}