Script to add users to LDAP

I have a cluster of servers that manage user authentication and group membership in OpenLDAP. The OpenLDAP clients support adding users by importing LDIF files to create the user and set appropriate group membership. I find this process a little annoying and typically find myself sloppily managing template LDIF files. I wrote the following script to simplify the process.

#!/bin/bash
#
# add_user.sh: Add user to LDAP
# Author: Nick Sabine
#

# Defaults
LDAP_BASE="dc=ORG,dc=local"
LDAP_ACCOUNTS_DN="ou=people,${LDAP_BASE}"
LDAP_USER_GROUP="cn=user_group,ou=groups,${LDAP_BASE}"
LDAP_ADMIN_GROUP="cn=admin_group,ou=groups,${LDAP_BASE}"
LDAP_BIND_DN="cn=Manager,${LDAP_BASE}"
USER_NAME=
USER_CN=
USER_SN=
USER_ID=
GROUP_ID=1000
IS_ADMIN=
LDAP_OPTIONS=

usage()
{
cat << EOF
usage $0 options

This script creates a user in LDAP

OPTIONS
  -h         Show this message
  -n   Username
  -c     User CN
  -s     User SN
  -i    User ID Number (default: next available number)
  -g    Primary group ID Number (default: $GROUP_ID)
  -a         Add user to administrator group
  -D         LDAP Bind DN (default: $LDAP_BIND_DN)
  -b         LDAP Base (default: $LDAP_BASE)
  -P         LDAP Accounts DN (default: $LDAP_ACCOUNTS_DN)
  -U         LDAP User Group DN (default: $LDAP_USER_GROUP)
  -A         LDAP Admin Group DN (default: $LDAP_ADMIN_GROUP)
  -t         Test. Show what would be done, but don’t actually modify LDAP.
EOF
}

error_ldap() {
  echo "Error: Error connecting to LDAP or uninitialized user tree"
}

while getopts "hn:c:s:i:g:aD:b:P:U:A:t" OPTION
do
  case $OPTION in
    h)
      usage
      exit 1
      ;;
    n)
      USER_NAME=$OPTARG
      ;;
    c)
      USER_CN=$OPTARG
      ;;
    s)
      USER_SN=$OPTARG
      ;;
    i)
      USER_ID=$OPTARG
      ;;
    g)
      GROUP_ID=$OPTARG
      ;;
    a)
      IS_ADMIN=1
      ;;
    D)
     LDAP_BIND_DN=$OPTARG
     ;;
    b)
     LDAP_BASE=$OPTARG
     ;;
    P)
     LDAP_ACCOUNTS_DN=$OPTARG
     ;;
    U)
      LDAP_USER_GROUP=$OPTARG
      ;;
    A)
      LDAP_ADMIN_GROUP=$OPTARG
      ;;
    t)
      LDAP_OPTIONS+=" -n "
      ;;
    ?)
      usage
      exit
      ;;
  esac
done

if [ -z $USER_NAME        ] ||
   [ -z $USER_CN          ] ||
   [ -z $USER_SN          ] ||
   [ -z $GROUP_ID         ] ||
   [ -z $LDAP_BIND_DN     ] ||
   [ -z $LDAP_ACCOUNTS_DN ] ||
   [ -z $LDAP_USER_GROUP  ] ||
   [ -z $LDAP_ADMIN_GROUP ]
then
  usage
  exit 1
fi

read -p "LDAP Manager Password: " -s LDAPPASS
echo


# If USER_ID not supplied, find next using ldap query
if [ -z $USER_ID ]
then
  HIGHEST_UID=$(ldapsearch -x -w "$LDAPPASS" -b "${LDAP_ACCOUNTS_DN}" -D "${LDAP_BIND_DN}" "(objectclass=posixaccount)" uidnumber | grep -e '^uid' | cut -d':' -f2 | sort | tail -1)
  if [ -z $HIGHEST_UID ]
  then
    error_ldap
    exit 1
  fi
  let USER_ID=HIGHEST_UID+1
fi

read -p "${USER_NAME} Initial Password: " -s USER_CLEARTEXT_PASS
echo

USER_PASS=$(slappasswd -h {SSHA} -s $USER_CLEARTEXT_PASS)

unset USER_CLEARTEXT_PASS

CHANGE_DATE=$(echo "$(date +%s) / ( 60 * 60 * 24 )" | bc)

LDIF=$(cat << EOF
dn: uid=${USER_NAME},${LDAP_ACCOUNTS_DN}
changetype: add
uid: ${USER_NAME}
cn: ${USER_CN}
sn: ${USER_SN}
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword: ${USER_PASS}
shadowLastChange: ${CHANGE_DATE}
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: ${USER_ID}
gidNumber: ${GROUP_ID}
homeDirectory: /home/${USER_NAME}

dn: ${LDAP_USER_GROUP}
changetype: modify
add: memberuid
memberuid: ${USER_NAME}

EOF
)

if [ $IS_ADMIN ]
then
  LDIF+=$(cat << EOF


dn: ${LDAP_ADMIN_GROUP}
changetype: modify
add: memberuid
memberuid: ${USER_NAME}

EOF
)
fi

echo "--------------------"
echo "Adding ${LDIF}"
echo "--------------------"
echo "$LDIF" | ldapmodify -x -w "$LDAPPASS" -D "${LDAP_BIND_DN}" $LDAP_OPTIONS

unset LDAPPASS

https://gist.github.com/nsabine/6599630