4

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 Answers5

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}

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]}"

Jay
  • 41
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.

sysadmin1138
  • 135,853
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'

basin
  • 598
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