Skip to content

Commit 0966001

Browse files
committed
More changes
1 parent d5b7986 commit 0966001

File tree

12 files changed

+887
-409
lines changed

12 files changed

+887
-409
lines changed

dissect/database/ese/cursor.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import TYPE_CHECKING
44

55
from dissect.database.ese.btree import BTree
6-
from dissect.database.ese.exception import NoNeighbourPageError
6+
from dissect.database.ese.exception import KeyNotFoundError, NoNeighbourPageError
77
from dissect.database.ese.record import Record
88

99
if TYPE_CHECKING:
@@ -64,7 +64,28 @@ def reset(self) -> None:
6464
if self._secondary:
6565
self._secondary.reset()
6666

67-
def search(self, **kwargs: RecordValue) -> Record:
67+
def make_key(self, *args: RecordValue, **kwargs: RecordValue) -> bytes:
68+
"""Generate a key for this index from the given values.
69+
70+
Args:
71+
*args: The values to generate a key for.
72+
**kwargs: The columns and values to generate a key for.
73+
74+
Returns:
75+
The generated key as bytes.
76+
"""
77+
if not args and not kwargs:
78+
raise ValueError("At least one value must be provided")
79+
80+
if args and kwargs:
81+
raise ValueError("Cannot mix positional and keyword arguments in make_key")
82+
83+
if args and not len(args) == 1 and not isinstance(args[0], list):
84+
raise ValueError("When using positional arguments, provide a single list of values")
85+
86+
return self.index.make_key(args[0] if args else kwargs)
87+
88+
def search(self, *args: RecordValue, **kwargs: RecordValue) -> Record:
6889
"""Search the index for the requested values.
6990
7091
Searching modifies the cursor state. Searching again will search from the current position.
@@ -76,7 +97,7 @@ def search(self, **kwargs: RecordValue) -> Record:
7697
Returns:
7798
A :class:`~dissect.database.ese.record.Record` object of the found record.
7899
"""
79-
key = self.index.make_key(kwargs)
100+
key = self.make_key(*args, **kwargs)
80101
return self.search_key(key, exact=True)
81102

82103
def search_key(self, key: bytes, exact: bool = True) -> Record:
@@ -90,13 +111,13 @@ def search_key(self, key: bytes, exact: bool = True) -> Record:
90111
self._primary.search(key, exact)
91112
return self._record()
92113

93-
def seek(self, **kwargs: RecordValue) -> None:
114+
def seek(self, *args: RecordValue, **kwargs: RecordValue) -> None:
94115
"""Seek to the record with the given values.
95116
96117
Args:
97118
**kwargs: The columns and values to seek to.
98119
"""
99-
key = self.index.make_key(kwargs)
120+
key = self.make_key(*args, **kwargs)
100121
self.search_key(key, exact=False)
101122

102123
def seek_key(self, key: bytes) -> None:
@@ -130,7 +151,10 @@ def find_all(self, **kwargs: RecordValue) -> Iterator[Record]:
130151
other_columns = kwargs
131152

132153
# We need at least an exact match on the indexed columns
133-
self.search(**indexed_columns)
154+
try:
155+
self.search(**indexed_columns)
156+
except KeyNotFoundError:
157+
return
134158

135159
current_key = self._primary.node().key
136160

dissect/database/ese/ese.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ def __init__(self, fh: BinaryIO, impacket_compat: bool = False):
3636
self.fh = fh
3737
self.impacket_compat = impacket_compat
3838

39+
self.fh.seek(0)
3940
self.header = c_ese.DBFILEHDR(fh)
4041
if self.header.ulMagic != ulDAEMagic:
4142
raise InvalidDatabase("invalid file header signature")

dissect/database/ese/index.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,20 +105,27 @@ def key_from_record(self, record: Record) -> bytes:
105105
values = {c.name: record[c.name] for c in self.columns}
106106
return self.make_key(values)
107107

108-
def make_key(self, values: dict[str, RecordValue]) -> bytes:
108+
def make_key(self, values: list[RecordValue] | dict[str, RecordValue]) -> bytes:
109109
"""Generate a key out of the given values.
110110
111111
Args:
112-
values: A map of the column names and values to generate a key for.
112+
values: A map of the column names and values to generate a key for, or a list of values in the order of the
113+
index columns.
113114
"""
114115
key_buf = []
115116
key_remaining = self._key_most
116117

117-
for column in self.columns:
118-
if column.name not in values:
119-
break
118+
if isinstance(values, dict):
119+
tmp = []
120+
for column in self.columns:
121+
if column.name not in values:
122+
break
123+
tmp.append(values[column.name])
124+
125+
values = tmp
120126

121-
key_part = encode_key(self, column, values[column.name], self._var_seg_mac)
127+
for column, value in zip(self.columns, values, strict=False):
128+
key_part = encode_key(self, column, value, self._var_seg_mac)
122129
key_buf.append(key_part)
123130
key_remaining -= len(key_part)
124131

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from __future__ import annotations
22

33
from dissect.database.ese.ntds.ntds import NTDS
4-
from dissect.database.ese.ntds.object import Computer, Group, Server, User
4+
from dissect.database.ese.ntds.object import Computer, Group, Object, Server, User
55

66
__all__ = [
77
"NTDS",
88
"Computer",
99
"Group",
10+
"Object",
1011
"Server",
1112
"User",
1213
]

0 commit comments

Comments
 (0)