# $Id: cdd-actions 224 2004-07-08 08:26:51Z tille $
#
# Backend dependant functions for cdd package
#
# For error codes check in /usr/include/sysexits.h

# CHECK Functions

#checkCDD() is backend indep, and is defined in ${SHAREDIR}/cdd-action

# Read adduser config to find out from which ID normal users start
# Default = 1000
FIRST_UID=1000
[ -s /etc/adduser.conf ] && . /etc/adduser.conf

# checks if User $1 exists as a system user
checkUser() {
	RET=0
	CDDUSER=$1
	if [ $# -ne 1 ]; then
		RET=64 # EX_USAGE
	elif ! getent passwd "${CDDUSER}" > /dev/null; then
		RET=67 # EX_NOUSER
	fi
	return ${RET}
}

# checks if Role $1 is registered into system
# actually a mere check if Unix group, named like the CDD project, exists
checkRole() {
	RET=0
	ROLE=$1
	if [ "$#" -ne 1 ]; then
		RET=64 # EX_USAGE
	elif ! getent group "${ROLE}" > /dev/null; then
		RET=67 # EX_NOUSER
	fi
	return ${RET}
}


# check if CDD ($1) has registered Role ($2) 
# (or, in other words, if Role has been registerd in CDD)
checkRoleInCDD() {
	RET=0
	CDD=$1
	ROLE=$2
	if [ "$#" -ne 2 ]; then 
		RET=64 # EX_USAGE
	# currently there is no way to extract a Role from a CDD if
	# they're named differently, using unixgroups backend
	elif [ "${CDD}" != "${ROLE}" ]; then
		RET=69 # EX_UNAVAILABLE
	fi
	return ${RET}
}

# checks if user $2 is registered in CDD $1
checkUserInCDD() {
	RET=0
	CDD=$1
	CDDUSER=$2
	if [ "$#" -ne 2 ]; then 
		RET=64 # EX_USAGE
	# currently the only way to check if user is registered in a CDD is check
	# if he/she covers any role the CDD, using unixgroups backend
	elif [ -z "`getUserRoles ${CDD} ${CDDUSER}`" ]; then
		RET=1 # user has no role, so is not registered in CDD
	fi
	return ${RET}
}

# GET Functions

# getCDDList() is backend indep and is defined in ${SHAREDIR}/cdd-action

# echos the roles registered by CDD
# for Unix groups backend, it's actually the identity function
getCDDRoleList() {
	RET=0
	CDD=$1
	if [ "$#" -ne 1 ]; then
		RET=64 # EX_USAGE
	else
		checkRole ${CDD} && echo ${CDD}
	fi
	return ${RET}
}

# echoes list of users having role $2 in CDD $1
# if $4 exists use ',' as separator between user names
getUsersInRole() {
	RET=0
	CDD=$1
	ROLE=$2
	SIMPLE=$3
	USERS=""
	if [ "$#" -ne 3 -a "$#" -ne 4 ]; then
		return RET=64 # EX_USAGE
	fi
	for user in `getent group ${ROLE} | sed -ne "s/.*:\(.*\)$/\1/p" | tr "," " "` ; do
		REALNAME=" "
		if [ $SIMPLE -ne 1 ] ; then
			REALNAME=" (`grep \"^$user:\" /etc/passwd | sed \"s/^$user:[^:]\+:[0-9]\+:[0-9]\+:\([^:]\+\):.*/\1/\" | sed \"s/,.*//\"`)"
		fi
		if [ "$#" -eq 4 ]; then
			if [ "$USERS" != "" ] ; then
				USERS="${USERS},"
			fi
		fi
		if [ "$USERS" != "" ] ; then
			USERS="${USERS} "
		fi
		USERS="${USERS}${user}${REALNAME}"
	done
	echo $USERS
	return ${RET}
}

# echoes list of all users of the system
# $1 = 1 - simply login names, $1 = 0 (or anything else) - login names and real name
# if $2 exists use ',' as separator between user names
getAllUsers() {
	RET=0
	if [ "$#" -ne 1 -a "$#" -ne 2 ]; then
		RET=64 # EX_USAGE
	else
		SIMPLE=$1
		TMPFILE=`tempfile`
		(IFS=":"
			while read user pass uid gid name rest ; do
				if [ $uid -ge $FIRST_UID -a "$user" != "nobody" ] ; then
        				name=`echo $name | sed "s/,.*//"`
				        if [ $SIMPLE -eq 1 ] ; then
				                echo "$user" >> ${TMPFILE}
				        else
				                echo "$user ($name)" >> ${TMPFILE}
					fi
				fi
			done < /etc/passwd
		)
		# Append ',' if second argument is given
		if [ "$#" -eq 2 ]; then
		    sort -u "${TMPFILE}" | tr '\n' ',' | sed 's/,/&\ /g' | sed 's/, *$//g'
		else
		    sort -u "${TMPFILE}"
		fi
		rm -f "${TMPFILE}"
	fi
	return ${RET}
}
# echo all Role covered by user $2 in CDD $1
getUserRoles() {
	RET=0
	CDD=$1
	CDDUSER=$2
	if [ "$#" -ne 2 ]; then
		RET=64 # EX_USAGE
	else
		CDDROLES=`getCDDRoleList ${CDD}`
		ROLES=""
		for ROLE in ${CDDROLES}; do
			for USER in `getUsersInRole ${CDD} ${ROLE} 1`; do
				test "${USER}" == "${CDDUSER}" && \
					ROLES="${ROLES} ${ROLE}"
			done
		done
		cddDebug "getUserRoles(): roles covered by user ${CDDUSER} in CDD ${CDD}: ${ROLES}"
		echo ${ROLES}
	fi
	return ${RET}
}


# echos the home directory of the system user
getUserHome() {
	RET=0
	CDDUSER=$1
	if [ "$#" -ne 1 ]; then
		RET=64 # EX_USAGE
	else
		if checkUser ${CDDUSER}; then
			getent passwd ${CDDUSER} | sed "s/.*:\([^:]*\):[^:]*$/\1/"
			RET=$?
		else
			RET=67 # EX_NOUSER
		fi
	fi

	return ${RET}
}



# ADD/SET functions

# adds role $2 to current unix groups for the specified CDD $1, as a system
# dynamic allocated group
addRole() {
	RET=0
	CDD=$1
	ROLE=$2
	if [ "$#" -ne 2 ]; then 
		RET=64 # EX_USAGE
	else
		${DRYRUN} addgroup --system "${ROLE}" || true
		RET=$?
	fi
	return ${RET}
}

# set user $2 to have role $3, for the specified CDD $1
setUserRole() {
	RET=0
	CDD=$1
	USER=$2
	ROLE=$3
	if [ "$#" -ne 3 ]; then 
		RET=64 # EX_USAGE
	else
		${DRYRUN} adduser ${USER} ${ROLE}
		RET=$?
	fi
	return ${RET}
}

# DEL/USET Functions

# remove role $2 for the specified CDD $1 from current unix groups, as a
# system dynamic allocated group
delRole() {
	RET=0
	CDD=$1
	ROLE=$2
	if [ "$#" -ne 2 ]; then 
		RET=64 # EX_USAGE
	else
		if checkRole "${ROLE}"; then
			${DRYRUN} delgroup "${ROLE}"
			RET=$?
		else
			RET=67 # EX_NOUSER
		fi
	fi
	return ${RET}
}


# unset user $2 from having role $3, for the specified CDD $1
unsetUserRole() {
	RET=0
	CDD=$1
	CDDUSER=$2
	ROLE=$3
	# Make sure CDDUSER and ROLE are BOTH defined, 
	# to avoid disasters using deluser
	if [ "$#" -ne 3 ]; then 
		RET=64 # EX_USAGE
	else
		if checkUser "${CDDUSER}"; then
			${DRYRUN} deluser "${CDDUSER}" "${ROLE}"
			RET=$?
		else
			RET=67 # EX_NOUSER
		fi
	fi
	return ${RET}
}
