Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
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;
}
Пример #8
0
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;
}