#!/bin/bash # # A simple script to add users and their group to ldap, as well as a kerberos principal. # set -eu usage(){ cat < [] [] [] $(basename $0) deluser $(basename $0) delhost $(basename $0) ldapvi $(basename $0) : User ID (login name) : Password : If given, the user is added to this posix group (in addition to his personal group). The group must already exist in the LDAP DT. , : LDAP attributes 'givenName' and 'sn'. If omitted, is used. : File containing lines of the form: adduser [] [] [] adduser [] [] [] … deluser deluser … Every line is processed like a single call to the $(basename $0) program. EOF } BASEDN="{{ basedn }}" LDAPADMIN="cn=admin,$BASEDN" ADPASSWD="$(cat {{ ldap_admin_pwd_file }})" if [ $# -lt 2 ] ; then if [ $# = 0 ] ; then usage exit 1 elif [ "$1" = ldapvi ] ; then exec ldapvi -m -h ldapi:/// -D "$LDAPADMIN" -b "$BASEDN" -w "$ADPASSWD" elif [ -r "$1" ]; then ## recursively call this program: while read -r LINE ; do $0 $LINE done < "$1" ## reset cache after mass import/deletion: sss_cache -U -G exit 0 else usage exit 1 fi elif [ $1 = adduser -a $# -lt 3 ] ; then echo "Error: Password missing." usage exit 1 fi ## Range of user and personal group IDs: MINID={{ min_id }} MAXID={{ max_id }} ## Range to cover in a single ldap search (must be smaller than 'olcSizeLimit' in cn=config): RANGE=399 HOMES="{{ lan_homes }}" COMMAND="$1" id="$2" pw="${3:-""}" grp="${4:-""}" gn="${5:-$2}" sn="${6:-$2}" domain="$(hostname -d)" if [ -x /usr/sbin/kadmin.local ] ; then KRB5=true pwEntry="" else KRB5=false pwEntry="userPassword: $pw" fi ################################################################################################## nextnum(){ local id=$MINID local bsta bend all uids gids num ## Search for the next pair of identical free IDs: while [ $id -le $MAXID ] ; do bsta=$id bend=$(( $bsta + $RANGE )) all="$(seq $bsta $bend)" uids="$(ldapsearch -Y EXTERNAL -H ldapi:/// -LLL -b "ou=people,$BASEDN" "(&(objectClass=posixAccount)(uidNumber>=$bsta)(uidNumber<=$bend))" \ uidNumber 2>/dev/null | grep "uidNumber: " | cut -f2 -d ' ' | sort -g | uniq)" gids="$(ldapsearch -Y EXTERNAL -H ldapi:/// -LLL -b "ou=groups,$BASEDN" "(&(objectClass=posixGroup)(gidNumber>=$bsta)(uidNumber<=$bend))" \ gidNumber 2>/dev/null | grep "gidNumber: " | cut -f2 -d ' ' | sort -g | uniq)" fuids="$(comm -13 <(echo "$uids") <(echo "$all"))" fgids="$(comm -13 <(echo "$gids") <(echo "$all"))" num=$(comm -12 <(echo "$fuids") <(echo "$fgids") | head -1) if [ -n "$num" ] ; then echo $num return else id=$(( $bend + 1 )) fi done ## something went wrong: exit 1 } add-user(){ local id="$1" local pwEntry="$2" local grp="$3" local gn="$4" local sn="$5" if ldapsearch -Y EXTERNAL -H ldapi:/// -LLL -b "ou=people,$BASEDN" "(&(objectClass=posixAccount)(uid=$id))" uid 2>/dev/null \ | grep -q "uid: $id" ; then echo "User '$id' exists already, skipping." return fi local uidNumber=$(nextnum) local gidNumber=$uidNumber if [ $uidNumber -ge $MAXID -o $gidNumber -ge $MAXID ] ; then echo "Error: $uidNumber and/or $gidNumber exceed max ID number ${MAXID}." exit 1 fi cat <&1 \ | sed '/ldap_initialize/d' for grp in $(ldapsearch -Y EXTERNAL -H ldapi:/// -LLL -b "ou=groups,$BASEDN" "(&(objectClass=posixGroup)(memberUid=${id}))" cn 2>/dev/null \ | grep cn: | cut -d ' ' -f2) ; do cat <