3

If I have the objectGUID attribute as returned by the ldapsearch command, how can I search the whole directory for an object with that objectGUID?

For example, if I search a user getting its objectGUID, I get the following:

$ 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==

Starting from the value b+bSezFkKkWDmbIZiyE5rg==, how can I create a query string to get that object?

5 Answers 5

4

This script worked for me; I'm posting it here in case it might help someone else

#!/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}
1
  • This may return more than you want if the search scope is "subtree" (default). So I suggest to add -s base for good measure Jan 13, 2019 at 11:35
4
# 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]}"

I used the above answer and ran into a couple of subtle errors during testing.

  1. BASE64_DECODED is set to binary data which can contain any possible byte value. echoing that without quotes causes some byte values to be interpreted by the shell. tabs and newlines (maybe more) will be converted to spaces, which corrupts your output data.

  2. hexdump by default will suppress duplicate characters and replace them with an asterisk and newline. So if your GUID ever has two consecutive bytes the same you will get some strange looking output:

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

Here is the corrected code that fixes these problems:

# 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]}"
1
  • Just for the sake of pointing it out, on this site, the order of answers is not preserved - they are ordered by net votes. Oct 5, 2014 at 6:55
1

The main problem is that objectGUID is a binary field, and certain ldapsearch builds don't have an ability to directly query that kind of field. As the output of searching for objectGUID shows, it's presuming the data is base64 and that's what you're seeing when searching for objectGUID. The actual data on one object in my tree is 32 bytes long, but linux ldapsearch gave me a 22 byte return value.

It looks like the Sun build of ldapsearch has the ability to handle binary data, but the Linux version does not.

0

In case you are using ldapsearch with -x option (to write all unprintable characters to the file), so you cannot have base64 decoded string, you can use this version:

G=`hexdump -e '1/1 "%02X "' /tmp/ldapsearch-objectGUID-oHJ3rK`
read g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 <<<"$G"
OBJECTGUID="${g3}${g2}${g1}${g0}-${g5}${g4}-${g7}${g6}-${g8}${g9}-${g10}${g11}${g12}${g13}${g14}${g15}"

Where you need to replace the filename with the correct filename displayed in output of ldapsearch, ie:

objectGUID:< file:///tmp/ldapsearch-objectGUID-oHJ3rK
0

The flaw of putting the GUID into the search base (-b "<GUID=${OBJECTGUID}>") used in the older answers is that you can find only one object this way although many tasks require batch retrieve.

My solution is passing the GUID bytes as escaped characters as part of the filter string, not the search base.

$ ./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'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .