#!/bin/bash # # The following is a script to set up local apps support on LTSP through LDM # # This hook modifies /etc/group and /etc/passwd directly with user/group # information gathered from the server. # 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" || boolean_is_true "$LTSP_FATCLIENT"; 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 LANGUAGE=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="" # those 2 variables are there because if group is rejected because of the gid we need to create this group. dgnames="" ngids="" oldifs="${IFS-not set}" IFS=":" while read gname gpass gid gusers; do match= case $gnames in *:"$gname":*|*:"$gname") # group name present in the list of groups already processed. match=1 case $gusers in "$LDM_USERNAME"|*,"$LDM_USERNAME",*|*,"$LDM_USERNAME"|"$LDM_USERNAME",*) dgnames="$dgnames $gname," ;; esac ;; esac case $gids in *:"$gid":*|*:"$gid") # gid present in the list of gids already processed. match=1 case $gusers in "$LDM_USERNAME"|*,"$LDM_USERNAME",*|*,"$LDM_USERNAME"|"$LDM_USERNAME",*) ngids="$ngids $gname," ;; esac ;; esac if [ -z "$match" ]; then echo "$gname:$gpass:$gid:$gusers" >>${TMPGROUP} gnames="$gnames:$gname" gids="$gids:$gid" fi done < ${COMBINED_GROUP} test "$oldifs" = "not set" && unset IFS || IFS="$oldifs" # cleanup dgnames=$(echo ${dgnames} | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//') ngids=$(echo ${ngids} | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//') tocreate="" oldifs="${IFS-not set}" IFS=, for e in $ngids; do match= for f in $dgnames; do if [ "$e" = "$f" ]; then match=1 fi done if [ -z "$match" ]; then tocreate="$tocreate $e," fi done tocreate=$(echo ${tocreate} | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//' | sed 's/^[[:blank:]]*//g') test "$oldifs" = "not set" && unset IFS || IFS="$oldifs" cp ${TMPGROUP} /etc/group chmod 644 /etc/group if [ -n "$myGroups" ]; then if /usr/bin/test -w /etc ; then oldifs="${IFS-not set}" IFS=, for ngroup in $tocreate; do ngroup=$(echo ${ngroup} | sed -e 's/ /\\\ /g') # FIXME: Problem with AD. Space not permited here. groupadd -r ${ngroup} done test "$oldifs" = "not set" && unset IFS || IFS="$oldifs" for group in $(echo ${myGroups} | tr ',' '\n' | sort -u); do /usr/sbin/usermod -a -G $group "${LDM_USERNAME}" 2>/dev/null done else # FIXME: maybe add system groups: $tocreate into /etc/group # Read-only /etc cannot use usermod myGroups=$(echo ${myGroups} | tr ',' '\n' | sort -u | tr '\n' ',' | sed 's/,$//') oldifs="${IFS-not set}" 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 test "$oldifs" = "not set" && unset IFS || IFS="$oldifs" fi fi # Now, let's mount the home directory oldifs="${IFS-not set}" IFS=":" export LDM_HOME="" export USER_UID="" export USER_GID="" while read user pass uid gid gecos home shell ; do # First, make the mountpoint LDM_HOME="$home" USER_UID="$uid" USER_GID="$gid" mkdir -p ${LDM_HOME} # LLIUREX HACK rsync -ax /etc/skel/ ${LDM_HOME} chown -R "$USER_UID":"$USER_GID" ${LDM_HOME} if [ -n "${XAUTHORITY_DIR}" ]; then chown "$USER_UID":"$USER_GID" ${XAUTHORITY_DIR} fi done < /etc/cups/client.conf elif ! grep -qsi "^Browsing on" /etc/cups/cupsd.conf; then # LLIUREX CHANGES # IP=$(getent hosts server | awk '{print $1}') if [ "$IP" != "" ]; then echo "ServerName ${IP}" > /etc/cups/client.conf else echo "ServerName ${LDM_SERVER}" > /etc/cups/client.conf fi # # fi fi n4d-modules enable-plugin /etc/n4d/conf.d/TeacherShare || true if boolean_is_true "$LTSP_FATCLIENT"; then mkdir -p /run/$LDM_USERNAME/home mkdir -p /run/$LDM_USERNAME/share mkdir -p /run/$LDM_USERNAME/groups_share mkdir -p /run/$LDM_USERNAME/teachers_share # Teachers need access to student home mount point # 10003 -> teachers gid if [ ${GRP_USER} = 'students' ]; then mount //$LDM_SERVER/home /run/$LDM_USERNAME/home -o username=$LDM_USERNAME,password=$LDM_PASSWORD,forceuid,forcegid,uid="$USER_UID",gid="10003" else mount //$LDM_SERVER/home /run/$LDM_USERNAME/home -o username=$LDM_USERNAME,password=$LDM_PASSWORD,forceuid,forcegid,uid="$USER_UID",gid="$USER_GID" fi mount //$LDM_SERVER/share /run/$LDM_USERNAME/share -o username=$LDM_USERNAME,password=$LDM_PASSWORD,forceuid,forcegid,uid="$USER_UID",gid="$USER_GID" mount //$LDM_SERVER/groups_share /run/$LDM_USERNAME/groups_share -o username=$LDM_USERNAME,password=$LDM_PASSWORD,forceuid,forcegid,uid="$USER_UID",gid="$USER_GID" mount //$LDM_SERVER/share_teachers /run/$LDM_USERNAME/teachers_share -o username=$LDM_USERNAME,password=$LDM_PASSWORD,forceuid,forcegid,uid="$USER_UID",gid="$USER_GID" fi unset LDM_PASSWORD fi