Skip to content

Commit f51339f

Browse files
committed
Fix deduplication of collected files on case insensitive targets
(DIS-2945)
1 parent 7e98198 commit f51339f

File tree

4 files changed

+49
-24
lines changed

4 files changed

+49
-24
lines changed

acquire/acquire.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,11 @@
9999

100100
def misc_windows_user_homes(target: Target) -> Iterator[fsutil.TargetPath]:
101101
misc_dirs = {
102-
("windows/serviceprofiles/localservice", False),
103-
("windows/serviceprofiles/networkservice", False),
104-
("windows/system32/config/systemprofile", False),
105-
("users", True),
106-
("documents and settings", True),
102+
("Windows/ServiceProfiles/LocalService", False),
103+
("Windows/ServiceProfiles/NetworkService", False),
104+
("Windows/System32/config/systemprofile", False),
105+
("Users", True),
106+
("Documents and Settings", True),
107107
}
108108

109109
for fs in target.fs.path().iterdir():
@@ -146,7 +146,7 @@ def misc_osx_user_homes(target: Target) -> Iterator[fsutil.TargetPath]:
146146
def from_user_home(target: Target, path: str) -> Iterator[str]:
147147
try:
148148
for user_details in target.user_details.all_with_home():
149-
yield normalize_path(target, user_details.home_path.joinpath(path))
149+
yield normalize_path(target, user_details.home_path.joinpath(path), lower_case=False)
150150
except Exception as e:
151151
log.warning("Error occurred when requesting all user homes")
152152
log.debug("", exc_info=e)

acquire/collector.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,14 @@ def serialize_path(path: Any) -> str:
7474

7575
# Naive way to serialize TargetPath filesystem's metadata is
7676
# to rely on uniqueness of `path._fs` object
77-
fs_id = id(path._fs)
78-
return f"{path._fs.__type__}:{fs_id}:{path}"
77+
fs = path._fs
78+
fs_id = id(fs)
79+
fs_type = fs.__type__
80+
path = str(path)
81+
if not fs.case_sensitive:
82+
path = path.lower()
83+
84+
return f"{fs_type}:{fs_id}:{path}"
7985

8086

8187
@dataclass

acquire/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,13 @@ def persist_execution_report(path: Path, report_data: dict) -> Path:
371371
SYSVOL_SUBST = re.compile(r"^(/\?\?/)?[cC]:")
372372

373373

374-
def normalize_path(target: Target, path: Path, resolve: bool = False) -> str:
374+
def normalize_path(target: Target, path: Path, resolve: bool = False, lower_case: bool = True) -> str:
375375
if resolve:
376376
path = path.resolve()
377377

378378
path = path.as_posix()
379379

380-
if not target.fs.case_sensitive:
380+
if not target.fs.case_sensitive and lower_case:
381381
path = path.lower()
382382

383383
if target.os == "windows":

tests/test_utils.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -296,94 +296,113 @@ def test_check_and_set_acquire_args_cagent():
296296

297297

298298
@pytest.mark.parametrize(
299-
"path, resolve, norm_path, case_sensitive, os",
299+
"path, resolve, lower_case, case_sensitive, os, result",
300300
[
301301
(
302302
pathlib.Path("/foo/bar"),
303303
False,
304-
"/foo/bar",
304+
True,
305305
True,
306306
"dummy",
307+
"/foo/bar",
307308
),
308309
(
309310
pathlib.Path("/foo/BAR"),
310311
False,
311-
"/foo/bar",
312+
True,
312313
False,
313314
"dummy",
315+
"/foo/bar",
314316
),
315317
(
316318
pathlib.Path("/foo/BAR"),
317319
False,
318-
"/foo/BAR",
320+
True,
319321
True,
320322
"dummy",
323+
"/foo/BAR",
321324
),
322325
(
323326
pathlib.Path("/foo/../bar"),
324327
False,
325-
"/foo/../bar",
328+
True,
326329
True,
327330
"dummy",
331+
"/foo/../bar",
328332
),
329333
(
330334
pathlib.Path("/foo/../foo/bar"),
331335
True,
332-
"/foo/bar",
336+
True,
333337
True,
334338
"dummy",
339+
"/foo/bar",
335340
),
336341
(
337342
pathlib.PureWindowsPath("c:\\foo\\bar"),
338343
False,
339-
"sysvol/foo/bar",
344+
True,
340345
False,
341346
"windows",
347+
"sysvol/foo/bar",
342348
),
343349
(
344350
pathlib.PureWindowsPath("C:\\foo\\bar"),
345351
False,
346-
"sysvol/foo/bar",
352+
True,
347353
False,
348354
"windows",
355+
"sysvol/foo/bar",
349356
),
350357
(
351358
pathlib.PureWindowsPath("\\??\\C:\\foo\\bar"),
352359
False,
353-
"sysvol/foo/bar",
360+
True,
354361
False,
355362
"windows",
363+
"sysvol/foo/bar",
356364
),
357365
(
358366
pathlib.PureWindowsPath("\\??\\c:\\foo\\bar"),
359367
False,
360-
"sysvol/foo/bar",
368+
True,
361369
False,
362370
"windows",
371+
"sysvol/foo/bar",
363372
),
364373
(
365374
pathlib.PureWindowsPath("D:\\foo\\bar"),
366375
False,
376+
True,
377+
False,
378+
"windows",
367379
"d:/foo/bar",
380+
),
381+
(
382+
pathlib.PureWindowsPath("D:\\Foo\\BAR"),
383+
False,
384+
False,
368385
False,
369386
"windows",
387+
"D:/Foo/BAR",
370388
),
371389
],
372390
)
373391
def test_utils_normalize_path(
374392
mock_target: Target,
375393
path: pathlib.Path,
376394
resolve: bool,
377-
norm_path: str,
395+
lower_case: bool,
378396
case_sensitive: bool,
379397
os: str,
398+
result: str,
380399
) -> None:
381400
with patch.object(mock_target, "os", new=os), patch.object(mock_target.fs, "_case_sensitive", new=case_sensitive):
382-
resolved_path = normalize_path(mock_target, path, resolve=resolve)
401+
resolved_path = normalize_path(mock_target, path, resolve=resolve, lower_case=lower_case)
383402

384403
if platform.system() == "Windows":
385404
# A resolved path on windows adds a C:\ prefix. So we check if it ends with our expected
386405
# path string
387-
assert resolved_path.endswith(norm_path)
406+
assert resolved_path.endswith(result)
388407
else:
389-
assert resolved_path == norm_path
408+
assert resolved_path == result

0 commit comments

Comments
 (0)