-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
smbclient.liststreams
to enumerate ADS streams (#294)
- Loading branch information
Showing
3 changed files
with
48 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
getxattr, | ||
link, | ||
listdir, | ||
liststreams, | ||
listxattr, | ||
lstat, | ||
makedirs, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
# Copyright: (c) 2019, Jordan Borean (@jborean93) <[email protected]> | ||
# MIT License (see LICENSE or https://opensource.org/licenses/MIT) | ||
|
||
from __future__ import annotations | ||
|
||
import collections | ||
import datetime | ||
import errno | ||
|
@@ -37,6 +39,7 @@ | |
FileLinkInformation, | ||
FileRenameInformation, | ||
FileStandardInformation, | ||
FileStreamInformation, | ||
) | ||
from smbprotocol.header import NtStatus | ||
from smbprotocol.ioctl import ( | ||
|
@@ -102,6 +105,12 @@ | |
) | ||
|
||
|
||
class SMBFileStreamInformation(t.NamedTuple): | ||
name: str | ||
size: int | ||
allocation_size: int | ||
|
||
|
||
def is_remote_path(path: str) -> bool: | ||
""" | ||
Returns True iff the given path is a remote SMB path (rather than a local path). | ||
|
@@ -1019,6 +1028,43 @@ def setxattr(path, attribute, value, flags=0, follow_symlinks=True, **kwargs): | |
set_info(transaction, ea_info) | ||
|
||
|
||
def liststreams(path: str, follow_symlinks=True, **kwargs: t.Any) -> list[SMBFileStreamInformation]: | ||
""" | ||
Return a list of the alternative data streams on a path. Listed streams can | ||
be opened by appending their name to the original path. An example call for | ||
a file with a single extra stream may return: | ||
``` | ||
[ | ||
SMBFileStreamInformation(name=':extra_stream:$DATA', size=8, allocation_size=8), | ||
SMBFileStreamInformation(name='::$DATA', size=103472, allocation_size=131072), | ||
] | ||
``` | ||
:param path: The full UNC path to the file to get the list of streams for. | ||
:param follow_symlinks: Whether to follow the symlink at path if encountered. | ||
:param kwargs: Common SMB Session arguments for smbclient. | ||
:return: List of streams on the file with each entry being a string. | ||
""" | ||
|
||
raw = SMBRawIO( | ||
path, | ||
desired_access=FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES, | ||
create_options=0 if follow_symlinks else CreateOptions.FILE_OPEN_REPARSE_POINT, | ||
**kwargs, | ||
) | ||
|
||
with SMBFileTransaction(raw) as transaction: | ||
query_info(transaction, FileStreamInformation, output_buffer_length=MAX_PAYLOAD_SIZE) | ||
|
||
return [ | ||
SMBFileStreamInformation( | ||
s["stream_name"].get_value(), s["stream_size"].get_value(), s["stream_allocation_size"].get_value() | ||
) | ||
for s in transaction.results[0] | ||
] | ||
|
||
|
||
def _delete(raw_type, path, **kwargs): | ||
# Ensures we delete the symlink (if present) and don't follow it down. | ||
co = CreateOptions.FILE_OPEN_REPARSE_POINT | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters