使用 ldapsearch 根据 objectGUID 获取对象

使用 ldapsearch 根据 objectGUID 获取对象

如果我有命令objectGUID返回的属性ldapsearch,我该如何在整个目录中搜索具有该属性的对象objectGUID

例如,如果我搜索某个用户获取其的objectGUID,我会得到以下内容:

$ ldapsearch -x -D $MyDn -W -h $Host -b "dc=x,dc=y" "(mail=something)" objectGUID

# 7f435ae312a0d8197605, p, Externals, x.y
dn: CN=7f435ae312a0d8197605,OU=p,DC=x,DC=y
objectGUID:: b+bSezFkKkWDmbIZiyE5rg==

从值开始b+bSezFkKkWDmbIZiyE5rg==,如何创建查询字符串来获取该对象?

答案1

这个脚本对我有用;我把它发布在这里,希望它能帮助别人

#!/bin/bash

# specify as first parameter the object ID as received by an LDAP query; it's base-64 encoded.
OBJECT_ID="${1}"

# we decode it, we hex-dump it and store it in an array to
# re-order it in the format expected by LDAP
BASE64_DECODED=$(echo $OBJECT_ID | base64 -d -i)
G=($(echo ${BASE64_DECODED} | hexdump -e '1/1 " %02X"'))
    OBJECTGUID="${G[3]}${G[2]}${G[1]}${G[0]}-${G[5]}${G[4]}-${G[7]}${G[6]}-${G[8]}${G[9]}-${G[10]}${G[11]}${G[12]}${G[13]}${G[14]}${G[15]}"

BIND_DN="CN=..."

# Note that we use the GUID as the search base
SEARCH_BASE="<GUID=${OBJECTGUID}>"

# we query for any object (the important point here is the search base)
QUERY="(cn=*)"

ATTRIBUTES="objectGUID userPrincipalName sAMAccountName"

ldapsearch -x -D "${BIND_DN}" -W -h x.y.com -b "${SEARCH_BASE}" "${QUERY}" ${ATTRIBUTES}

答案2

# we decode it, we hex-dump it and store it in an array to
# re-order it in the format expected by LDAP
BASE64_DECODED=$(echo $OBJECT_ID | base64 -d -i)
G=($(echo ${BASE64_DECODED} | hexdump -e '1/1 " %02X"'))

OBJECTGUID="${G[3]}${G[2]}${G[1]}${G[0]}-${G[5]}${G[4]}-${G[7]}${G[6]}-${G[8]}${G[9]}-${G[10]}${G[11]}${G[12]}${G[13]}${G[14]}${G[15]}"

我使用了上述答案,并在测试期间遇到了一些细微的错误。

  1. BASE64_DECODED设置为可以包含任何可能的字节值的二进制数据。如果不使用引号,则回显该数据会导致某些字节值被 shell 解释。制表符和换行符(可能更多)将转换为空格,从而破坏您的输出数据。

  2. hexdump默认情况下会抑制重复字符并用星号和换行符替换它们。因此,如果您的 GUID 有两个连续相同的字节,您将得到一些奇怪的输出:

    OBJECT_ID = Qdicy5qc3kOqtrZ3dYswgw==
    OBJECTGUID = CB9CD841-9C9A-43DE-AAB6*-77758B30830A
    

以下是修复这些问题的更正代码:

# we 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"'))

OBJECTGUID="${G[3]}${G[2]}${G[1]}${G[0]}-${G[5]}${G[4]}-${G[7]}${G[6]}-${G[8]}${G[9]}-${G[10]}${G[11]}${G[12]}${G[13]}${G[14]}${G[15]}"

答案3

主要问题是 objectGUID 是一个二进制字段,而某些 ldapsearch 版本无法直接查询此类字段。正如搜索 objectGUID 的输出所示,它假定数据是 base64,这就是您在搜索 objectGUID 时看到的内容。我的树中一个对象的实际数据长度为 32 个字节,但 linux ldapsearch 给了我一个 22 字节的返回值。

看起来 Sun 构建的 ldapsearch 具有处理二进制数据的能力,但是 Linux 版本却不具备。

答案4

将 GUID 放入-b "<GUID=${OBJECTGUID}>"旧答案中使用的搜索基础()的缺陷是,尽管许多任务需要批量检索,但通过这种方式您只能找到一个对象。

我的解决方案是将 GUID 字节传递为转义字符作为过滤字符串的一部分,而不是搜索基础。

$ ./myldapsearch b+bSezFkKkWDmbIZiyE5rg== Qdicy5qc3kOqtrZ3dYswgw==
(|(ObjectGuid=\6F\E6\D2\7B\31\64\2A\45\83\99\B2\19\8B\21\39\AE)(ObjectGuid=\41\D8\9C\CB\9A\9C\DE\43\AA\B6\B6\77\75\8B\30\83))

$ ldapsearch ... '(|(ObjectGuid=\6F\E6\D2\7B\31\64\2A\45\83\99\B2\19\8B\21\39\AE)(ObjectGuid=\41\D8\9C\CB\9A\9C\DE\43\AA\B6\B6\77\75\8B\30\83))' sAMAccountName ObjectGUID
...
objectGUID:: b+bSezFkKkWDmbIZiyE5rg==
...
objectGUID:: Qdicy5qc3kOqtrZ3dYswgw==
...
# numEntries: 2

_

#!/bin/bash

fn_base64_uuid_to_hexarray() {
  # hexdump base64 valie in $2 to a new indexed array of hex values and name the array $1

  # declare global array, not assigning a value for 2 reasons:
  # - command substitution exit code would be discarded
  # - declaring arrays with variable name require quoting the right side: $n='(1 2 3)'
  declare -a -g ${1:?}

  # declare a local nameref with a static name so no quoting is needed
  local -n a=${1:?}
  a=( $(echo "${2:?}" | base64 -d | fn_hexdump_stdin) )
}

fn_hexdump_stdin() {
  # hexdump stdin as values separated by space

  hexdump -v -e '1/1 " %02X"'
}

fn_format_hexarray_uuid_as_isostr() {
  #ex: fn_format_hexarray_uuid_as_iso hexarray
  local -n G=${1:?}
  OBJECTGUID="${G[3]}${G[2]}${G[1]}${G[0]}-${G[5]}${G[4]}-${G[7]}${G[6]}-${G[8]}${G[9]}-${G[10]}${G[11]}${G[12]}${G[13]}${G[14]}${G[15]:?}"
}

fn_format_hexarray_as_ldap_filter_value() {
  # escape hexarray named $1 as ldap filter value and store in variable named $2

  declare -g ${2:?}=
  local -n G=${1:?}
  local -n s=${2:?}
  for h in "${G[@]}"; do
    s=$s'\'$h
  done
}

printf '(|'
for OBJECT_ID in "$@"; do
  fn_base64_uuid_to_hexarray hexarray "$OBJECT_ID"
  fn_format_hexarray_as_ldap_filter_value hexarray ldap_filter_value
  printf '(ObjectGuid=%s)' "$ldap_filter_value"
done
printf ')\n'

相关内容