从objectSid转换为SID表示的Python代码
我想从LDAP查询检索base64编码的objectSid到Active Directory数据库,并将其转换为标准SID表示形式。你能给我一个这样做的Python代码片段吗?这应该可以做到:从objectSid转换为SID表示的Python代码,python,active-directory,Python,Active Directory,我想从LDAP查询检索base64编码的objectSid到Active Directory数据库,并将其转换为标准SID表示形式。你能给我一个这样做的Python代码片段吗?这应该可以做到: import struct def convert(binary): version = struct.unpack('B', binary[0])[0] # I do not know how to treat version != 1 (it does not exist yet)
import struct
def convert(binary):
version = struct.unpack('B', binary[0])[0]
# I do not know how to treat version != 1 (it does not exist yet)
assert version == 1, version
length = struct.unpack('B', binary[1])[0]
authority = struct.unpack('>Q', '\x00\x00' + binary[2:8])[0]
string = 'S-%d-%d' % (version, authority)
binary = binary[8:]
assert len(binary) == 4 * length
for i in xrange(length):
value = struct.unpack('<L', binary[4*i:4*(i+1)])[0]
string += '-%d' % value
return string
导入结构
def转换(二进制):
version=struct.unpack('B',二进制[0])[0]
#我不知道如何对待版本!=1(它还不存在)
断言版本==1,版本
长度=结构解包('B',二进制[1])[0]
authority=struct.unpack('>Q','\x00\x00'+二进制[2:8])[0]
字符串='S-%d-%d'(版本、权限)
二进制=二进制[8:]
断言长度(二进制)==4*长度
对于X范围内的i(长度):
value=struct.unpack(“使用或参见ldap3中的实现
这是@Giovanni Mascellani的答案,适用于Python 3.x:
import struct
def convert(binary):
version = struct.unpack('B', binary[0:1])[0]
# I do not know how to treat version != 1 (it does not exist yet)
assert version == 1, version
length = struct.unpack('B', binary[1:2])[0]
authority = struct.unpack(b'>Q', b'\x00\x00' + binary[2:8])[0]
string = 'S-%d-%d' % (version, authority)
binary = binary[8:]
assert len(binary) == 4 * length
for i in range(length):
value = struct.unpack('<L', binary[4*i:4*(i+1)])[0]
string += '-%d' % value
return string
导入结构
def转换(二进制):
version=struct.unpack('B',二进制[0:1])[0]
#我不知道如何处理版本!=1(它还不存在)
断言版本==1,版本
长度=结构解包('B',二进制[1:2])[0]
authority=struct.unpack(b'>Q',b'\x00\x00'+二进制[2:8])[0]
字符串='S-%d-%d'(版本、权限)
二进制=二进制[8:]
断言长度(二进制)==4*长度
对于范围内的i(长度):
value=struct.unpack(“S-1-5-21-2562418665-3218585558-1813906818-1576格式的SID
具有以下十六进制原始格式:010500000000000515000E967BB98D6B7D7BF82051E6C28060000
,可以分解如下:
S
:这意味着这是一个objectSid
01
:(1)是修订版吗?据我所知,ans始终是1
05
:分支机构的计数,或者您可以简单地说,破折号计数减去2
000000000005
:(5)大端
15000000
:(21)小尾端
e967bb98
:(2562418665)小尾端
d6b7d7bf
:(3218585558)小尾端
82051e6c
:(1813906818)小尾端
28060000
:(1576)小尾端
应以相反的顺序读取Small-endian。这就是二进制数据的表示方式,其中最低有效字节首先存储。
因此,Big-endian是最高有效字节首先存储的顺序。这是一篇解释字节顺序的好文章
这是一篇关于ObjeCId结构的简要介绍,也是一篇不错的博客文章
根据这些信息,让我们尝试读取SID,该SID作为二进制文件从LDAP查询返回。binascii
库可用于Python 2和Python 3:
from binascii import b2a_hex
def sid_to_str(sid):
try:
# Python 3
if str is not bytes:
# revision
revision = int(sid[0])
# count of sub authorities
sub_authorities = int(sid[1])
# big endian
identifier_authority = int.from_bytes(sid[2:8], byteorder='big')
# If true then it is represented in hex
if identifier_authority >= 2 ** 32:
identifier_authority = hex(identifier_authority)
# loop over the count of small endians
sub_authority = '-' + '-'.join([str(int.from_bytes(sid[8 + (i * 4): 12 + (i * 4)], byteorder='little')) for i in range(sub_authorities)])
# Python 2
else:
revision = int(b2a_hex(sid[0]))
sub_authorities = int(b2a_hex(sid[1]))
identifier_authority = int(b2a_hex(sid[2:8]), 16)
if identifier_authority >= 2 ** 32:
identifier_authority = hex(identifier_authority)
sub_authority = '-' + '-'.join([str(int(b2a_hex(sid[11 + (i * 4): 7 + (i * 4): -1]), 16)) for i in range(sub_authorities)])
objectSid = 'S-' + str(revision) + '-' + str(identifier_authority) + sub_authority
return objectSid
except Exception:
pass
return sid
sid = b'\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xe9\x67\xbb\x98\xd6\xb7\xd7\xbf\x82\x05\x1e\x6c\x28\x06\x00\x00'
print(sid_to_str(sid)) # S-1-5-21-2562418665-3218585558-1813906818-1576
如果您使用Linux并安装了Samba:
from samba.dcerpc import security
from samba.ndr import ndr_unpack
def convert(binary_sid):
return str(ndr_unpack(security.dom_sid, binary_sid))
其中binary\u sid
是sid的二进制表示形式。我在源代码中找不到它,但是否有一个格式化程序可以做相反的事情?(将格式化字符串转换为原始二进制)@kakigadol来自win32security import ConvertStringSidToSid
问题是,在我的例子中,我运行的是一台linux服务器,它无法安装PyWin32。最后我发现了这段代码,我复制了它的一些功能:我想如果安装Samba,这也可以在Windows上运行,当然也可以在MacOS上运行。
from samba.dcerpc import security
from samba.ndr import ndr_unpack
def convert(binary_sid):
return str(ndr_unpack(security.dom_sid, binary_sid))