-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsmb.py
More file actions
138 lines (117 loc) · 4.89 KB
/
smb.py
File metadata and controls
138 lines (117 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#! /usr/bin/env python3
# -*- coding: utf-8; py-indent-offset: 4 -*-
#
# Author: Linuxfabrik GmbH, Zurich, Switzerland
# Contact: info (at) linuxfabrik (dot) ch
# https://www.linuxfabrik.ch/
# License: The Unlicense, see LICENSE file.
# https://github.com/Linuxfabrik/monitoring-plugins/blob/main/CONTRIBUTING.rst
"""Provides functions to establish native SMB connections."""
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
__version__ = '2025042001'
import smbclient
import smbprotocol.exceptions
def glob(filename, username, password, timeout, pattern='*', encrypt=True):
"""
List matching files or a single file from an SMB storage device.
Connects to the SMB server and retrieves file entries matching the given pattern.
### Parameters
- **filename** (`str`): Full SMB path to the file or directory.
- **username** (`str`): Username for authentication.
- **password** (`str`): Password for authentication.
- **timeout** (`int`): Connection timeout in seconds.
- **pattern** (`str`, optional): Glob pattern to match files. Default is `'*'`.
- **encrypt** (`bool`, optional): Enable SMB encryption if available. Defaults to `True`.
### Returns
- **tuple** (`bool`, `list` or `str`):
- `True` and a list of file entries if successful.
- `False` and an error message otherwise.
### Notes
- Converts generator from `scandir()` to a list immediately to catch any exceptions early.
### Example
>>> success, files = lib.smb.glob('smb://server/share', 'user', 'pass', timeout=5)
"""
try:
file_entry = smbclient._os.SMBDirEntry.from_path(
filename,
username=username,
password=password,
connection_timeout=timeout,
encrypt=encrypt,
)
if file_entry.is_file():
return True, [file_entry]
files = list(
smbclient.scandir(
filename,
mode='rb',
username=username,
password=password,
connection_timeout=timeout,
search_pattern=pattern,
encrypt=encrypt,
)
)
return True, files
except (
smbprotocol.exceptions.SMBAuthenticationError,
smbprotocol.exceptions.LogonFailure,
):
return False, 'Login failed'
except smbprotocol.exceptions.SMBOSError as e:
context = getattr(e, '__context__', None)
if isinstance(context, smbprotocol.exceptions.ObjectNameNotFound):
return False, 'No such file or directory on the SMB server.'
if e.strerror == 'No such file or directory':
return True, []
return False, f'I/O error "{e.strerror}" while opening or reading {filename}'
except Exception as e:
return False, f'Unknown error opening or reading {filename}:\n{e}'
def open_file(filename, username, password, timeout, encrypt=True):
"""
Retrieve the binary content of a file from an SMB storage device.
This function connects to an SMB server and attempts to open the specified file for reading
in binary mode.
### Parameters
- **filename** (`str`): The full SMB path to the file.
- **username** (`str`): Username for authentication.
- **password** (`str`): Password for authentication.
- **timeout** (`int`): Connection timeout in seconds.
- **encrypt** (`bool`, optional): Enable SMB encryption if available. Defaults to `True`.
### Returns
- **tuple** (`bool`, `object` or `str`):
- `True` and a file descriptor if successful.
- `False` and an error message otherwise.
### Notes
- Wrap the returned file object in a `with` block to ensure it is properly closed.
### Example
>>> with lib.base.coe(lib.smb.open_file(url, args.USERNAME, args.PASSWORD, args.TIMEOUT)) as fd:
>>> result = lib.txt.to_text(fd.read())
"""
try:
file_obj = smbclient.open_file(
filename,
mode='rb',
username=username,
password=password,
connection_timeout=timeout,
encrypt=encrypt,
)
return True, file_obj
except (
smbprotocol.exceptions.SMBAuthenticationError,
smbprotocol.exceptions.LogonFailure,
) as e:
return False, str(e)
except smbprotocol.exceptions.SMBOSError as e:
if isinstance(
getattr(e, '__context__', None), smbprotocol.exceptions.FileIsADirectory
):
return False, 'The file specified is a directory, expected a file.'
if isinstance(
getattr(e, '__context__', None), smbprotocol.exceptions.ObjectNameNotFound
):
return False, 'No such file or directory on the SMB server.'
return False, f'I/O error "{e.strerror}" while opening or reading {filename}'
except Exception as e:
return False, f'Unknown error opening or reading {filename}:\n{e}'