From 7b897bbaa6bf64b4423a623883c115369d7e641c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Mon, 7 Apr 2008 11:46:46 +0000 Subject: [PATCH] Implement cache iteration and clean up modue. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22817 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/krb5/scache.c | 155 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 119 insertions(+), 36 deletions(-) diff --git a/lib/krb5/scache.c b/lib/krb5/scache.c index 25358442e..cf243d359 100644 --- a/lib/krb5/scache.c +++ b/lib/krb5/scache.c @@ -43,8 +43,6 @@ typedef struct krb5_scache { sqlite_uint64 cid; - /* */ - HEIMDAL_MUTEX imutex; sqlite3_stmt *icred; sqlite3_stmt *dcred; sqlite3_stmt *iprincipal; @@ -60,14 +58,10 @@ typedef struct krb5_scache { #define SCACHE(X) ((krb5_scache *)(X)->data.data) -#define DEFAULT_SCACHE "/tmp/scache-bar" /* XXX */ - -#define SCACHE_STRING(x) #x -#define SCACHE_XSTRING(x) SCACHE_STRING(x) +#define KRB5_SCACHE_FILE "/tmp/krb5scc_%{uid}" +#define KRB5_SCACHE_NAME "SDB:" KRB5_SCACHE_FILE #define SCACHE_INVALID_CID ((sqlite_uint64)-1) -#define SCACHE_DEF_CID 1 -#define SCACHE_DEF_CID_NAME SCACHE_XSTRING(SCACHE_DEF_CID) #define SCACHE_DEF_NAME "Default-cache" /* @@ -80,7 +74,7 @@ typedef struct krb5_scache { "defaultcache INTEGER NOT NULL" \ ")" -#define SQL_SETUP_MASTER "INSERT INTO master VALUES(1, " SCACHE_DEF_CID_NAME ")" +#define SQL_SETUP_MASTER "INSERT INTO master VALUES(1, 1)" #define SQL_CCACHE "" \ "CREATE TABLE caches (" \ @@ -150,14 +144,33 @@ scc_free(krb5_scache *s) free(s->file); if (s->name) free(s->name); - /* XXX handle stmts */ + + if (s->icred) + sqlite3_finalize(s->icred); + if (s->dcred) + sqlite3_finalize(s->dcred); + if (s->iprincipal) + sqlite3_finalize(s->iprincipal); + if (s->icache) + sqlite3_finalize(s->icache); + if (s->ucachen) + sqlite3_finalize(s->ucachen); + if (s->ucachep) + sqlite3_finalize(s->ucachep); + if (s->dcache) + sqlite3_finalize(s->dcache); + if (s->scache) + sqlite3_finalize(s->scache); + if (s->scache_name) + sqlite3_finalize(s->scache_name); + if (s->db) sqlite3_close(s->db); free(s); } static krb5_scache * -scc_alloc(const char *name) +scc_alloc(krb5_context context, const char *name) { krb5_scache *s; @@ -180,10 +193,13 @@ scc_alloc(const char *name) *file++ = '\0'; s->file = strdup(file); } else { - s->file = strdup(DEFAULT_SCACHE); + _krb5_expand_default_cc_name(context, + KRB5_SCACHE_FILE, + &s->file); } } else { - s->file = strdup(DEFAULT_SCACHE); + _krb5_expand_default_cc_name(context, KRB5_SCACHE_FILE, + &s->file); asprintf(&s->name, "unique:%08x", (unsigned long)s); } if (s->file == NULL || s->name == NULL) { @@ -191,8 +207,6 @@ scc_alloc(const char *name) return NULL; } - HEIMDAL_MUTEX_init(&s->imutex); - return s; } @@ -200,6 +214,7 @@ static krb5_error_code open_database(krb5_context context, krb5_scache *s, int flags) { int ret; + ret = sqlite3_open_v2(s->file, &s->db, SQLITE_OPEN_READWRITE|flags, NULL); if (ret) { if (s->db) { @@ -379,7 +394,7 @@ scc_resolve(krb5_context context, krb5_ccache *id, const char *res) krb5_scache *s; int ret; - s = scc_alloc(res); + s = scc_alloc(context, res); if (s == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return KRB5_CC_NOMEM; @@ -425,7 +440,7 @@ scc_gen_new(krb5_context context, krb5_ccache *id) { krb5_scache *s; - s = scc_alloc(NULL); + s = scc_alloc(context, NULL); if (s == NULL) { krb5_set_error_string (context, "malloc: out of memory"); @@ -690,16 +705,16 @@ scc_get_principal(krb5_context context, if (sqlite3_step(s->scache) != SQLITE_ROW) { sqlite3_reset(s->scache); - krb5_set_error_string(context, "No principal for scache %ld", - (unsigned long)s->cid); + krb5_set_error_string(context, "No principal for cache SCACHE:%s:%s", + s->file, s->name); return KRB5_CC_END; } if (sqlite3_column_type(s->scache, 0) != SQLITE_TEXT) { sqlite3_reset(s->scache); krb5_set_error_string(context, "Principal data of wrong type " - "for scache %ld", - (unsigned long)s->cid); + "for SCACHE:%s:%s", + s->file, s->name); return KRB5_CC_END; } @@ -707,8 +722,8 @@ scc_get_principal(krb5_context context, if (str == NULL) { sqlite3_reset(s->scache); krb5_set_error_string(context, "Principal not set " - "for scache %ld", - (unsigned long)s->cid); + "for SCACHE:%s:%s", + s->file, s->name); return KRB5_CC_END; } @@ -778,8 +793,8 @@ scc_get_next (krb5_context context, if (sqlite3_column_type(stmt, 0) != SQLITE_BLOB) { krb5_set_error_string(context, "credential of wrong type " - "for scache %ld", - (unsigned long)s->cid); + "for SCACHE:%s:%s", + s->file, s->name); return KRB5_CC_END; } @@ -825,23 +840,94 @@ scc_set_flags(krb5_context context, return 0; /* XXX */ } +struct cache_iter { + sqlite3 *db; + sqlite3_stmt *stmt; +}; + static krb5_error_code scc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) { - krb5_clear_error_string(context); - return KRB5_CC_END; + struct cache_iter *ctx; + krb5_error_code ret; + char *name; + + *cursor = NULL; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + ret = _krb5_expand_default_cc_name(context, KRB5_SCACHE_FILE, &name); + if (ret) { + free(ctx); + return ret; + } + + ret = sqlite3_open_v2(name, &ctx->db, SQLITE_OPEN_READWRITE, NULL); + free(name); + if (ret != SQLITE_OK) { + free(ctx); + krb5_set_error_string(context, "no scache"); + return ENOENT; + } + + ret = prepare_stmt(context, ctx->db, &ctx->stmt, + "SELECT name FROM caches"); + if (ret) { + sqlite3_close(ctx->db); + free(ctx); + return ret; + } + + *cursor = ctx; + + return 0; } static krb5_error_code scc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) { - krb5_clear_error_string(context); - return KRB5_CC_END; + struct cache_iter *ctx = cursor; + krb5_error_code ret; + const char *name; + krb5_scache *s = NULL; + +again: + ret = sqlite3_step(ctx->stmt); + if (ret == SQLITE_DONE) { + krb5_clear_error_string(context); + return KRB5_CC_END; + } else if (ret != SQLITE_ROW) { + krb5_set_error_string(context, "Database failed: %s", + sqlite3_errmsg(s->db)); + return KRB5_CC_IO; + } + + if (sqlite3_column_type(ctx->stmt, 0) != SQLITE_TEXT) + goto again; + + name = (const char *)sqlite3_column_text(ctx->stmt, 0); + if (name == NULL) + goto again; + + ret = _krb5_cc_allocate(context, &krb5_scc_ops, id); + if (ret) + return ret; + + return scc_resolve(context, id, name); } static krb5_error_code scc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) { + struct cache_iter *ctx = cursor; + + sqlite3_finalize(ctx->stmt); + sqlite3_close(ctx->db); + free(ctx); return 0; } @@ -909,12 +995,9 @@ rollback: static krb5_error_code scc_default_name(krb5_context context, char **str) { - asprintf(str, "SCACHE:%s:%s", DEFAULT_SCACHE, SCACHE_DEF_NAME); - if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); - return ENOMEM; - } - return 0; + return _krb5_expand_default_cc_name(context, + KRB5_SCACHE_NAME, + str); } @@ -925,7 +1008,7 @@ scc_default_name(krb5_context context, char **str) */ const krb5_cc_ops krb5_scc_ops = { - "SCACHE", + "SDB", scc_get_name, scc_resolve, scc_gen_new,