You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从已加入域的Ubuntu 16.04程序化获取NTFS文件共享权限?

程序化获取NTFS文件共享权限的实现方案(Python优先)

根据你的场景——域环境里有Windows Server 2014+的NTFS共享,且Ubuntu 16.04已加入域、能识别AD用户组、域用户可登录——我整理了几种优先Python的实现方案,还有其他备选方法,你可以按需选择:

Python 实现方案

方法1:调用Samba系统工具smbcacls解析输出

Ubuntu已加入域,域用户登录后可直接用smbcacls访问共享并读取ACL信息,Python通过subprocess调用该命令后解析输出即可。

步骤:

  1. 先确保安装samba-client:
sudo apt-get install samba-client -y
  1. 编写Python脚本:
import subprocess
import re

def get_ntfs_share_permissions(share_path, domain_user=None):
    # share_path格式://<服务器名>/<共享文件夹>
    cmd_args = ["smbcacls", share_path]
    if domain_user:
        # 指定域用户,格式:domain\username
        cmd_args.extend(["-U", domain_user])
    
    try:
        # 执行命令并捕获输出
        result = subprocess.run(
            cmd_args,
            capture_output=True,
            text=True,
            check=True
        )
        output_lines = result.stdout.splitlines()
        permission_list = []
        
        # 正则匹配解析ACL行,跳过REVISION和CONTROL开头的配置行
        acl_pattern = re.compile(r'^(\S+)\s+(\S+)\s+(\S+)\s+(.*)$')
        for line in output_lines:
            if line.startswith(('REVISION', 'CONTROL')):
                continue
            match = acl_pattern.match(line)
            if match:
                sid, perm_type, perm_value, identity_name = match.groups()
                permission_list.append({
                    'sid': sid,
                    'identity': identity_name.strip(),
                    'permission_type': perm_type,  # ALLOWED/DENIED
                    'permission_value': perm_value
                })
        return permission_list
    except subprocess.CalledProcessError as e:
        print(f"获取权限失败:{e.stderr.strip()}")
        return None

# 调用示例
target_share = "//dc01/company_files"
permissions = get_ntfs_share_permissions(target_share)
if permissions:
    for perm in permissions:
        print(f"主体: {perm['identity']} | 权限类型: {perm['permission_type']} | 权限值: {perm['permission_value']}")

说明:脚本会自动过滤配置行,提取用户/组、权限类型和权限值;如果当前登录用户无访问权限,可通过domain_user参数指定有权限的域账号。

方法2:用纯Python库pysmb直接操作SMB共享

pysmb是纯Python实现的SMB/CIFS客户端库,无需依赖系统Samba工具,直接在Python中建立SMB连接并读取ACL。

步骤:

  1. 安装pysmb:
pip install pysmb
  1. 编写脚本:
from smb.SMBConnection import SMBConnection

def get_smb_share_acl(server_name, share_name, domain, username, password):
    # 初始化SMB连接,启用NTLMv2认证(适配域环境)
    conn = SMBConnection(
        username,
        password,
        local_name='ubuntu_client',  # 本地机器标识
        remote_name=server_name,
        domain=domain,
        use_ntlm_v2=True
    )
    
    # 连接到SMB服务器(默认端口445)
    if not conn.connect(server_name, 445):
        print("SMB共享连接失败")
        return None
    
    try:
        # 获取共享根目录的ACL
        acl_entries = conn.getACL(share_name, '/')
        permission_details = []
        
        for ace in acl_entries:
            # 将SID转换为可读的用户/组名称
            identity_name = conn.getSIDName(ace.sid)
            permission_details.append({
                'sid': ace.sid,
                'identity': identity_name,
                'permission_type': 'ALLOWED' if ace.type == 0x00 else 'DENIED',
                'permission_mask': ace.mask
            })
        return permission_details
    except Exception as e:
        print(f"读取ACL失败:{str(e)}")
        return None
    finally:
        # 关闭连接
        conn.close()

# 调用示例
server = "dc01"
share = "company_files"
domain = "MYCORP"
user = "john.doe"
pwd = "your_password_here"

acl_info = get_smb_share_acl(server, share, domain, user, pwd)
if acl_info:
    for info in acl_info:
        print(f"主体: {info['identity']} | 权限类型: {info['permission_type']} | 权限掩码: {hex(info['permission_mask'])}")

说明:这个方案无需依赖系统工具,更适合跨平台场景;需要提供域用户的账号密码来建立SMB连接,getSIDName方法会自动将SID转换为AD中的用户/组名称(依赖Ubuntu的域解析能力,已加入域的话正常可用)。

其他备选方案

1. Shell脚本直接解析smbcacls输出

如果不需要Python,也可以用Shell脚本快速实现:

# 输出用户/组、权限类型、权限值
smbcacls //dc01/company_files | grep -vE 'REVISION|CONTROL' | awk '{print "主体: "$4" | 权限类型: "$2" | 权限值: "$3}'

适合简单的自动化场景,无需编写复杂代码。

2. LDAP结合SMB权限查询(精准映射AD对象)

如果需要更深入的AD用户/组信息,可以通过LDAP查询将SID映射到AD对象详情,配合SMB权限数据使用。Ubuntu上可以用python-ldap库实现:

import ldap

def get_ad_identity_from_sid(sid, dc_host, domain, username, password):
    ldap_uri = f"ldap://{dc_host}"
    conn = ldap.initialize(ldap_uri)
    conn.set_option(ldap.OPT_REFERRALS, 0)
    # 绑定域用户
    conn.simple_bind_s(f"{domain}\\{username}", password)
    
    # 搜索SID对应的AD对象
    search_base = f"DC={domain.split('.')[0]},DC={domain.split('.')[1]}"
    search_filter = f"(objectSid={sid})"
    result = conn.search_s(
        search_base,
        ldap.SCOPE_SUBTREE,
        search_filter,
        ['name', 'sAMAccountName', 'objectClass']
    )
    
    if result:
        attrs = result[0][1]
        return {
            'name': attrs['name'][0].decode('utf-8'),
            'account': attrs['sAMAccountName'][0].decode('utf-8'),
            'type': '用户' if 'user' in attrs['objectClass'] else '组'
        }
    else:
        return None

这个方法可以和前面的SMB权限获取逻辑结合,实现更完整的权限审计。

内容的提问来源于stack exchange,提问作者okila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:15:36