Это была невероятно нетривиальная задача, и, к сожалению, ответ не такой простой, как я надеялся ...
Я отправляю этот ответ, если кто-то застрянет с той же проблемой в в будущем, но надеюсь, что, может быть, кто-то опубликует лучшее решение раньше
Чтобы найти владельца, я использовал эту библиотеку с ее примерами :
from smb.SMBConnection import SMBConnection
conn = SMBConnection(username='<username>', password='<password>', domain=<domain>', my_name='<some pc name>', remote_name='<server name>')
conn.connect('<server name>')
sec_att = conn.getSecurity('<share name>', r'\some\file\path')
owner_sid = sec_att.owner
Проблема в этот пакет pysmb
даст вам только SID владельца, а не его имя.
Чтобы узнать его имя, вам нужно сделать запрос ldap, как в этом ответе (повторная публикация кода):
from ldap3 import Server, Connection, ALL
from ldap3.utils.conv import escape_bytes
s = Server('my_server', get_info=ALL)
c = Connection(s, 'my_user', 'my_password')
c.bind()
binary_sid = b'....' # your sid must be in binary format
c.search('my_base', '(objectsid=' + escape_bytes(binary_sid) + ')', attributes=['objectsid', 'samaccountname'])
print(c.entries)
Но, конечно, ничего не будет легко, мне потребовались часы, чтобы найти способ преобразовать строковый SID в двоичный SID в python, , и в конце концов это решило проблему :
# posting the needed functions and omitting the class part
def byte(strsid):
'''
Convert a SID into bytes
strdsid - SID to convert into bytes
'''
sid = str.split(strsid, '-')
ret = bytearray()
sid.remove('S')
for i in range(len(sid)):
sid[i] = int(sid[i])
sid.insert(1, len(sid)-2)
ret += longToByte(sid[0], size=1)
ret += longToByte(sid[1], size=1)
ret += longToByte(sid[2], False, 6)
for i in range(3, len(sid)):
ret += cls.longToByte(sid[i])
return ret
def byteToLong(byte, little_endian=True):
'''
Convert bytes into a Python integer
byte - bytes to convert
little_endian - True (default) or False for little or big endian
'''
if len(byte) > 8:
raise Exception('Bytes too long. Needs to be <= 8 or 64bit')
else:
if little_endian:
a = byte.ljust(8, b'\x00')
return struct.unpack('<q', a)[0]
else:
a = byte.rjust(8, b'\x00')
return struct.unpack('>q', a)[0]
... И, наконец, у вас есть полное решение! наслаждайтесь: (