#!/bin/sh -
env=`dirname $0`/.env; test -r "$env" && . "$env"
# dependency: ldapsearch

# 2026-01-29 ldap.umich.edu now requires authenticated access (ie .env here)
#	     see also /usr/local/bin/helpdesk/ldaplookup
srv="${LDAPQ_SERVER:-ldap://ldap.umich.edu}"; dc="${LDAPQ_DC:-dc=umich,dc=edu}"
srv_mm=ldap://ldap.ent.med.umich.edu;	      dc_mm="dc=med,$dc"
# consider ldaps://DOMAIN

# ldapq - perform a common search on an ldap server
# Steve Kinzler, steve@kinzler.com, Nov 23/Aug 24
# https://kinzler.com/me/home.html#unix

decode=; case "$1" in -[dD]) decode="$1"; shift;; esac
case "$1,$#" in
-h,*|--help,*|*,[01])	cat 1>&2 <<EOF
usage: ldapq [ -d | -D ]
       { allg | allgown | u | uname | uid | user | g | gname | gid }
       query_term [ [ -, ] attr ... ]
	-d	decode any Base64 field values to UTF-8
	-D	as -d but also as a single line
	-,	try to output a comma-separated list of main attribute values
u and g query on either name or id.  user queries with a common name.
query_term may include "*" for wildcard matching.
Set LDAPQ_SERVER (default $srv; MichMed $srv_mm)
and LDAPQ_DC (default $dc; MichMed $dc_mm)
in the environment to specify another ldap service.
Set LDAPQ_NOWARN to non-empty to suppress argument suspicion warnings.
Set LDAPQ_ARGS to any custom initial arguments to ldapsearch.
EOF
			exit 1;;
esac

what="$1"; shift; who="$1"; shift
list=; case "$1" in -,) list="$1"; shift;; esac
case "$what" in
uname|uid|user)		LDAPQ_ARGS="$LDAPQ_ARGS $LDAPQ_ARGS_U";;
gname|gid|allg|allgown)	LDAPQ_ARGS="$LDAPQ_ARGS $LDAPQ_ARGS_G";;
esac
case "$what" in
allg)	set "ou=Groups,$dc" "member=uid=$who,ou=People,$dc" dn "$@";;
allgown)set "ou=Groups,$dc" "owner=uid=$who,ou=People,$dc"  dn "$@";;

u)	if   echo "$who" | grep -s '^[0-9][0-9]*$' > /dev/null
	then	exec "$0" $decode uid   "$who" $list "$@"
	elif echo "$who" | grep -s ' '		   > /dev/null
	then	exec "$0" $decode user  "$who" $list "$@"
	else	exec "$0" $decode uname "$who" $list "$@"
	fi;;
uname)	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s '^[0-9]*$' > /dev/null &&
		echo "$0: warning, did you mean uid? ($who)"   1>&2)
	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s ' '	      > /dev/null &&
		echo "$0: warning, did you mean user? ($who)"  1>&2)
	set "ou=People,$dc"		   "uid=$who"	    "$@";;
uid)	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s '^[0-9]*$' > /dev/null ||
		echo "$0: warning, did you mean uname? ($who)" 1>&2)
	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s ' '	      > /dev/null &&
		echo "$0: warning, did you mean user? ($who)"  1>&2)
	set "ou=People,$dc"		   "uidNumber=$who" "$@";;
user)	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s '^[0-9]*$' > /dev/null &&
		echo "$0: warning, did you mean uid? ($who)"   1>&2)
	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s ' '	      > /dev/null ||
		echo "$0: warning, did you mean uname? ($who)" 1>&2)
	set "ou=People,$dc"		   "cn=$who"	    "$@";;

g)	if echo "$who" | grep -s '^[0-9][0-9]*$' > /dev/null
	then	exec "$0" $decode gid   "$who" $list "$@"
	else	exec "$0" $decode gname "$who" $list "$@"
	fi;;
gname)	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s '^[0-9]*$' > /dev/null &&
		echo "$0: warning, did you mean gid? ($who)"   1>&2)
	set "ou=User Groups,ou=Groups,$dc" "cn=$who"	    "$@";;
gid)	test -z "$LDAPQ_NOWARN" &&
	    (echo "$who" | grep -s '^[0-9]*$' > /dev/null ||
		echo "$0: warning, did you mean gname? ($who)" 1>&2)
	set "ou=User Groups,ou=Groups,$dc" "gidNumber=$who" "$@";;

*)	echo "$0: unknown search type ($what)" 1>&2; exit 2;;
esac

# "-H *://DOMAIN" appears more widely supported and flexible than "-h DOMAIN"
ldapsearch $LDAPQ_ARGS -o ldif_wrap=no -xLLL -H "$srv" -b "$@" |
grep -v '^ACL:' |
case "$decode" in
?*)	s=; case "$decode" in -D) s='s|\n| |g;';; esac
	perl -MMIME::Base64 -MEncode=decode -n -00 -e 's/\n +//g;
	     s/:: (\S+)/": " . do { $_ = decode("UTF-8", decode_base64($1));
				    '"$s"' $_ }/eg; print';;
*)	cat;;
esac |
case "$list" in
?*)	sed '/^dn: /d; /^ufn: /d; /^ *$/d; s/^[^=]*=//; s/,.*//' |
		sort -u | paste -s -d,;;
*)	cat;;
esac
