예제 #1
0
파일: scache.c 프로젝트: hyc/heimdal
static krb5_error_code KRB5_CALLCONV
scc_resolve(krb5_context context, krb5_ccache *id, const char *res)
{
    krb5_scache *s;
    int ret;

    s = scc_alloc(context, res);
    if (s == NULL) {
	krb5_set_error_message(context, KRB5_CC_NOMEM,
			       N_("malloc: out of memory", ""));
	return KRB5_CC_NOMEM;
    }

    ret = make_database(context, s);
    if (ret) {
	scc_free(s);
	return ret;
    }

    ret = sqlite3_bind_text(s->scache_name, 1, s->name, -1, NULL);
    if (ret != SQLITE_OK) {
	krb5_set_error_message(context, ENOMEM,
			       "bind name: %s", sqlite3_errmsg(s->db));
	scc_free(s);
	return ENOMEM;
    }

    if (sqlite3_step(s->scache_name) == SQLITE_ROW) {

	if (sqlite3_column_type(s->scache_name, 0) != SQLITE_INTEGER) {
	    sqlite3_reset(s->scache_name);
	    krb5_set_error_message(context, KRB5_CC_END,
				   N_("Cache name of wrong type "
				      "for scache %s", ""),
				   s->name);
	    scc_free(s);
	    return KRB5_CC_END;
	}

	s->cid = sqlite3_column_int(s->scache_name, 0);
    } else {
	s->cid = SCACHE_INVALID_CID;
    }
    sqlite3_reset(s->scache_name);

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

    return 0;
}
예제 #2
0
파일: scache.c 프로젝트: hyc/heimdal
static krb5_error_code KRB5_CALLCONV
scc_close(krb5_context context,
	  krb5_ccache id)
{
    scc_free(SCACHE(id));
    return 0;
}
예제 #3
0
static krb5_scache * KRB5_CALLCONV
scc_alloc(krb5_context context, const char *name)
{
    krb5_error_code ret;
    krb5_scache *s;

    ALLOC(s, 1);
    if(s == NULL)
	return NULL;

    s->cid = SCACHE_INVALID_CID;

    if (name) {
	char *file;

	if (*name == '\0') {
	    krb5_error_code ret;
	    ret = get_def_name(context, &s->name);
	    if (ret)
		s->name = strdup(SCACHE_DEF_NAME);
	} else
	    s->name = strdup(name);

	file = strrchr(s->name, ':');
	if (file) {
	    *file++ = '\0';
	    s->file = strdup(file);
	    ret = 0;
	} else {
	    ret = _krb5_expand_default_cc_name(context, KRB5_SCACHE_DB, &s->file);
	}
    } else {
	_krb5_expand_default_cc_name(context, KRB5_SCACHE_DB, &s->file);
	ret = asprintf(&s->name, "unique-%p", s);
    }
    if (ret < 0 || s->file == NULL || s->name == NULL) {
	scc_free(s);
	return NULL;
    }

    return s;
}
예제 #4
0
파일: scache.c 프로젝트: hyc/heimdal
static krb5_error_code KRB5_CALLCONV
scc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
{
    krb5_scache *sfrom = SCACHE(from);
    krb5_scache *sto = SCACHE(to);
    krb5_error_code ret;

    if (strcmp(sfrom->file, sto->file) != 0) {
	krb5_set_error_message(context, KRB5_CC_BADNAME,
			       N_("Can't handle cross database "
				  "credential move: %s -> %s", ""),
			       sfrom->file, sto->file);
	return KRB5_CC_BADNAME;
    }

    ret = make_database(context, sfrom);
    if (ret)
	return ret;

    ret = exec_stmt(context, sfrom->db,
		    "BEGIN IMMEDIATE TRANSACTION", KRB5_CC_IO);
    if (ret) return ret;

    if (sto->cid != SCACHE_INVALID_CID) {
	/* drop old cache entry */

	sqlite3_bind_int(sfrom->dcache, 1, sto->cid);
	do {
	    ret = sqlite3_step(sfrom->dcache);
	} while (ret == SQLITE_ROW);
	sqlite3_reset(sfrom->dcache);
	if (ret != SQLITE_DONE) {
	    krb5_set_error_message(context, KRB5_CC_IO,
				   N_("Failed to delete old cache: %d", ""),
				   (int)ret);
	    goto rollback;
	}
    }

    sqlite3_bind_text(sfrom->ucachen, 1, sto->name, -1, NULL);
    sqlite3_bind_int(sfrom->ucachen, 2, sfrom->cid);

    do {
	ret = sqlite3_step(sfrom->ucachen);
    } while (ret == SQLITE_ROW);
    sqlite3_reset(sfrom->ucachen);
    if (ret != SQLITE_DONE) {
	krb5_set_error_message(context, KRB5_CC_IO,
			       N_("Failed to update new cache: %d", ""),
			       (int)ret);
	goto rollback;
    }

    sto->cid = sfrom->cid;

    ret = exec_stmt(context, sfrom->db, "COMMIT", KRB5_CC_IO);
    if (ret) return ret;

    scc_free(sfrom);

    return 0;

rollback:
    exec_stmt(context, sfrom->db, "ROLLBACK", 0);
    scc_free(sfrom);

    return KRB5_CC_IO;
}