Skip to content

Instantly share code, notes, and snippets.

@schorschii
Last active January 9, 2025 13:43
Show Gist options
  • Save schorschii/0f29db24e7e5ee063c92513ed0aaf097 to your computer and use it in GitHub Desktop.
Save schorschii/0f29db24e7e5ee063c92513ed0aaf097 to your computer and use it in GitHub Desktop.
SSSD's AD objectSID to Linux UID mapping algorithm, implemented in Python
#!/bin/python3
import sys
SSS_IDMAP_DEFAULT_LOWER = 200000
SSS_IDMAP_DEFAULT_UPPER = 2000200000
SSS_IDMAP_DEFAULT_RANGESIZE = 200000
def murmur3_32(data, seed = 0):
c1 = 0xcc9e2d51
c2 = 0x1b873593
length = len(data)
h1 = seed
roundedEnd = (length & 0xfffffffc) # round down to 4 byte block
for i in range(0, roundedEnd, 4):
# little endian load order
k1 = (ord(data[i]) & 0xff) | ((ord(data[i + 1]) & 0xff) << 8) | \
((ord(data[i + 2]) & 0xff) << 16) | (ord(data[i + 3]) << 24)
k1 *= c1
k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15)
k1 *= c2
h1 ^= k1
h1 = (h1 << 13) | ((h1 & 0xffffffff) >> 19) # ROTL32(h1,13)
h1 = h1 * 5 + 0xe6546b64
# tail
k1 = 0
val = length & 0x03
if val == 3:
k1 = (ord(data[roundedEnd + 2]) & 0xff) << 16
# fallthrough
if val in [2, 3]:
k1 |= (ord(data[roundedEnd + 1]) & 0xff) << 8
# fallthrough
if val in [1, 2, 3]:
k1 |= ord(data[roundedEnd]) & 0xff
k1 *= c1
k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15)
k1 *= c2
h1 ^= k1
# finalization
h1 ^= length
# fmix(h1)
h1 ^= ((h1 & 0xffffffff) >> 16)
h1 *= 0x85ebca6b
h1 ^= ((h1 & 0xffffffff) >> 13)
h1 *= 0xc2b2ae35
h1 ^= ((h1 & 0xffffffff) >> 16)
return h1 & 0xffffffff
def main():
if(len(sys.argv) != 2):
print('Usage: '+sys.argv[0]+' <SID>')
print('You can find your user SID by reading the objectSid attribute via LDAP query.')
sys.exit(1)
if(len(sys.argv[1].rsplit('-')) != 8):
print('This is not a valid SID!')
sys.exit(1)
domain_sid = sys.argv[1].rsplit('-', 1)[0]
rid = int(sys.argv[1].rsplit('-', 1)[1])
# see: https://manpages.ubuntu.com/manpages/bionic/en/man5/sssd-ad.5.html#id%20mapping
slices = (SSS_IDMAP_DEFAULT_UPPER - SSS_IDMAP_DEFAULT_LOWER) / SSS_IDMAP_DEFAULT_RANGESIZE
domain_sid_hash = murmur3_32(domain_sid, 0xdeadbeef)
slice = int( ((domain_sid_hash % slices) * SSS_IDMAP_DEFAULT_RANGESIZE) + SSS_IDMAP_DEFAULT_LOWER )
uid = slice + rid
print(uid)
if(__name__ == '__main__'):
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment