Samba3在S-1-22-1范围内为用户使用SID,为组使用S-1-22-2。例如,S-1-22-1-1-10042是具有uid 10042的UNIX用户。 我希望能够将这样的SID映射到名称,如'myunixaccount',类似于Windows帐户映射的此功能:
SecurityIdentifier sid = ...; // For instance from FileSystemAccessRule.
name = sid.Translate(typeof(NTAccount)).Value;
Windows本身能够进行此映射,但我似乎无法找到映射算法。
已添加:环境说明
在Convert SID to Username in C#上测试了建议的解决方案。它没有帮助。因此一些额外的环境描述:
piece of ldap.conf
nss_base_passwd=OU=nl,OU=xxx,dc=yyy,dc=local?sub(objectCategory=user)
nss_map_objectclass posixAccount User
nss_map_objectclass shadowAccount User
nss_map_attribute uid sAMAccountName
nss_map_attribute uidNumber uidNumber
nss_map_attribute gidNumber gidNumber
nss_map_attribute cn sAMAccountName
nss_map_attribute uniqueMember member
nss_map_attribute userPassword msSFUPassword
nss_map_attribute homeDirectory unixHomeDirectory
nss_map_attribute loginShell loginShell
nss_map_attribute gecos cn
nss_map_objectclass posixGroup Group
nss_map_attribute shadowLastChange pwdLastSet
UNIX上的交互式登录与Windows身份验证工作正常,dito用于Samba共享。在域上使用PC时,它不会要求凭据。
一些样本,用户gle3(在1中突出显示)也存在于域中但具有不同的SID。这里使用的SID是Samba SID,如S-1-22-1-1-10001。
在(2)中,您可以看到用户存在于使用过的passwd配置中。以下当然不会产生任何结果:grep gle3 /etc/passwd
,因为条目是从远程服务器使用的。远程服务器将gle3的用户SID映射到UNIX uid 10001和默认组10003。
在(3)中,您可以看到默认组不存在,这就是权限无法将其解析为名称的原因。
很明显,Windows以某种方式询问文件服务器:“给我这些SID上的数据”和Samba文件服务器以某种方式响应:好吧,那就是“Unix User \ gle3”和“Unix Group \ 10003”,但我不知道有最后一个的组名。
答案 0 :(得分:1)
前段时间我一直在用这种方法在2000+计算机网络上构建本地局域网爬虫。我很确定你提出的问题不是SMB协议的一部分。您实际上可以看到:如果Windows无法解析凭据,它将在安全属性中显示SID。
基本上发生的是SID是映射到唯一ID的对象ID(如用户名/组)。他们像GUID一样工作。通常PC在SID中进行通信,而不是在用户名中进行通信。
现在,您需要考虑不同类型的SID:
实际上还有很多......证书凭证,保留用户等都是可以用于登录的对象ID - 但我会保持简单。此评论的关键点是,虽然所有用户名都有SID,但并非所有SID都具有用户名。
如果您某处有某个AD(您似乎这样做),则正确的设置包含此处的所有用户。获得完整映射的最简单方法是简单地枚举完整的活动目录。那应该包含所有的映射。基本上就是这样的:
DirectoryEntry root = new DirectoryEntry("LDAP://dc=MyCompany,dc=com");
DirectorySearcher search = new DirectorySearcher(root);
search.Filter = "(objectCategory=Person)";
search.SearchScope = SearchScope.Subtree;
search.PropertiesToLoad.Add("objectSid");
search.PropertiesToLoad.Add("displayName");
foreach(SearchResult result in search.FindAll())
{
// grab the data - if present
if(result.Properties["objectSid"] != null && result.Properties["objectSid"].Count > 1)
{
var sid = result.Properties["objectSid"][0];
}
if(result.Properties["displayName"] != null && result.Properties["displayName"].Count > 0)
{
var userName = result.Properties["displayName"][0].ToString();
}
}