#
# The following is a script to set up local apps support on LTSP through LDM
#
# The presumption is that the environment is set up such that NSS will look
# at extrafiles, ie. additional local files for passwd and group beyond
# those found in /etc.
#
# This will enable us to easily bypass the need for setting up local user
# authentication, and instead leverage the authentication already set up on
# the server.

if boolean_is_true "$LOCAL_APPS"; then

    # Set up local uids/gids

    LOCALAPPS_CACHE=/var/cache/ltsp-localapps
    export LOCALAPPS_CACHE
    mkdir -p ${LOCALAPPS_CACHE} 2>/dev/null

    # Copy /etc/passwd and /etc/group to cache if it does not exist (should only happen on first login)
    for i in passwd group; do
        if [ ! -e "${LOCALAPPS_CACHE}/${i}" ]; then
            cp /etc/${i} "${LOCALAPPS_CACHE}/${i}"
        else
            cp "${LOCALAPPS_CACHE}/${i}" /etc/${i}
        fi
    done

    # Get logged in username if not set
    [ -z "$LDM_USERNAME" ] && LDM_USERNAME=$(ssh -S ${LDM_SOCKET} ${LDM_SERVER} 'echo ${USER}')

    # Get passwd info *just* for that user
    ssh -S ${LDM_SOCKET} ${LDM_SERVER} "/usr/bin/getent passwd ${LDM_USERNAME}" | sed -e "s/${LDM_USERNAME}/${LDM_USERNAME}/i" >>/etc/passwd

    # Get all group info and copy to COMBINED_GROUP
    COMBINED_GROUP=${LOCALAPPS_CACHE}/group.combined
    cp /etc/group ${COMBINED_GROUP}
    ssh -S ${LDM_SOCKET} ${LDM_SERVER} "/usr/bin/getent group" >> ${COMBINED_GROUP}

    # Get the system groups that the user belongs to, so we can add him back in
    myGroups=$(ssh -S ${LDM_SOCKET} ${LDM_SERVER} /usr/bin/getent group|egrep "[,:]${LDM_USERNAME}(,|$)"|cut -d: -f1| tr '\n' ',' | sed -e 's/,$//g')

    # (/usr/bin/id is only needed because getent evidently does not return groups
    # added by pam_group (bug in pam_group?)

    myGroups1=$(ssh -S ${LDM_SOCKET} ${LDM_SERVER} LANG=C /usr/bin/id | sed -e 's/^.*groups=//' -e 's/) .*$/)/'|cut -d= -f2|sed -e 's/[0-9]*(//g' -e 's/)//g')

    # concatenate groups from different sources, stripping off prefixed and
    # trailing commas
    myGroups=$(echo ${myGroups},${myGroups1} | sed -e 's/^,//g' -e 's/,$//g')

    # Get the user's groups specifically (in case they weren't returned by "getent group")
    myGroups_quoted=$(echo $myGroups | sed -e "s/^/\\\'/" -e "s/$/\\\'/" -e "s/,/\\\' \\\'/g")
    ssh -S ${LDM_SOCKET} ${LDM_SERVER} LANG=C eval getent group ${myGroups_quoted} >> ${COMBINED_GROUP}
    unset myGroups_quoted

    # Now, some groups may have different gids on the server than the client chroot
    # So, let's prune out all the dups
    TMPGROUP="${LOCALAPPS_CACHE}/tmpgroup"
    [ -f "${TMPGROUP}" ] && rm ${TMPGROUP}
    gnames=""
    gids=""
    while read line; do
        gname=$(echo $line|cut -d: -f1)
        gid=$(echo $line|cut -d: -f3)
        match=
        for e in $gnames; do
            if [ "$gname" = "$e" ]; then
                match=1
            fi
        done
        for e in $gids; do
            if [ "$gid" = "$e" ]; then
                match=1
            fi
        done
        if [ -z "$match" ]; then
            echo "$line" >>${TMPGROUP}
            gnames="$gnames $gname"
            gids="$gids $gid"
        fi
    done < ${COMBINED_GROUP}
    cp ${TMPGROUP} /etc/group
    chmod 644 /etc/group


    if [ -n "$myGroups" ]; then
        if [ -w /etc ]; then
            usermod -G "$myGroups" "${LDM_USERNAME}" 2>/dev/null
        else
            # Read-only /etc cannot use usermod
            myGroups=$(echo ${myGroups} | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//')
            OLDIFS="$IFS"
            IFS=,
            cp /etc/group $TMPGROUP
            for group in $myGroups ; do
                # add user to each group manually
                line="$(egrep ^${group}: $TMPGROUP | egrep -v [:,]${LDM_USERNAME}'(,|$)' )"
                if [ -n "$line" ]; then
                    # add the user to the group
                    sed -i -e "s/^$line/$line,${LDM_USERNAME}/g" -e 's/:,/:/g' $TMPGROUP
                fi
            done
            cp $TMPGROUP /etc/group
            unset IFS
            test -n "$OLDIFS" && IFS="$OLDIFS"
        fi
    fi

    # Now, let's mount the home directory

    # First, make the mountpoint
    LDM_HOME=$(getent passwd ${LDM_USERNAME}|cut -d: -f6)
    export LDM_HOME
    mkdir -p ${LDM_HOME}
    chown $(getent passwd "${LDM_USERNAME}" | cut -d ":" -f 3-4) ${LDM_HOME}
    if [ -n "${XAUTHORITY_DIR}" ]; then
        chown $(getent passwd "${LDM_USERNAME}" | cut -d ":" -f 3-4) ${XAUTHORITY_DIR}
    fi

    ## Maybe do this:
    ## export HOME=${LOCALAPPS_CACHE}

    # Mount the home directory
    sshfs -o allow_other,ControlPath=${LDM_SOCKET} ${LDM_SERVER}:${LDM_HOME} ${LDM_HOME}

    # Mount other directories
    if [ -n "${LOCAL_APPS_EXTRAMOUNTS}" ]; then
        OLDIFS="$IFS"
        IFS=","
        for extradir in ${LOCAL_APPS_EXTRAMOUNTS}; do
            mkdir -p "${extradir}"
            sshfs -o allow_other,ControlPath=${LDM_SOCKET} "${LDM_SERVER}:${extradir}" "${extradir}"
        done
        IFS="$OLDIFS"
    fi

    # Create tmpdir for localapps menu
    if boolean_is_true "$LOCAL_APPS_MENU" && [ -x "/usr/bin/ltsp-genmenu" ]; then
        # get a temporary directory on the server
        TMP_XDG_MENU="$(ssh -S ${LDM_SOCKET} ${LDM_SERVER} mktemp -d /tmp/ltsp-localapps-${LDM_USERNAME}-XXXXXX)"
        export TMP_XDG_MENU
        CLIENT_ENV="${CLIENT_ENV} XDG_DATA_DIRS=${TMP_XDG_MENU}/:/usr/local/share/:/usr/share/"

        # Make the local temporary directory
        TMP_XDG_DIR_LOCAL="$(mktemp -d /tmp/ltsp-localapps-${LDM_USERNAME}-XXXXXX)"
        export TMP_XDG_DIR_LOCAL

        # chown the tmpdir to be owned by the user
        chown -R $(getent passwd "${LDM_USERNAME}" | cut -d ":" -f 3-4) ${TMP_XDG_DIR_LOCAL} 

        # Generate the localapp menu
        su - ${LDM_USERNAME} -c "LOCAL_APPS_MENU_ITEMS=${LOCAL_APPS_MENU_ITEMS} TMP_XDG_DIR_LOCAL=${TMP_XDG_DIR_LOCAL} /usr/bin/ltsp-genmenu install"

        # now, scp the directory to the /tmp dir on the server
        scp -r -o "ControlPath $LDM_SOCKET" -o "User $LDM_USERNAME" ${TMP_XDG_DIR_LOCAL}/* ${LDM_SERVER}:${TMP_XDG_MENU}

        # Clean up local
        rm -rf ${TMP_XDG_DIR_LOCAL} || true
    fi

    # if cups is installed in the chroot, use LDM_SERVER for printing
    mkdir -p /etc/cups/
    if [ -n "${CUPS_SERVER}" ]; then
        echo "ServerName ${CUPS_SERVER}" > /etc/cups/client.conf
    else
        echo "ServerName ${LDM_SERVER}" > /etc/cups/client.conf
    fi

fi
