#!/bin/bash
#
# To use this script, enable internal operation log.
#   nsslapd-plugin-logging: on
#   nsslapd-accesslog-level: 260
#
# Then identify the user you want to do 'id <user>'
# Replace in FILTER_MEMBEROF, use100 with this user
#
HOST=...
PORT=389
BIND_DN="cn=directory manager"
BIND_PWD="Secret123"
MEMBEROF_FULL=/tmp/memberof.full.$$
MEMBEROF_FILE=/tmp/memberof.$$
MEMBERS_FILE=/tmp/members.$$

#
# Note: all searches are users/usergroups
# So 'id <user>' does not care about sudo/hbac groups
#
BASE="cn=accounts,dc=ipa,dc=lab"

#
# Deref taken from maps in src/providers/ipa/ipa_opts.c
#
DEREF_MEMBEROF="deref=memberof:ipaUserGroup,posixGroup,cn,userPassword,gidNumber,member,ipaUniqueID,ipaNTSecurityIdentifier,modifyTimestamp,ipaExternalMember"
FILTER_MEMBEROF="(&(uid=user100)(objectclass=posixAccount)(&(uidNumber=*)(!(uidNumber=0))))"

DEREF_MEMBERS="deref=member:objectClass,posixGroup,cn,userPassword,gidNumber,member,ipaUniqueID,ipaNTSecurityIdentifier,modifyTimestamp,entryUSN,ipaExternalMember,uid"

#
# retrieve the groups that user100 is memberof
# Pick up only group with gidNumber (way to skip hbac/sudo groups
#
get_memberof()
{
    ldapsearch -LLL -o ldif-wrap=no -h ${HOST} -p ${PORT} -D "${BIND_DN}" -w ${BIND_PWD} -b "$BASE" -s sub -E ${DEREF_MEMBEROF} ${FILTER_MEMBEROF} > ${MEMBEROF_FULL}
    grep -i '# memberof:' ${MEMBEROF_FULL} | while read f
    do
        if [ -n "`echo $f | grep -i 'gidNumber'`" ] 
        then
                GID=`echo "$f" | sed 's/.*<gidNumber=\([0-9]*\)>;.*$/\1/' `
                GROUP_DN=`echo "$f" | sed 's/.*>;cn/cn/' `
                echo "${GID}    ${GROUP_DN}"
        fi
    done > ${MEMBEROF_FILE}
}
old_get_memberof()
{
ldapsearch -LLL -o ldif-wrap=no -h ${HOST} -p ${PORT} -D "${BIND_DN}" -w ${BIND_PWD} -b "$BASE" -s sub -E ${DEREF_MEMBEROF} ${FILTER_MEMBEROF} > ${MEMBEROF_FULL}
grep -i '# memberof:' ${MEMBEROF_FULL} | while read f
do
    GID=`echo "$f" | sed 's/.*<gidNumber=\([0-9]*\)>;.*$/\1/' `
    GROUP_DN=`echo "$f" | sed 's/.*>;cn/cn/' `
    echo "${GID}    ${GROUP_DN}" > ${MEMBEROF_FILE}
done
}

#
# Retrieve the members of each usergroup that user100 is memberof
#
get_members()
{
FILTER_MEMBERS="(&(gidNumber=$1)(|(objectClass=ipaUserGroup)(objectClass=posixGroup))(cn=*)(&(gidNumber=*)(!(gidNumber=0))))"
ldapsearch -LLL -o ldif-wrap=no -h ${HOST} -p ${PORT} -D "${BIND_DN}" -w ${BIND_PWD} -b "${BASE}" -s sub -E ${DEREF_MEMBERS} ${FILTER_MEMBERS} >> ${MEMBERS_FILE}
}

get_memberof
cat ${MEMBEROF_FILE} | while read f
do
	get_members $f
done
