使用 ldapsearch 根据 objectSid 获取 SID

使用 ldapsearch 根据 objectSid 获取 SID

我有对象标识符ldapsearch 命令返回的属性,我该如何生成SID以人类可读的格式呈现?

ldapsearch 命令:

ldapsearch -LLL -H ldap://dc.example.com:389 -b dc=example,dc=lk -D example\administrator -w adminPassword "(sAMAccountName=bob)" | grep -i "objectSid::" | cut -d ":" -f3 | xargs

此命令返回 AD 用户“bob”的 objectSid。假设它返回的 objectSid 为:

AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA==

我想要按照以下格式生成其 SID:

S-1-5-21-1270179133-2928470170-2248674342-4324

在 Linux 中可以做到这一点吗?

参考:使用 ldapsearch 根据 objectGUID 获取对象

答案1

最后我成功地从 ObjectSid 构造了 SID。如果有人感兴趣的话,这里有完整的 shell 脚本。

#!/bin/bash

# Base-64 encoded objectSid
OBJECT_ID="AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA=="

# Decode it, hex-dump it and store it in an array
G=($(echo -n $OBJECT_ID | base64 -d -i | hexdump -v -e '1/1 " %02X"'))

# SID in HEX
# SID_HEX=${G[0]}-${G[1]}-${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}-${G[8]}${G[9]}${G[10]}${G[11]}-${G[12]}${G[13]}${G[14]}${G[15]}-${G[16]}${G[17]}${G[18]}${G[19]}-${G[20]}${G[21]}${G[22]}${G[23]}-${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}

# SID Structure: https://technet.microsoft.com/en-us/library/cc962011.aspx
# LESA = Little Endian Sub Authority
# BESA = Big Endian Sub Authority
# LERID = Little Endian Relative ID
# BERID = Big Endian Relative ID

BESA2=${G[8]}${G[9]}${G[10]}${G[11]}
BESA3=${G[12]}${G[13]}${G[14]}${G[15]}
BESA4=${G[16]}${G[17]}${G[18]}${G[19]}
BESA5=${G[20]}${G[21]}${G[22]}${G[23]}
BERID=${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}

LESA1=${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}
LESA2=${BESA2:6:2}${BESA2:4:2}${BESA2:2:2}${BESA2:0:2}
LESA3=${BESA3:6:2}${BESA3:4:2}${BESA3:2:2}${BESA3:0:2}
LESA4=${BESA4:6:2}${BESA4:4:2}${BESA4:2:2}${BESA4:0:2}
LESA5=${BESA5:6:2}${BESA5:4:2}${BESA5:2:2}${BESA5:0:2}
LERID=${BERID:6:2}${BERID:4:2}${BERID:2:2}${BERID:0:2}

LE_SID_HEX=${LESA1}-${LESA2}-${LESA3}-${LESA4}-${LESA5}-${LERID}

# Initial SID value which is used to construct actual SID
SID="S-1"

# Convert LE_SID_HEX to decimal values and append it to SID as a string
IFS='-' read -ra ADDR <<< "${LE_SID_HEX}"
for OBJECT in "${ADDR[@]}"; do
  SID=${SID}-$((16#${OBJECT}))
done

echo ${SID}

答案2

这对我有用:perl -MNet::LDAP::SID -E 'my $binary=qx(echo AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA== | base64 --decode); my $sid = Net::LDAP::SID->new($binary); say $sid->as_string'

只能用 perl 来完成,但我猜作为示例就足够了。

答案3

首先,您可以通过在过滤器后包含所需的属性来限制 ldapsearch 查询返回的答案集,当您想要多个结果时,这应该会更快一些。

 ldapsearch -LLL -H ldap://dc.example.com:389 -b dc=example,dc=lk -D example\administrator -w adminPassword "(sAMAccountName=bob)" ObjectSID

第二,当属性与其值之间用双冒号分隔时,::表示该值是base64 编码. ldapsearch 不具备模式感知能力,它不知道这种 base64 编码的属性是否是可以在支持 unicode 的终端中显示为文本的 unicode 文本字符串,或者例如 jpegPhoto 或其他无法在终端中轻易显示的数据,并且不会为您解码这些值。

echo   AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA== | base64 --decode

应该可以。据我所知base64应该在 coreutils 包中。


问题是对象标识符base64解码后仍然是二进制值需要进一步转换为才能显示常规安全标识符格式S-1-5-21-1270179133-2928470170-2248674342-4324

您需要用您选择的脚本/编程语言编写一个转换例程,例如其他人已经做过的perl 或者php

答案4

YasithaB 在回答他自己的问题时给出的脚本中存在一些小问题:

它使用 ${G[28]},将其中一个 ID 视为 5 个字节长。我认为这是错误的,SID 通常只有 28 个字节的二进制数,编号为 0-27

它假设 SID 有 5 个子 ID,而它可以/应该使用 ${G[1]} 来查找 ID 的数量。

结尾部分看起来非常复杂 - 创建 $LE_SID_HEX,然后将其再次分割并转换为十进制。一行代码:

printf "S-1-%u-%u-%u-%u-%u-%u\n" $(( 16#$LESA1 )) $(( 16#$LESA2 )) $(( 16#$LESA3 )) $(( 16#$LESA4 )) $(( 16#$LESA5 )) $(( 16#$LERID ))

将给出与脚本最后 12 行相同的结果。

相关内容