summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass')
-rw-r--r--eclass/user.eclass88
1 files changed, 88 insertions, 0 deletions
diff --git a/eclass/user.eclass b/eclass/user.eclass
index 0e7aa43d8932..fdf98caa6099 100644
--- a/eclass/user.eclass
+++ b/eclass/user.eclass
@@ -434,6 +434,24 @@ egetcomment() {
egetent passwd "$1" | cut -d: -f${pos}
}
+# @FUNCTION: egetgroups
+# @USAGE: <user>
+# @DESCRIPTION:
+# Gets all the groups user belongs to. The primary group is returned
+# first, then all supplementary groups. Groups are ','-separated.
+egetgroups() {
+ [[ $# -eq 1 ]] || die "usage: egetgroups <user>"
+
+ local egroups_arr
+ read -r -a egroups_arr < <(id -G -n "$1")
+
+ local defgroup=${egroups_arr[0]}
+ # sort supplementary groups to make comparison possible
+ readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort)
+ local exgroups=${exgroups_arr[*]}
+ echo "${defgroup}${exgroups:+,${exgroups// /,}}"
+}
+
# @FUNCTION: esethome
# @USAGE: <user> <homedir>
# @DESCRIPTION:
@@ -623,4 +641,74 @@ esetcomment() {
esac
}
+# @FUNCTION: esetgroups
+# @USAGE: <user> <groups>
+# @DESCRIPTION:
+# Update the group field in a platform-agnostic way.
+# Required parameters is the username and the new list of groups,
+# primary group first.
+esetgroups() {
+ _assert_pkg_ebuild_phase ${FUNCNAME}
+
+ [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <user> <groups>"
+
+ # get the username
+ local euser=$1; shift
+
+ # lets see if the username already exists
+ if [[ -z $(egetent passwd "${euser}") ]] ; then
+ ewarn "User does not exist, cannot set group -- skipping."
+ return 1
+ fi
+
+ # handle group
+ local egroups=$1; shift
+
+ local g egroups_arr=()
+ IFS="," read -r -a egroups_arr <<<"${egroups}"
+ [[ ${#egroups_arr[@]} -gt 0 ]] || die "${FUNCNAME}: no groups specified"
+
+ for g in "${egroups_arr[@]}" ; do
+ if [[ -z $(egetent group "${g}") ]] ; then
+ eerror "You must add group ${g} to the system first"
+ die "${g} is not a valid GID"
+ fi
+ done
+
+ local defgroup=${egroups_arr[0]} exgroups_arr=()
+ # sort supplementary groups to make comparison possible
+ readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort)
+ local exgroups=${exgroups_arr[*]}
+ exgroups=${exgroups// /,}
+ egroups=${defgroup}${exgroups:+,${exgroups}}
+
+ # exit with no message if group membership is up to date
+ if [[ $(egetgroups "${euser}") == ${egroups} ]]; then
+ return 0
+ fi
+
+ local opts=( -g "${defgroup}" -G "${exgroups}" )
+ einfo "Updating groups for user '${euser}' ..."
+ einfo " - Groups: ${egroups}"
+
+ # update the group
+ case ${CHOST} in
+ *-freebsd*|*-dragonfly*)
+ pw usermod "${euser}" "${opts[@]}" && return 0
+ [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups"
+ eerror "There was an error when attempting to update the groups for ${euser}"
+ eerror "Please update it manually on your system:"
+ eerror "\t pw usermod \"${euser}\" ${opts[*]}"
+ ;;
+
+ *)
+ usermod "${opts[@]}" "${euser}" && return 0
+ [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups"
+ eerror "There was an error when attempting to update the groups for ${euser}"
+ eerror "Please update it manually on your system (as root):"
+ eerror "\t usermod ${opts[*]} \"${euser}\""
+ ;;
+ esac
+}
+
fi