【问题标题】:pysmb from linux to Windows, Unable to connect to shared devicepysmb 从 linux 到 Windows,无法连接到共享设备
【发布时间】:2020-10-09 05:26:34
【问题描述】:

尝试通过pysmb 连接到 smb 共享并出现错误...

smb.smb_structs.OperationFailure: Failed to list  on \\\\H021BSBD20\\shared_folder: Unable to connect to shared device

我使用的代码看起来像...

from smb.SMBConnection import SMBConnection
import json
import pprint
import warnings

pp = pprint.PrettyPrinter(indent=4)
PROJECT_HOME = "/path/to/my/project/"

# load configs
CONF = json.load(open(f"{PROJECT_HOME}/configs/configs.json"))
pp.pprint(CONF)

# list all files in storage smb dir
#https://pysmb.readthedocs.io/en/latest/api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath
IS_DIRECT_TCP = False
CNXN_PORT = 139 if not IS_DIRECT_TCP else 445
LOCAL_IP = "172.18.4.69"
REMOTE_NAME = "H021BSBD20"  # exact name shown as Device Name in System Settings
SERVICE_NAME = "\\\\H021BSBD20\\shared_folder"
REMOTE_IP = "172.18.7.102"
try:
    conn = SMBConnection(CONF['smb_creds']['username'], CONF['smb_creds']['password'],
                         my_name=LOCAL_IP, remote_name=REMOTE_NAME,
                         use_ntlm_v2=True,
                         is_direct_tcp=IS_DIRECT_TCP)
    conn.connect(REMOTE_IP, CNXN_PORT)
except Exception:
    warnings.warn("\n\nFailed to initially connect, attempting again with param use_ntlm_v2=False\n\n")
    conn = SMBConnection(CONF['smb_creds']['username'], CONF['smb_creds']['password'],
                         my_name=LOCAL_IP, remote_name=REMOTE_NAME,
                         use_ntlm_v2=False,
                         is_direct_tcp=IS_DIRECT_TCP)
    conn.connect(REMOTE_IP, CNXN_PORT)

files = conn.listPath(f'{SERVICE_NAME}', '\\')
pp.pprint(files)

在我的机器上使用smbclient,我可以通过以下操作成功连接到共享...

[root@airflowetl etl]# smbclient -U my_user \\\\H021BSBD20\\shared_folder

我在 python 代码中使用的反斜杠数量是为了创建与使用 smbclient 时相同的字符串(已尝试在代码中使用较少的反斜杠,但没有帮助)。

请注意,我在 python 代码中使用访问共享文件夹并使用smbclient 的用户无法访问/登录到托管共享的实际机器(他们只被允许访问如上所示的特定共享文件夹)。

有人知道这里会发生什么吗?还有其他可以完成的调试步骤吗?

【问题讨论】:

    标签: python pysmb


    【解决方案1】:

    在 github repo 问题部分 (https://github.com/miketeo/pysmb/issues/169) 询问后,我能够解决问题。这只是由于我用于 conn.listPath() servicename 参数的 arg。

    当仔细查看该函数 (https://pysmb.readthedocs.io/en/latest/api/smb_SMBConnection.html) 的文档时,我看到...

    service_name (string/unicode) – 路径的共享文件夹的名称

    最初,我只查看函数 signature,它表示 service_name,所以我认为它与 smbclient 命令行工具(我一直是将servicename 参数输入为\\\\devicename\\sharename(与pysmb 不同,我们可以从文档字符串中看到,它只需要share 作为服务名称)。

    所以而不是

    files = conn.listPath("\\\\H021BSBD20\\shared_folder", '\\')
    

    我愿意

    files = conn.listPath("shared_folder", '\\')
    

    完整重构的sn-p如下图,仅供参考。

    import argparse
    import json
    import os
    import pprint
    import socket
    import sys
    import traceback
    import warnings
    
    from smb.SMBConnection import SMBConnection
    
    
    def parseArguments():
        # Create argument parser
        parser = argparse.ArgumentParser()
        # Positional mandatory arguments
        parser.add_argument("project_home", help="project home path", type=str)
        parser.add_argument("device_name", help="device (eg. NetBIOS) name in configs of share to process", type=str)
        # Optional arguments
        # parser.add_argument("-dfd", "--data_file_dir",
        #                     help="path to data files dir to be pushed to sink, else source columns based on form_type",
        #                     type=str, default=None)
        # Parse arguments
        args = parser.parse_args()
        return args
    
    
    args = parseArguments()
    for a in args.__dict__:
        print(str(a) + ": " + str(args.__dict__[a]))
    
    pp = pprint.PrettyPrinter(indent=4)
    PROJECT_HOME = args.project_home
    REMOTE_NAME = args.device_name
    
    # load configs
    CONF = json.load(open(f"{PROJECT_HOME}/configs/configs.json"))
    CREDS = json.load(open(f"{PROJECT_HOME}/configs/creds.json"))
    pp.pprint(CONF)
    
    SMB_CONFS = next(info for info in CONF["smb_server_configs"] if info["device_name"] == args.device_name)
    print("\nUsing details for device:")
    pp.pprint(SMB_CONFS)
    
    # list all files in storage smb dir
    #https://pysmb.readthedocs.io/en/latest/api/smb_SMBConnection.html#smb.SMBConnection.SMBConnection.listPath
    IS_DIRECT_TCP = False
    CNXN_PORT = 139 if IS_DIRECT_TCP is False else 445
    LOCAL_IP = socket.gethostname()  #"172.18.4.69"
    REMOTE_NAME = SMB_CONFS["device_name"]
    SHARE_FOLDER = SMB_CONFS["share_folder"]
    REMOTE_IP = socket.gethostbyname(REMOTE_NAME)  # "172.18.7.102"
    print(LOCAL_IP)
    print(REMOTE_NAME)
    try:
        conn = SMBConnection(CREDS['smb_creds']['username'], CREDS['smb_creds']['password'],
                             my_name=LOCAL_IP, remote_name=REMOTE_NAME,
                             use_ntlm_v2=False,
                             is_direct_tcp=IS_DIRECT_TCP)
        conn.connect(REMOTE_IP, CNXN_PORT)
    except Exception:
        traceback.print_exc()
        warnings.warn("\n\nFailed to initially connect, attempting again with param use_ntlm_v2=True\n\n")
        conn = SMBConnection(CREDS['smb_creds']['username'], CREDS['smb_creds']['password'],
                             my_name=LOCAL_IP, remote_name=REMOTE_NAME,
                             use_ntlm_v2=True,
                             is_direct_tcp=IS_DIRECT_TCP)
        conn.connect(REMOTE_IP, CNXN_PORT)
    
    files = conn.listPath(SHARE_FOLDER, '\\')
    if len(files) > 0:
        print("Found listed files")
        for f in files:
            print(f.filename)
    else:
        print("No files to list, this likely indicates a problem. Exiting...")
        exit(255)
    

    【讨论】:

      猜你喜欢
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 2012-08-18
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      相关资源
      最近更新 更多