在 Java 中获取 SMB 共享文件的名称和权限



我想连接到SMB服务器并浏览其文件,并且对于给定的路径,以便能够检索具有名称和权限的文件和文件夹列表。

我需要支持所有 SMB 方言,并且能够从我的代码中做到这一点。

代码大致如下:

smbClient.connect(serverInfo);
info = smbClient.getShare(shareName);
for(File file : info.getFiles) {
    List<permission> permissions = file.getPermissions();
    //do something
}

我已经尝试了一些选项,例如smbj,impacket,nmap,samba,但它们似乎都不能满足我上面的要求。

有没有办法实现上述目标,使用 Java、Python 或任何我可以从我的 Java 代码调用的 linux CLI?

我想它可以帮助你改进jcifs-ng。

**// Option 1 - SMB2 and SMB3:**
Properties prop = new Properties();
prop.put( "jcifs.smb.client.enableSMB2", "true");
prop.put( "jcifs.smb.client.disableSMB1", "false");
prop.put( "jcifs.traceResources", "true" );
Configuration config = new PropertyConfiguration(prop);
CIFSContext baseContext = new BaseContext(config);
CIFSContext contextWithCred = baseContext.withCredentials(new NtlmPasswordAuthentication(baseContext, domain, fileSystemInfo.getUsername(), fileSystemInfo.getPassword()));
SmbFile share = new SmbFile(fullPath.replace('', '/'), contextWithCred);
if (!share.exists())
{
    share.mkdirs();
}
share.close();

选项 2 - SMB1 和 CIFS:

SingletonContext context = SingletonContext.getInstance();
CIFSContext testCtx = context.withCredentials(
    new NtlmPasswordAuthentication(
        context, domain, fileSystemInfo.getUsername(), fileSystemInfo.getPassword()
    )
);
SmbFile smbFile = new SmbFile(fullPath.replace('', '/'), testCtx);
if (!smbFile.exists())
{
    smbFile.mkdirs();
}
smbFile.close();

我认为没有任何开源Java库可以支持您所需的一切。

有一个非开源库,叫做jNQ,由"Visuality Systems"提供。

此库支持所有 SMB 方言(SMB1 到 SMB3.1.1(

在链接中有一个用于浏览的代码示例(您可以获取列表中每个文件的安全描述符(:

PasswordCredentials cr = new PasswordCredentials("userName", "password", "domain");
Mount mt = new Mount("IpAddress","ShareName", cr);
Directory dir = new Directory(mt, "dir1");
Directory.Entry entry;
System.out.println(DIR + " scan:");
do {
    entry = dir.next();
    if (null != entry)
        System.out.println(entry.name + " : size = " + entry.info.eof);
} while (entry != null);

我们遇到了同样的问题,并发现 jcifs-ng 使用 java 可以最好地满足我们的要求(我们只在 v1 和 v2 上测试了它,但最新版本也对 v3 有一些支持(。您的代码如下所示:

Configuration config = new PropertyConfiguration(new Properties());
CIFSContext context = new BaseContext(config);
context = context.withCredentials(new NtlmPasswordAuthentication(null, domain, userName, password));
String share = "smb://HOSTNAME/SHARENAME/";
try (SmbFile share = new SmbFile(url, context)) {
    for (SmbFile file : share.listFiles()) {
        ACE[] groups = file.getSecurity();
        // Do something..
    }
}

其中 ACE 是访问控制项,它是控制或监视对对象的访问(简称权限(的元素。

请注意,最新版本可能尚未在 Maven 或 Gradle 上发布,因此您必须克隆存储库并自行构建它。

如果您运行的是Windows,并且运行该程序的用户有权访问共享,则可以使用java.nio来执行此操作。Java.nio 允许您访问 SMB 共享。

Path path = Paths.get(<SharedFile>);
AclFileAttributeView aclAttribute = Files.getFileAttributeView(path, AclFileAttributeView.class);

然后,可以使用aclAttribute.getAcls();获取用户及其权限。

最新更新