Closed prathishpkr closed 8 months ago
@prathishpkr Yes, pysmb can be used to copy file between Windows and Linux Samba service. However, there are issues with your code snippet. Please refer to https://pysmb.readthedocs.io/en/latest/api/smb_SMBConnection.html for an example on how the perform the copy operation.
@miketeo, i have tried to upload the file from local to Samba server using storeFile method, there am getting the below issues
NFO:SMB.SMBConnection:Authentication with remote machine "IP address" for user "osboxes" will be using NTLM v2 authentication (with extended security)
Traceback (most recent call last):
File "w:/FIM_C_src/FIM-C-master/FIM-C-master/fim/Loc_SMB.py", line 50, in
smb.smb_structs.ProtocolError: Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS
==================== SMB Message ====================
Command: 0x72 (SMB_COM_NEGOTIATE)
Status: NTSTATUS=0x00000000
Flags: 0x88
Flags2: 0xC003
PID: 26092
UID: 0
MID: 1
TID: 0
Security: 0x0000000000000000
Parameters: 2 bytes
b'ffff'
Data: 0 bytes
b''
==================== SMB Data Packet (hex) ====================
b'ff534d4272000000008803c00000000000000000000000000000ec650000010001ffff0000',
@prathishpkr try to modify the smb.conf on the Samba service, and restart your Samba service.
client min protocol = SMB2
client max protocol = SMB3
More information at https://www.cyberciti.biz/faq/how-to-configure-samba-to-use-smbv2-and-disable-smbv1-on-linux-or-unix/
@miketeo, could you please assist me for test file for this below code, do we want to define the function 2 times for connection for SMB2 and SMB, cause below code am not able to upload the files and also large amount of data will support to transfer storefile ?
class SMBNetworkShare(): SMBDetails(hardcoded) -> declared as Glo variable.
def __init__(self, smbServerAddress, smbport, conn, smbUser, smbPassword, smbShareName, smbClientName, smbDestFolder, smbSourceFolder, smbretSourceFolder, smbretDestFolder) -> None:
self.smbServerAddress = smbServerAddress
self.smbShareName = smbShareName
self.smbClientName = smbClientName
self.smbUser = smbUser
self.smbport = smbport
self.password = smbPassword
self.conn = conn
self.smbDestFolder = smbDestFolder
self.smbSourceFolder = smbSourceFolder
# self.smbretSourceFolder = smbretSourceFolder
# self.smbretDestFolder = smbDestFolder
# self.directory_was_online = True
# SMB Connect to Samba server
def __open_connection(self) -> None:
logger = logging.getLogger("SMBNetworkShare")
try:
self.conn = SMBConnection(self.smbServerAddress, self.smbport, self.smbUser,
self.smbPassword, self.smbClientName, use_ntlm_v2=True, is_direct_tcp=True)
self.conn.connect(self.smbServerAddress, 445)
except Exception as ex:
logger.error('Failed to connect smb server "(' +
self.smbServerAddress + '":' + str(ex))
def local_dir_list(self, dir: str): # Local dir
list_dir = []
try:
# SMB_FILE_ATTRIBUTE_ARCHIVE | SMB_FILE_ATTRIBUTE_INCL_NORMAL)
local_dir = os.listdir(dir)
for file_list in local_dir:
file_list.append(list_dir)
except Exception as e:
logging.error("Error occurred while listing files", str(e))
# -> None: #smb_shareName(target_dir)
def copy_to(self, SMBConnection, source_dir: str, target_dir: str, max_attempts=3):
logger = logging.getLogger(SMBConnection)
# self.conn.connect()
try:
source_file_size = os.path.getsize(self.smbSourceFolder)
for attempt in range(1, max_attempts + 1):
try:
fileList = self.local_dir_list(source_dir)
for filename in fileList:
logger.info("File Copying " + filename)
# smbDestFolder, filename)
destPath = os.path.join(
self.smbDestFolder, target_dir, filename)
# (smbSourceFolder, filename)
srcPath = os.path.join(source_dir, filename)
with open(srcPath, 'rb') as f:
# (smbShareName, destPath, f)
self.conn.storeFile(
f, self.smbShareName, destPath, overwrite=True)
# ********for checking successfully******
logger.info(f"File Uploaded ")
destination_file_info = self.conn.query_info(
self.smbDestFolder) # get_attributes(self.smbDestFolder)
destination_file_size = destination_file_info.standard_infromation.endoffile
if source_file_size != destination_file_size:
logger.warning(
f" File {attempt} + filename + Uploaded Successfully, but filesize does not match !!!")
if attempt < max_attempts:
logger.warning(
f"Retrying to upload again after sleep time")
time.sleep(5) # wait for 5ms to retry!!!
else:
logger.info(
f"Filesize are same and uploaded successfully")
else:
# Successfully done
return True
except Exception as ex:
logger.warning(
f"Attempt {attempt} failed: + filename + : + {str(ex)}")
if attempt < max_attempts:
logger.warning(f"Retrying after sleep time")
time.sleep(5) # wait for 5ms to retry!!!
else:
logger.error(
f'Maximum attempts reached, Failed to upload')
finally:
self.conn.disconnect()
if conn == True:
conn.close()
Can you correct the formatting for your code?
@miketeo could you please check above format now, please check and let know.
self.conn = SMBConnection(self.smbServerAddress, self.smbport, self.smbUser, self.smbPassword, self.smbClientName, use_ntlm_v2=True, is_direct_tcp=True)
The parameters to the SMBConnection are incorrect. The order should be userID, password, client_machine_name, server_name, use_ntlm_v2. The server_name must be the remote Samba name, e.g. MYSERVER, or SAMBA. You need to check your Samba configuration or try to use your Windows explorer to browse for the exact name.
It's probably safe to drop support SMB and focus on supporting SMB2 in your app. If your app fails to connect using port 445, try port 139. Sometimes, one of the ports is blocked by firewall.
@miketeo Could you please assist me, have try to find the document of to get the list of files presents in subdirectory/subfolder and the filesize checked for destination location (remote location ), is that support os.walk() which is support for localfile to fetch the list of files details(it should retrieve the files of all file format, including subdirectory/subfolder inside files) and for filesize can we retrieve the information if use the below method
destination_file_info = self.conn.query_info(self.smbDestFolder) # get_attributes(self.smbDestFolder) destination_file_size = destination_file_info.standard_infromation.endoffile.
could you please share the documents, if we use above method.
Copy a file using smb from windows to remote linux and linux to remote windows, is that possible using retrieveFile() or storeFile().
import smbclient from smb.SMBConnection import SMBConnection
def Copy_data_linux_to_windows(source_file, destination_file, username, password, server_ip, share_name): try: conn = SMBConnection(username, password, '', '')
if name == "main": source_file = "/tmp/Copy_dir/Python_Test.zip" destination_file = r"W:\Python_Test.zip"
destination_path ="C:\SMB\Python_Test.zip"