diff options
-rw-r--r-- | helper/string.inc | 9 | ||||
-rw-r--r-- | helper/useradd.inc | 136 | ||||
-rwxr-xr-x | mltk | 1 | ||||
-rw-r--r-- | remote/tools/policykit/policykit.build | 11 |
4 files changed, 153 insertions, 4 deletions
diff --git a/helper/string.inc b/helper/string.inc new file mode 100644 index 00000000..1d15b26e --- /dev/null +++ b/helper/string.inc @@ -0,0 +1,9 @@ + +# usage: VAR=$(trim " string ") +trim() { + local var=$1 + var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters + var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters + echo -n "$var" +} + diff --git a/helper/useradd.inc b/helper/useradd.inc new file mode 100644 index 00000000..7d1f5909 --- /dev/null +++ b/helper/useradd.inc @@ -0,0 +1,136 @@ +# Add a user to the system +# +# Usage: +# either do ID_OF_REQUESTED_USER=$(add_user herbert) +# or ID_OF_USER=$(USER=herbert GROUP=somegroup PASSWORD=secret123 add_user) +# Valid params are: +# USER, GROUP, USERID, GROUPID, PASSWORD, USERHOME, USERSHELL +# defaults are no password, home=/nonexistent, usershell=/bin/false +# IDs will be generated in the range of 5-999 if not explicitly given +# TODO: Make it possible to pass a range of IDs if you don't want one <1000 but don't care about the exact ID + +. string.inc + +NAME_REGEX='^[a-z][-a-z0-9]*$' + +# Generate a UID for a given USERNAME. Return existing UID if possible, generate new one otherwise +generate_uid() +{ + [ $# -ne 1 ] && echo "generate_uid fail. want 1 argument." && exit 1 >&2 + [ -z "${_PASSWD}" ] && echo "passwd file not set." && exit 1 >&2 + local _UID=$(grep -E "^$1:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') + if [ "x${_UID}" = "x" ] + then + local _TRIES=0 + while [ ${_TRIES} -lt 50 ] + do + _TRIES=$[ ${_TRIES} + 1 ] + _UID=$[ 5 + $RANDOM % 900 ] + local _TEST=$(grep -E "^[^:]+:[^:]*:${_UID}:" "${_PASSWD}") + [ "x${_TEST}" = "x" ] && break + done + [ ${_TRIES} -ge 50 ] && echo "Generating a UID failed." && exit 1 >&2 + fi + echo ${_UID} +} + +# Generate a UID for a given USERNAME. Return existing UID if possible, generate new one otherwise +generate_gid() +{ + [ $# -ne 2 ] && echo "generate_gid fail. want 2 arguments." && exit 1 >&2 + [ -z "${_GROUP}" ] && echo "group file not set." && exit 1 >&2 + local _GID=$(grep -E "^$1:[^:]*:[0-9]+:" "${_GROUP}" | head -1 | awk -F ':' '{print $3}') + if [ "x${_GID}" = "x" ] + then + # group does not exist, try to create + local _TRIES=0 + _GID=$2 # try to use uid as gid if not taken yet + while [ ${_TRIES} -lt 50 ] + do + _TRIES=$[ ${_TRIES} + 1 ] + local _TEST=$(grep -E "^[^:]+:[^:]*:${_GID}:" "${_GROUP}") + [ "x${_TEST}" = "x" ] && break + _GID=$[ 5 + $RANDOM % 900 ] # using uid as gid not possible, generate new one + done + [ ${_TRIES} -ge 50 ] && echo "Generating a GID failed." && exit 1 >&2 + fi + echo ${_GID} +} + +add_user() { + [ -z "${INIT_DIR}" ] && echo "add_user: INIT_DIR not set" && exit 1 + if [ -z $USER -a $# -eq 0 ] + then + echo " ** add_user usage **" + echo "add_user <username>" + echo "OR" + echo "USER=<username> [GROUP=<groupname>] [USERID=<userid>] [GROUPID=<groupid>] [USERHOME=<homedir>] [USERSHELL=<shell>] [PASSWORD=<pass>] add_user" + exit 1 + fi + local _PASSWD=${INIT_DIR}/etc/passwd + local _GROUP=${INIT_DIR}/etc/group + local _SHADOW=${INIT_DIR}/etc/shadow + [ "x$USER" = "x" ] && local USER=$1 + USER=$(trim "$USER") + if ! [[ $USER =~ $NAME_REGEX ]] + then + echo "Invalid username: $USER" >&2 + exit 1 + fi + [ "x$GROUP" = "x" ] && local GROUP=$USER + GROUP=$(trim "$GROUP") + if ! [[ $GROUP =~ $NAME_REGEX ]] + then + echo "Invalid group: $GROUP" >&2 + exit 1 + fi + [ "x$USERID" = "x" ] && local USERID=$(generate_uid ${USER}) + USERID=$(trim "$USERID") + [ "$USERID" -lt "1" -o "$USERID" -gt "65535" ] && echo "Invalid userid: $USERID" && exit 1 >&2 + [ "x$GROUPID" = "x" ] && local GROUPID=$(generate_gid ${GROUP} ${USERID}) + GROUPID=$(trim "$GROUPID") + [ "$GROUPID" -lt "1" -o "$GROUPID" -gt "65535" ] && echo "Invalid groupid: $GROUPID" && exit 1 >&2 + # all required variables have been set + # does the desired username already exist? if so, check if UID matches, otherwise bail out + local _UID=$(grep -E "^${USER}:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') + [ ! -z "${_UID}" ] && [ "x${_UID}" != "x${USERID}" ] && echo "User ${USER}(${USERID}) already exists with UID ${_UID}" && exit 1 >&2 + # do the same for the group + local _GID=$(grep -E "^${GROUP}:[^:]*:[0-9]+:" "${_GROUP}" | head -1 | awk -F ':' '{print $3}') + [ ! -z "${_GID}" ] && [ "x${_GID}" != "x${GROUPID}" ] && echo "Group ${GROUP}(${GROUPID}) already exists with GID ${_GID}" && exit 1 >&2 + # if user already exists, check if he is in another group than the one requested. if so, bail out + # (TODO: don't bail out and add user to the new group) + if [ ! -z "${_UID}" ] + then + local _EXGID=$(grep -E "^${USER}:[^:]*:[0-9]+:" "${_PASSWD}" | head -1 | awk -F ':' '{print $3}') + [ "x${GROUPID}" != "x${_EXGID}" ] && echo "Requested GID $GROUPID differs from existing GID $_EXGID" && exit 1 >&2 + fi + # if user does not exist, try to add it + if [ -z "${_UID}" ] + then + local _TEST=$(grep -E "^[^:]+:[^:]*:${USERID}:" "${_PASSWD}") + [ ! -z "${_TEST}" ] && echo "Cannot add $USER - desired UID $USERID already in use." && exit 1 >&2 + fi + if [ -z "${_GID}" ] + then + local _TEST=$(grep -E "^[^:]+:[^:]*:${GROUPID}:" "${_GROUP}") + [ ! -z "${_TEST}" ] && echo "Cannot add $GROUP - desired GID $GROUPID already in use." && exit 1 >&2 + fi + [ -z "${USERHOME}" ] && local USERHOME=/nonexistent + [ -z "${USERSHELL}" ] && local USERSHELL=/bin/false + if [ -z "${_UID}" ] + then + if [ -z "${PASSWORD}" ] + then + local PASSWORD='*' + else + PASSWORD=$(sha1pass "${PASSWORD}") + [ -z "${PASSWORD}" ] && PASSWORD=$(openssl passwd -1 "${PASSWORD}") + [ -z "${PASSWORD}" ] && "Error generating hashed password for $USER" && exit 1 >&2 + fi + echo "${USER}:x:${USERID}:${GROUPID}:${USER}:${USERHOME}:${USERSHELL}" >> "${_PASSWD}" + echo "${USER}:${PASSWORD}:15555:0:99999:7:::" >> "${_SHADOW}" + fi + [ -z "${_GID}" ] && echo "${GROUP}:x:${GROUPID}:" >> "${_GROUP}" + echo "${USERID}" +} + @@ -20,6 +20,7 @@ SELF=$(readlink -f $0) ROOT_DIR=$(dirname ${SELF}) . ${ROOT_DIR}/helper/functions.common.sh +. "${ROOT_DIR}/helper/useradd.inc" banner () { echo -e "\033[38;5;202m\t __ __ __ " diff --git a/remote/tools/policykit/policykit.build b/remote/tools/policykit/policykit.build index b027cc85..db216f22 100644 --- a/remote/tools/policykit/policykit.build +++ b/remote/tools/policykit/policykit.build @@ -58,8 +58,11 @@ build () { post_copy() { #Add Polkit User/Group/Shadow to Stage3.2 - echo "polkitd:!:15756::::::" >> ${INIT_DIR}/etc/shadow - echo "polkitd:x:999:999:User for polkitd:/:/sbin/nologin" >> ${INIT_DIR}/etc/passwd - echo "polkitd:x:999:" >> ${INIT_DIR}/etc/group - + local RET=$(add_user polkitd) + if ! [[ $RET ~= [0-9]+ ]] + then + echo "USERADD FAILED: $RET" 1>&2 + exit 1 + fi } + |