static krb5_error_code LDAP_fetch(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) { LDAPMessage *msg, *e; krb5_error_code ret; ret = LDAP_principal2message(context, db, entry->principal, &msg); if (ret) return ret; e = ldap_first_entry(HDB2LDAP(db), msg); if (e == NULL) { ret = HDB_ERR_NOENTRY; goto out; } ret = LDAP_message2entry(context, db, e, entry); if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, entry); if (ret) hdb_free_entry(context,entry); } } out: ldap_msgfree(msg); return ret; }
static krb5_error_code mdb_fetch(krb5_context context, HDB *db, krb5_const_principal principal, unsigned flags, hdb_entry_ex *entry) { krb5_data key, value; krb5_error_code code; code = mdb_principal2key(context, principal, &key); if (code) return code; code = db->hdb__get(context, db, key, &value); krb5_data_free(&key); if(code) return code; code = mdb_value2entry(context, &value, &entry->entry); krb5_data_free(&value); if (code) return code; if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { code = hdb_unseal_keys (context, db, &entry->entry); if (code) hdb_free_entry(context, entry); } return 0; }
/** * Retrieves an entry by searching for the given * principal in the Principal database table, both * for canonical principals and aliases. * * @param context The current krb5_context * @param db Heimdal database handle * @param principal The principal whose entry to search for * @param flags Currently only for HDB_F_DECRYPT * * @return 0 if everything worked, an error code if not */ static krb5_error_code hdb_sqlite_fetch(krb5_context context, HDB *db, krb5_const_principal principal, unsigned flags, hdb_entry_ex *entry) { int sqlite_error; krb5_error_code ret; char *principal_string; hdb_sqlite_db *hsdb = (hdb_sqlite_db*)(db->hdb_db); sqlite3_stmt *fetch = hsdb->fetch; krb5_data value; ret = krb5_unparse_name(context, principal, &principal_string); if (ret) { free(principal_string); return ret; } sqlite3_bind_text(fetch, 1, principal_string, -1, SQLITE_STATIC); sqlite_error = hdb_sqlite_step(context, hsdb->db, fetch); if (sqlite_error != SQLITE_ROW) { if(sqlite_error == SQLITE_DONE) { ret = HDB_ERR_NOENTRY; goto out; } else { krb5_set_error_string(context, "sqlite fetch failed: %d", sqlite_error); ret = EINVAL; goto out; } } if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, &entry->entry); if(ret) { hdb_free_entry(context, entry); goto out; } } value.length = sqlite3_column_bytes(fetch, 0); value.data = (void *) sqlite3_column_blob(fetch, 0); ret = hdb_value2entry(context, &value, &entry->entry); if(ret) goto out; ret = 0; out: sqlite3_clear_bindings(fetch); sqlite3_reset(fetch); free(principal_string); return ret; }
static krb5_error_code DB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry, int flag) { DB *d = (DB*)db->hdb_db; DBT key, value; krb5_data key_data, data; int code; code = db->hdb_lock(context, db, HDB_RLOCK); if(code == -1) { krb5_set_error_message(context, HDB_ERR_DB_INUSE, "Database %s in use", db->hdb_name); return HDB_ERR_DB_INUSE; } code = (*d->seq)(d, &key, &value, flag); db->hdb_unlock(context, db); /* XXX check value */ if(code == -1) { code = errno; krb5_set_error_message(context, code, "Database %s seq error: %s", db->hdb_name, strerror(code)); return code; } if(code == 1) { krb5_clear_error_message(context); return HDB_ERR_NOENTRY; } key_data.data = key.data; key_data.length = key.size; data.data = value.data; data.length = value.size; memset(entry, 0, sizeof(*entry)); if (hdb_value2entry(context, &data, &entry->entry)) return DB_seq(context, db, flags, entry, R_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { code = hdb_unseal_keys (context, db, &entry->entry); if (code) hdb_free_entry (context, entry); } if (code == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc(sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { code = ENOMEM; krb5_set_error_message(context, code, "malloc: out of memory"); hdb_free_entry (context, entry); } else { hdb_key2principal(context, &key_data, entry->entry.principal); } } return code; }
static krb5_error_code NDBM_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry, int first) { struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum key, value; krb5_data key_data, data; krb5_error_code ret = 0; if(first) key = dbm_firstkey(d->db); else key = dbm_nextkey(d->db); if(key.dptr == NULL) return HDB_ERR_NOENTRY; key_data.data = key.dptr; key_data.length = key.dsize; ret = db->hdb_lock(context, db, HDB_RLOCK); if(ret) return ret; value = dbm_fetch(d->db, key); db->hdb_unlock(context, db); data.data = value.dptr; data.length = value.dsize; memset(entry, 0, sizeof(*entry)); if(hdb_value2entry(context, &data, &entry->entry)) return NDBM_seq(context, db, flags, entry, 0); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys (context, db, &entry->entry); if (ret) hdb_free_entry (context, entry); } if (ret == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc (sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { hdb_free_entry (context, entry); ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); } else { hdb_key2principal (context, &key_data, entry->entry.principal); } } return ret; }
static krb5_error_code DB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry, int flag) { DBT key, value; DBC *dbcp = db->hdb_dbc; krb5_data key_data, data; int code; memset(&key, 0, sizeof(DBT)); memset(&value, 0, sizeof(DBT)); if ((*db->hdb_lock)(context, db, HDB_RLOCK)) return HDB_ERR_DB_INUSE; code = (*dbcp->c_get)(dbcp, &key, &value, flag); (*db->hdb_unlock)(context, db); /* XXX check value */ if (code == DB_NOTFOUND) return HDB_ERR_NOENTRY; if (code) return code; key_data.data = key.data; key_data.length = key.size; data.data = value.data; data.length = value.size; memset(entry, 0, sizeof(*entry)); if (hdb_value2entry(context, &data, &entry->entry)) return DB_seq(context, db, flags, entry, DB_NEXT); if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { code = hdb_unseal_keys (context, db, &entry->entry); if (code) hdb_free_entry (context, entry); } if (entry->entry.principal == NULL) { entry->entry.principal = malloc(sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { hdb_free_entry (context, entry); krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } else { hdb_key2principal(context, &key_data, entry->entry.principal); } } return 0; }
/** * Retrieves an entry by searching for the given * principal in the Principal database table, both * for canonical principals and aliases. * * @param context The current krb5_context * @param db Heimdal database handle * @param principal The principal whose entry to search for * @param flags Currently only for HDB_F_DECRYPT * @param kvno kvno to fetch is HDB_F_KVNO_SPECIFIED use used * * @return 0 if everything worked, an error code if not */ static krb5_error_code hdb_sqlite_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) { int sqlite_error; krb5_error_code ret; hdb_sqlite_db *hsdb = (hdb_sqlite_db*)(db->hdb_db); sqlite3_stmt *fetch = hsdb->fetch; krb5_data value; krb5_principal enterprise_principal = NULL; if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { if (principal->name.name_string.len != 1) { ret = KRB5_PARSE_MALFORMED; krb5_set_error_message(context, ret, "malformed principal: " "enterprise name with %d name components", principal->name.name_string.len); return ret; } ret = krb5_parse_name(context, principal->name.name_string.val[0], &enterprise_principal); if (ret) return ret; principal = enterprise_principal; } ret = bind_principal(context, principal, fetch, 1); if (ret) return ret; krb5_free_principal(context, enterprise_principal); sqlite_error = hdb_sqlite_step(context, hsdb->db, fetch); if (sqlite_error != SQLITE_ROW) { if(sqlite_error == SQLITE_DONE) { ret = HDB_ERR_NOENTRY; goto out; } else { ret = HDB_ERR_UK_RERROR; krb5_set_error_message(context, ret, "sqlite fetch failed: %d", sqlite_error); goto out; } } value.length = sqlite3_column_bytes(fetch, 0); value.data = (void *) sqlite3_column_blob(fetch, 0); ret = hdb_value2entry(context, &value, &entry->entry); if(ret) goto out; if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, &entry->entry); if(ret) { hdb_free_entry(context, entry); goto out; } } ret = 0; out: sqlite3_clear_bindings(fetch); sqlite3_reset(fetch); return ret; }
static krb5_error_code LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) { int msgid, rc, parserc; krb5_error_code ret; LDAPMessage *e; msgid = HDB2MSGID(db); if (msgid < 0) return HDB_ERR_NOENTRY; do { rc = ldap_result(HDB2LDAP(db), msgid, LDAP_MSG_ONE, NULL, &e); switch (rc) { case LDAP_RES_SEARCH_REFERENCE: ldap_msgfree(e); ret = 0; break; case LDAP_RES_SEARCH_ENTRY: /* We have an entry. Parse it. */ ret = LDAP_message2entry(context, db, e, entry); ldap_msgfree(e); break; case LDAP_RES_SEARCH_RESULT: /* We're probably at the end of the results. If not, abandon. */ parserc = ldap_parse_result(HDB2LDAP(db), e, NULL, NULL, NULL, NULL, NULL, 1); if (parserc != LDAP_SUCCESS && parserc != LDAP_MORE_RESULTS_TO_RETURN) { krb5_set_error_string(context, "ldap_parse_result: %s", ldap_err2string(parserc)); ldap_abandon(HDB2LDAP(db), msgid); } ret = HDB_ERR_NOENTRY; HDBSETMSGID(db, -1); break; case LDAP_SERVER_DOWN: ldap_msgfree(e); LDAP_close(context, db); HDBSETMSGID(db, -1); ret = ENETDOWN; break; default: /* Some unspecified error (timeout?). Abandon. */ ldap_msgfree(e); ldap_abandon(HDB2LDAP(db), msgid); ret = HDB_ERR_NOENTRY; HDBSETMSGID(db, -1); break; } } while (rc == LDAP_RES_SEARCH_REFERENCE); if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, entry); if (ret) hdb_free_entry(context,entry); } } return ret; }