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; }
static krb5_error_code KRB5_CALLCONV scc_close(krb5_context context, krb5_ccache id) { scc_free(SCACHE(id)); return 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; }
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; }