Remove race in enewuser, enewgroup

We had an obvious TOCTOU problem in enewuser and enewgroup.
The code would check to see if a user or group was already
created early in these functions, then do a bunch of work
and check again. If the account was created in the meantime,
it'd barf on the second check. This check is redundant anyway
so remove it.

BUG=chromium:378270
TEST=remove accounts for a package and emerge it again
TEST=release trybot

Change-Id: If522df57468cd79466c27945b2240d9bc11ca503
Previous-Reviewed-on: https://chromium-review.googlesource.com/201831
(cherry picked from commit c6778c492f5e75819c316e75f2aae44f33534e4e)
Reviewed-on: https://chromium-review.googlesource.com/202923
Reviewed-by: Chris Masone <cmasone@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/eclass/user.eclass b/eclass/user.eclass
index 12e1b20..8f25c93 100644
--- a/eclass/user.eclass
+++ b/eclass/user.eclass
@@ -190,8 +190,11 @@
 	# Need to check if the acct exists while we hold the lock, in case
 	# another ebuild added it in the meantime.
 	local key=$(awk -F':' '{ print $1 }' <<<"${entry}")
-	if [[ -z $(egetent --nolock "${db}" "${key}" "${root}") ]] ; then
+	local existing_entry=$(egetent --nolock "${db}" "${key}" "${root}")
+	if [[ -z ${existing_entry} ]] ; then
 		echo "${entry}" >> "${dbfile}" || die "Could not write ${entry} to ${dbfile}."
+	else
+		einfo "'${entry}' superceded by '${existing_entry}'"
 	fi
 
 	rm "${lockfile}" || die "Failed to release lock on ${lockfile}."
@@ -242,13 +245,6 @@
 enewuser() {
 	_assert_pkg_ebuild_phase ${FUNCNAME}
 
-	local ACCOUNTS_DIRS
-	_find_accounts_dirs
-	if [[ ${#ACCOUNTS_DIRS[@]} -eq 0 ]] ; then
-		ewarn "No user/group data files present. Skipping."
-		return 0
-	fi
-
 	# get the username
 	local euser=$1; shift
 	if [[ -z ${euser} ]] ; then
@@ -261,6 +257,14 @@
 		return 0
 	fi
 
+	# Locate all applicable accounts profiles.
+	local ACCOUNTS_DIRS
+	_find_accounts_dirs
+	if [[ ${#ACCOUNTS_DIRS[@]} -eq 0 ]] ; then
+		ewarn "No user/group data files present. Skipping."
+		return 0
+	fi
+
 	# Ensure username exists in profile.
 	if [[ -z $(_get_value_for_user "${euser}" user) ]] ; then
 		die "'${euser}' does not exist in profile!"
@@ -303,10 +307,6 @@
 		# If profile has no entry w/UID and caller specified one, OK.
 	fi
 
-	if [[ -n $(egetent passwd ${euid}) ]] ; then
-		eerror "UID ${euid} already taken!"
-		die "${euid} already taken in $(egetent passwd ${euid})"
-	fi
 	einfo " - Userid: ${euid}"
 
 	# See if there's a provided gid and use it if so.
@@ -386,13 +386,6 @@
 enewgroup() {
 	_assert_pkg_ebuild_phase ${FUNCNAME}
 
-	local ACCOUNTS_DIRS
-	_find_accounts_dirs
-	if [[ ${#ACCOUNTS_DIRS[@]} -eq 0 ]] ; then
-		ewarn "No user/group data files present. Skipping."
-		return 0
-	fi
-
 	# Get the group.
 	local egroup=$1; shift
 	if [[ -z ${egroup} ]] ; then
@@ -404,6 +397,14 @@
 	if [[ -n $(egetent group "${egroup}") ]] ; then
 		return 0
 	fi
+
+	# Locate all applicable accounts profiles.
+	local ACCOUNTS_DIRS
+	_find_accounts_dirs
+	if [[ ${#ACCOUNTS_DIRS[@]} -eq 0 ]] ; then
+		ewarn "No user/group data files present. Skipping."
+		return 0
+	fi
 	# Ensure group exists in profile.
 	if [[ -z $(_get_value_for_group "${egroup}" group) ]] ; then
 		die "Config for ${egroup} not present in profile!"
@@ -446,10 +447,6 @@
 			die "${egid} conflicts with provided ${provided_gid}!"
 		fi
 	fi
-	if [[ -n $(egetent group ${egid}) ]] ; then
-		eerror "Groupid ${egid} already taken!"
-		die "${egid} already taken in $(egetent group ${egid})"
-	fi
 	einfo " - Groupid: ${egid}"
 
 	# Handle extra.