Implement cache iteration and clean up modue.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@22817 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -43,8 +43,6 @@ typedef struct krb5_scache {
|
|||||||
|
|
||||||
sqlite_uint64 cid;
|
sqlite_uint64 cid;
|
||||||
|
|
||||||
/* */
|
|
||||||
HEIMDAL_MUTEX imutex;
|
|
||||||
sqlite3_stmt *icred;
|
sqlite3_stmt *icred;
|
||||||
sqlite3_stmt *dcred;
|
sqlite3_stmt *dcred;
|
||||||
sqlite3_stmt *iprincipal;
|
sqlite3_stmt *iprincipal;
|
||||||
@@ -60,14 +58,10 @@ typedef struct krb5_scache {
|
|||||||
|
|
||||||
#define SCACHE(X) ((krb5_scache *)(X)->data.data)
|
#define SCACHE(X) ((krb5_scache *)(X)->data.data)
|
||||||
|
|
||||||
#define DEFAULT_SCACHE "/tmp/scache-bar" /* XXX */
|
#define KRB5_SCACHE_FILE "/tmp/krb5scc_%{uid}"
|
||||||
|
#define KRB5_SCACHE_NAME "SDB:" KRB5_SCACHE_FILE
|
||||||
#define SCACHE_STRING(x) #x
|
|
||||||
#define SCACHE_XSTRING(x) SCACHE_STRING(x)
|
|
||||||
|
|
||||||
#define SCACHE_INVALID_CID ((sqlite_uint64)-1)
|
#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"
|
#define SCACHE_DEF_NAME "Default-cache"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -80,7 +74,7 @@ typedef struct krb5_scache {
|
|||||||
"defaultcache INTEGER NOT NULL" \
|
"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 "" \
|
#define SQL_CCACHE "" \
|
||||||
"CREATE TABLE caches (" \
|
"CREATE TABLE caches (" \
|
||||||
@@ -150,14 +144,33 @@ scc_free(krb5_scache *s)
|
|||||||
free(s->file);
|
free(s->file);
|
||||||
if (s->name)
|
if (s->name)
|
||||||
free(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)
|
if (s->db)
|
||||||
sqlite3_close(s->db);
|
sqlite3_close(s->db);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_scache *
|
static krb5_scache *
|
||||||
scc_alloc(const char *name)
|
scc_alloc(krb5_context context, const char *name)
|
||||||
{
|
{
|
||||||
krb5_scache *s;
|
krb5_scache *s;
|
||||||
|
|
||||||
@@ -180,10 +193,13 @@ scc_alloc(const char *name)
|
|||||||
*file++ = '\0';
|
*file++ = '\0';
|
||||||
s->file = strdup(file);
|
s->file = strdup(file);
|
||||||
} else {
|
} else {
|
||||||
s->file = strdup(DEFAULT_SCACHE);
|
_krb5_expand_default_cc_name(context,
|
||||||
|
KRB5_SCACHE_FILE,
|
||||||
|
&s->file);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
asprintf(&s->name, "unique:%08x", (unsigned long)s);
|
||||||
}
|
}
|
||||||
if (s->file == NULL || s->name == NULL) {
|
if (s->file == NULL || s->name == NULL) {
|
||||||
@@ -191,8 +207,6 @@ scc_alloc(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HEIMDAL_MUTEX_init(&s->imutex);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +214,7 @@ static krb5_error_code
|
|||||||
open_database(krb5_context context, krb5_scache *s, int flags)
|
open_database(krb5_context context, krb5_scache *s, int flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sqlite3_open_v2(s->file, &s->db, SQLITE_OPEN_READWRITE|flags, NULL);
|
ret = sqlite3_open_v2(s->file, &s->db, SQLITE_OPEN_READWRITE|flags, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (s->db) {
|
if (s->db) {
|
||||||
@@ -379,7 +394,7 @@ scc_resolve(krb5_context context, krb5_ccache *id, const char *res)
|
|||||||
krb5_scache *s;
|
krb5_scache *s;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
s = scc_alloc(res);
|
s = scc_alloc(context, res);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
krb5_set_error_string (context, "malloc: out of memory");
|
krb5_set_error_string (context, "malloc: out of memory");
|
||||||
return KRB5_CC_NOMEM;
|
return KRB5_CC_NOMEM;
|
||||||
@@ -425,7 +440,7 @@ scc_gen_new(krb5_context context, krb5_ccache *id)
|
|||||||
{
|
{
|
||||||
krb5_scache *s;
|
krb5_scache *s;
|
||||||
|
|
||||||
s = scc_alloc(NULL);
|
s = scc_alloc(context, NULL);
|
||||||
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
krb5_set_error_string (context, "malloc: out of memory");
|
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) {
|
if (sqlite3_step(s->scache) != SQLITE_ROW) {
|
||||||
sqlite3_reset(s->scache);
|
sqlite3_reset(s->scache);
|
||||||
krb5_set_error_string(context, "No principal for scache %ld",
|
krb5_set_error_string(context, "No principal for cache SCACHE:%s:%s",
|
||||||
(unsigned long)s->cid);
|
s->file, s->name);
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sqlite3_column_type(s->scache, 0) != SQLITE_TEXT) {
|
if (sqlite3_column_type(s->scache, 0) != SQLITE_TEXT) {
|
||||||
sqlite3_reset(s->scache);
|
sqlite3_reset(s->scache);
|
||||||
krb5_set_error_string(context, "Principal data of wrong type "
|
krb5_set_error_string(context, "Principal data of wrong type "
|
||||||
"for scache %ld",
|
"for SCACHE:%s:%s",
|
||||||
(unsigned long)s->cid);
|
s->file, s->name);
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,8 +722,8 @@ scc_get_principal(krb5_context context,
|
|||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
sqlite3_reset(s->scache);
|
sqlite3_reset(s->scache);
|
||||||
krb5_set_error_string(context, "Principal not set "
|
krb5_set_error_string(context, "Principal not set "
|
||||||
"for scache %ld",
|
"for SCACHE:%s:%s",
|
||||||
(unsigned long)s->cid);
|
s->file, s->name);
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,8 +793,8 @@ scc_get_next (krb5_context context,
|
|||||||
|
|
||||||
if (sqlite3_column_type(stmt, 0) != SQLITE_BLOB) {
|
if (sqlite3_column_type(stmt, 0) != SQLITE_BLOB) {
|
||||||
krb5_set_error_string(context, "credential of wrong type "
|
krb5_set_error_string(context, "credential of wrong type "
|
||||||
"for scache %ld",
|
"for SCACHE:%s:%s",
|
||||||
(unsigned long)s->cid);
|
s->file, s->name);
|
||||||
return KRB5_CC_END;
|
return KRB5_CC_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,23 +840,94 @@ scc_set_flags(krb5_context context,
|
|||||||
return 0; /* XXX */
|
return 0; /* XXX */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cache_iter {
|
||||||
|
sqlite3 *db;
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
};
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
scc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
|
scc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
|
||||||
{
|
{
|
||||||
krb5_clear_error_string(context);
|
struct cache_iter *ctx;
|
||||||
return KRB5_CC_END;
|
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
|
static krb5_error_code
|
||||||
scc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
|
scc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
|
||||||
{
|
{
|
||||||
krb5_clear_error_string(context);
|
struct cache_iter *ctx = cursor;
|
||||||
return KRB5_CC_END;
|
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
|
static krb5_error_code
|
||||||
scc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,12 +995,9 @@ rollback:
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
scc_default_name(krb5_context context, char **str)
|
scc_default_name(krb5_context context, char **str)
|
||||||
{
|
{
|
||||||
asprintf(str, "SCACHE:%s:%s", DEFAULT_SCACHE, SCACHE_DEF_NAME);
|
return _krb5_expand_default_cc_name(context,
|
||||||
if (*str == NULL) {
|
KRB5_SCACHE_NAME,
|
||||||
krb5_set_error_string(context, "out of memory");
|
str);
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -925,7 +1008,7 @@ scc_default_name(krb5_context context, char **str)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const krb5_cc_ops krb5_scc_ops = {
|
const krb5_cc_ops krb5_scc_ops = {
|
||||||
"SCACHE",
|
"SDB",
|
||||||
scc_get_name,
|
scc_get_name,
|
||||||
scc_resolve,
|
scc_resolve,
|
||||||
scc_gen_new,
|
scc_gen_new,
|
||||||
|
Reference in New Issue
Block a user