From patchwork Wed Oct 23 21:13:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Henningsen X-Patchwork-Id: 1182500 Return-Path: X-Original-To: incoming-buildroot@patchwork.ozlabs.org Delivered-To: patchwork-incoming-buildroot@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=busybox.net (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=buildroot-bounces@busybox.net; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=asklandd.dk Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=asklandd-dk.20150623.gappssmtp.com header.i=@asklandd-dk.20150623.gappssmtp.com header.b="waBmV1hl"; dkim-atps=neutral Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46z3D675bpz9sPF for ; Thu, 24 Oct 2019 08:19:34 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 07794877A5; Wed, 23 Oct 2019 21:19:33 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hmJ2V33-rB5s; Wed, 23 Oct 2019 21:19:30 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id 2B5D9856B7; Wed, 23 Oct 2019 21:19:30 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id 469741BF870 for ; Wed, 23 Oct 2019 21:19:29 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 4385584771 for ; Wed, 23 Oct 2019 21:19:29 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6uFEmzeSPmXS for ; Wed, 23 Oct 2019 21:19:27 +0000 (UTC) X-Greylist: delayed 00:06:10 by SQLgrey-1.7.6 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 494C082E12 for ; Wed, 23 Oct 2019 21:19:27 +0000 (UTC) Received: by mail-wm1-f53.google.com with SMTP id b24so378980wmj.5 for ; Wed, 23 Oct 2019 14:19:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=asklandd-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=p8jFU25UhXYnyX4JBMysclQDsw1lM34RGhrXSgXgsN4=; b=waBmV1hlC99ighC3v1t4inr3Qec4BDITDR5/ZTfUuISivl1PvxbDoJg5JWcVROJUND f+yztuRCO4gl+IJZR5aEAlVJakkR/hOF8DUgotcx/mQDkbBi+lkvF3beJhLWdaYROsyu FymjR4y9I7jbo8COACupebtqNMFyWX8pngJx7T2RvXbUrTDUi/Ew86a0VjvsDUrrXWzN F6Bkif9hNlkdJZlrSADplU+sswpaRKTKEBL8P+OyWhWt1mkOIxDH9av4W+yyRnd1Qh/7 xK5gIIwrDVgQA09N+MbsK3cEYv8WyFDIftobKmafRwqCWfTnBMdsjxhTzQBND25o5DLY zy4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=p8jFU25UhXYnyX4JBMysclQDsw1lM34RGhrXSgXgsN4=; b=ga4mxj6fzSgcnTZDbXp3fD5gEUR4RbLCH0boSfpaBmoLtzQdbDgwjENB5syPArjCPV gJt8jB8p/0IzyZlqNMVlK3hSoW3e6jdurWxOpGJuU1UKdpE6Uc+MCdVuVCWDnSAOwsIA OX8Yu3E8U1Iey2CPMqWLm9GaGt0oUOzxDwuVllo8kHZk2FtXenGIddD1WEFLY5OhvDGy XGEvS+bwGi4HbxpEb1IRCZjC5YFlwej9HuNDOcbwJjcellukeu0PqkxUE5mIQwxMbd97 I8sGCnKDqJkG7AmI4NVD2++wVArO0fKUncy13aBtnMgskTPj9lLiP7Af31goWCMWQ9WW tIRQ== X-Gm-Message-State: APjAAAWm1MTWC4JV/n2sxe3AIyQSR2UOH8lrF1XCkVENcKlHgLV7kXtc 7kVrWDF2GpmX6yu7aCcy+U+JgvrkmaA= X-Google-Smtp-Source: APXvYqysWQTZt/pO35mbOiqiAL/qJHXBdjWuF3SzrW4YDsKg4UBivyi2kBy5R3xU79SAGpapmUMFZQ== X-Received: by 2002:a1c:f401:: with SMTP id z1mr1669649wma.66.1571865194809; Wed, 23 Oct 2019 14:13:14 -0700 (PDT) Received: from lumines.sputnik.lan (static-5-186-52-63.ip.fibianet.dk. [5.186.52.63]) by smtp.gmail.com with ESMTPSA id q11sm362603wmq.21.2019.10.23.14.13.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Oct 2019 14:13:14 -0700 (PDT) From: Stephan Henningsen X-Google-Original-From: Stephan Henningsen To: buildroot@buildroot.org Date: Wed, 23 Oct 2019 23:13:13 +0200 Message-Id: <20191023211313.6758-1-stephan+buildroot@asklandd.dk> X-Mailer: git-send-email 2.17.1 Subject: [Buildroot] [PATCH 1/1] support/scripts: added support for system and normal uid/gid. X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas De Schampheleire MIME-Version: 1.0 Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" Signed-off-by: Stephan Henningsen --- docs/manual/makeusers-syntax.txt | 18 +-- support/scripts/mkusers | 196 ++++++++++++++++++++++++------- 2 files changed, 162 insertions(+), 52 deletions(-) diff --git a/docs/manual/makeusers-syntax.txt b/docs/manual/makeusers-syntax.txt index 467e596230..2c57df1a13 100644 --- a/docs/manual/makeusers-syntax.txt +++ b/docs/manual/makeusers-syntax.txt @@ -20,13 +20,17 @@ Where: It can not be +root+, and must be unique. If set to +-+, then just a group will be created. - +uid+ is the desired UID for the user. It must be unique, and not - +0+. If set to +-1+, then a unique UID will be computed by Buildroot - in the range [1000...1999] + +0+. If set to +-1+, then a unique systen UID will be computed by + Buildroot in the range [100...499]. If set to +-2+, then a unique + normal UID will be computed by Buildroot in the range [1000...1999] - +group+ is the desired name for the user's main group. It can not be +root+. If the group does not exist, it will be created. - +gid+ is the desired GID for the user's main group. It must be unique, and not +0+. If set to +-1+, and the group does not already exist, then - a unique GID will be computed by Buildroot in the range [1000..1999] + a unique system GID will be computed by Buildroot in the range + [100..499]. If set to +-2+, and the group does not already exist, + then a unique normal GID will be computed by Buildroot in the range + [1000..1999]. - +password+ is the crypt(3)-encoded password. If prefixed with +!+, then login is disabled. If prefixed with +=+, then it is interpreted as clear-text, and will be crypt-encoded (using MD5). If prefixed with @@ -57,16 +61,16 @@ will belong to the user and its main group. Examples: ---- -foo -1 bar -1 !=blabla /home/foo /bin/sh alpha,bravo Foo user +foo -1 bar -1 !=secret123 /home/foo /bin/sh alpha,bravo Foo user ---- This will create this user: - +username+ (aka login name) is: +foo+ -- +uid+ is computed by Buildroot +- +uid+ is a system uid computed by Buildroot - main +group+ is: +bar+ -- main group +gid+ is computed by Buildroot -- clear-text +password+ is: +blabla+, will be crypt(3)-encoded, and login is disabled. +- main group +gid+ is a system uid computed by Buildroot +- clear-text +password+ is: +secret123+, will be crypt(3)-encoded, and login is disabled. - +home+ is: +/home/foo+ - +shell+ is: +/bin/sh+ - +foo+ is also a member of +groups+: +alpha+ and +bravo+ diff --git a/support/scripts/mkusers b/support/scripts/mkusers index d00ba33823..ff13e81160 100755 --- a/support/scripts/mkusers +++ b/support/scripts/mkusers @@ -4,10 +4,25 @@ myname="${0##*/}" #---------------------------------------------------------------------------- # Configurable items -MIN_UID=1000 -MAX_UID=1999 -MIN_GID=1000 -MAX_GID=1999 +NEW_SYSTEM_UID=-1 +NEW_SYSTEM_GID=-1 + +MIN_SYSTEM_UID=100 +MAX_SYSTEM_UID=499 +MIN_SYSTEM_GID=100 +MAX_SYSTEM_GID=499 + +NEW_NORMAL_UID=-2 +NEW_NORMAL_GID=-2 + +MIN_NORMAL_UID=1000 +MAX_NORMAL_UID=1999 +MIN_NORMAL_GID=1000 +MAX_NORMAL_GID=1999 + +MIN_UID=-2 +MIN_GID=-2 + # No more is configurable below this point #---------------------------------------------------------------------------- @@ -19,11 +34,19 @@ error() { printf "%s: " "${myname}" >&2 printf "${fmt}" "${@}" >&2 } + fail() { error "$@" exit 1 } +# Verbose debugging, enable with e.g.: V=1 make +v() { + if [ -n "${V}" ] && [ ${V} -ge 1 ]; then + printf "${@}\\n" >&2 + fi +} + #---------------------------------------------------------------------------- if [ ${#} -ne 2 ]; then fail "usage: %s USERS_TABLE TARGET_DIR\n" @@ -125,6 +148,8 @@ check_user_validity() { local gid="${4}" local _uid _ugid _gid _username _group _ugroup + v "check_user_validity: username=$username, uid=$uid, group=$group, gid=$gid" + _group="$( get_group "${gid}" )" _gid="$( get_gid "${group}" )" _ugid="$( get_ugid "${username}" )" @@ -132,13 +157,15 @@ check_user_validity() { _uid="$( get_uid "${username}" )" _ugroup="$( get_ugroup "${username}" )" + v "... _group=$_group, _gid=$_gid, _ugid=$_ugid, _uid=$_uid, _username=$_username, _ugroup=$_ugroup" + if [ "${username}" = "root" ]; then fail "invalid username '%s\n'" "${username}" fi - if [ ${gid} -lt -1 -o ${gid} -eq 0 ]; then + if [ ${gid} -lt ${MIN_GID} -o ${gid} -eq 0 ]; then fail "invalid gid '%d' for '%s'\n" ${gid} "${username}" - elif [ ${gid} -ne -1 ]; then + elif [ ${gid} -ne ${NEW_NORMAL_GID} -a ${gid} -ne ${NEW_SYSTEM_GID} ]; then # check the gid is not already used for another group if [ -n "${_group}" -a "${_group}" != "${group}" ]; then fail "gid '%d' for '%s' is already used by group '%s'\n" \ @@ -149,7 +176,7 @@ check_user_validity() { # Need to split the check in two, otherwise '[' complains it # is missing arguments when _gid is empty if [ -n "${_gid}" ] && [ ${_gid} -ne ${gid} ]; then - fail "group '%s' for '%s' already exists with gid '%d' (wants '%d')\n" \ + fail "group '%s' for user '%s' already exists with gid '%d' (wants '%d')\n" \ "${group}" "${username}" ${_gid} ${gid} fi @@ -162,9 +189,9 @@ check_user_validity() { fi fi - if [ ${uid} -lt -1 -o ${uid} -eq 0 ]; then + if [ ${uid} -lt ${MIN_UID} -o ${uid} -eq 0 ]; then fail "invalid uid '%d' for '%s'\n" ${uid} "${username}" - elif [ ${uid} -ne -1 ]; then + elif [ ${uid} -ne ${NEW_NORMAL_UID} -o ${uid} -ne ${NEW_SYSTEM_UID} ]; then # check the uid is not already used for another user if [ -n "${_username}" -a "${_username}" != "${username}" ]; then fail "uid '%d' for '%s' already used by user '%s'\n" \ @@ -190,30 +217,56 @@ check_user_validity() { } #---------------------------------------------------------------------------- -# Generate a unique GID for given group. If the group already exists, -# then simply report its current GID. Otherwise, generate the lowest GID -# that is: +# Generate a unique *normal* GID for given group. If the group already +# exists, then simply report its current GID. Otherwise, generate the lowest +# GID that is: +# - not 0 +# - comprised in [MIN_NORMAL_GID..MAX_NORMAL_GID] +# - not already used by a group +generate_normal_gid() { + local group="${1}" + local gid + + gid="$( get_gid "${group}" )" + if [ -z "${gid}" ]; then + for(( gid=MIN_NORMAL_GID; gid<=MAX_NORMAL_GID; gid++ )); do + if [ -z "$( get_group "${gid}" )" ]; then + break + fi + done + if [ ${gid} -gt ${MAX_NORMAL_GID} ]; then + fail "can not allocate a GID for normal group '%s'\n" "${group}" + fi + fi + printf "%d\n" "${gid}" +} + +#---------------------------------------------------------------------------- +# Generate a unique *system* GID for given group. If the group already +# exists, then simply report its current GID. Otherwise, generate the lowest +# GID that is: # - not 0 -# - comprised in [MIN_GID..MAX_GID] +# - comprised in [MIN_SYSTEM_GID..MAX_SYSTEM_GID] # - not already used by a group -generate_gid() { +generate_system_gid() { local group="${1}" local gid gid="$( get_gid "${group}" )" if [ -z "${gid}" ]; then - for(( gid=MIN_GID; gid<=MAX_GID; gid++ )); do + for(( gid=MIN_SYSTEM_GID; gid<=MAX_SYSTEM_GID; gid++ )); do if [ -z "$( get_group "${gid}" )" ]; then break fi done - if [ ${gid} -gt ${MAX_GID} ]; then - fail "can not allocate a GID for group '%s'\n" "${group}" + if [ ${gid} -gt ${MAX_SYSTEM_GID} ]; then + fail "can not allocate a GID for system group '%s'\n" "${group}" fi fi printf "%d\n" "${gid}" } + #---------------------------------------------------------------------------- # Add a group; if it does already exist, remove it first add_one_group() { @@ -221,11 +274,17 @@ add_one_group() { local gid="${2}" local members + v "add_one_group: group=$group, gid=$gid" + # Generate a new GID if needed - if [ ${gid} -eq -1 ]; then - gid="$( generate_gid "${group}" )" + if [ ${gid} -eq ${NEW_NORMAL_GID} ]; then + gid="$( generate_normal_gid "${group}" )" + elif [ ${gid} -eq ${NEW_SYSTEM_GID} ]; then + gid="$( generate_system_gid "${group}" )" fi + v "...gid=$gid" + members=$(get_members "$group") # Remove any previous instance of this group, and re-add the new one sed -i --follow-symlinks -e '/^'"${group}"':.*/d;' "${GROUP}" @@ -239,25 +298,50 @@ add_one_group() { } #---------------------------------------------------------------------------- -# Generate a unique UID for given username. If the username already exists, -# then simply report its current UID. Otherwise, generate the lowest UID -# that is: +# Generate a unique *normal* UID for given username. If the username already +# exists then simply report its current UID. Otherwise, generate the lowest +# UID that is: +# - not 0 +# - comprised in [MIN_NORMAL_UID..MAX_NORMAL_UID] +# - not already used by a user +generate_normal_uid() { + local username="${1}" + local uid + + uid="$( get_uid "${username}" )" + if [ -z "${uid}" ]; then + for(( uid=MIN_NORMAL_UID; uid<=MAX_NORMAL_UID; uid++ )); do + if [ -z "$( get_username "${uid}" )" ]; then + break + fi + done + if [ ${uid} -gt ${MAX_NORMAL_UID} ]; then + fail "can not allocate a UID for normal user '%s'\n" "${username}" + fi + fi + printf "%d\n" "${uid}" +} + +#---------------------------------------------------------------------------- +# Generate a unique *system* UID for given username. If the username already +# exists then simply report its current UID. Otherwise, generate the lowest +# UID that is: # - not 0 -# - comprised in [MIN_UID..MAX_UID] +# - comprised in [MIN_SYSTEM_UID..MAX_SYSTEM_UID] # - not already used by a user -generate_uid() { +generate_system_uid() { local username="${1}" local uid uid="$( get_uid "${username}" )" if [ -z "${uid}" ]; then - for(( uid=MIN_UID; uid<=MAX_UID; uid++ )); do + for(( uid=MIN_SYSTEM_UID; uid<=MAX_SYSTEM_UID; uid++ )); do if [ -z "$( get_username "${uid}" )" ]; then break fi done - if [ ${uid} -gt ${MAX_UID} ]; then - fail "can not allocate a UID for user '%s'\n" "${username}" + if [ ${uid} -gt ${MAX_SYSTEM_UID} ]; then + fail "can not allocate a UID for system user '%s'\n" "${username}" fi fi printf "%d\n" "${uid}" @@ -303,12 +387,16 @@ add_one_user() { local comment="${9}" local _f _group _home _shell _gid _passwd + v "add_one_user: username=$username, uid=$uid, group=$group, gid=$gid, groups=$groups" + # First, sanity-check the user check_user_validity "${username}" "${uid}" "${group}" "${gid}" # Generate a new UID if needed - if [ ${uid} -eq -1 ]; then - uid="$( generate_uid "${username}" )" + if [ ${uid} -eq ${NEW_NORMAL_UID} ]; then + uid="$( generate_normal_uid "${username}" )" + elif [ ${uid} -eq ${NEW_SYSTEM_UID} ]; then + uid="$( generate_system_uid "${username}" )" fi # Remove any previous instance of this user @@ -372,11 +460,18 @@ main() { local -a ENTRIES # Some sanity checks - if [ ${MIN_UID} -le 0 ]; then - fail "MIN_UID must be >0 (currently %d)\n" ${MIN_UID} + if [ ${MIN_NORMAL_UID} -le 0 ]; then + fail "MIN_NORMAL_UID must be >0 (currently %d)\n" ${MIN_NORMAL_UID} + fi + if [ ${MIN_NORMAL_GID} -le 0 ]; then + fail "MIN_NORMAL_GID must be >0 (currently %d)\n" ${MIN_NORMAL_GID} + fi + + if [ ${MIN_SYSTEM_UID} -le 0 ]; then + fail "MIN_SYSTEM_UID must be >0 (currently %d)\n" ${MIN_SYSTEM_UID} fi - if [ ${MIN_GID} -le 0 ]; then - fail "MIN_GID must be >0 (currently %d)\n" ${MIN_GID} + if [ ${MIN_SYSTEM_GID} -le 0 ]; then + fail "MIN_SYSTEM_GID must be >0 (currently %d)\n" ${MIN_SYSTEM_GID} fi # Read in all the file in memory, exclude empty lines and comments @@ -384,33 +479,44 @@ main() { ENTRIES+=( "${line}" ) done < <( sed -r -e 's/#.*//; /^[[:space:]]*$/d;' "${USERS_TABLE}" ) - # We first create groups whose gid is not -1, and then we create groups - # whose gid is -1 (automatic), so that, if a group is defined both with - # a specified gid and an automatic gid, we ensure the specified gid is - # used, rather than a different automatic gid is computed. + # We first create groups whose gid is specific (not ANY_*_GID), + # and then we create groups whose gid is automatic (is ANY_*_GID, + # so that, if a group is defined both with a specified gid and an + # automatic gid, we ensure the specified gid is used, rather than + # a different automatic gid is computed. - # First, create all the main groups which gid is *not* automatic + # First, create all the main groups where gid is *specific*. for line in "${ENTRIES[@]}"; do read username uid group gid passwd home shell groups comment <<<"${line}" - [ ${gid} -ge 0 ] || continue # Automatic gid + [ ${gid} -ge 0 ] || continue # Automatic gid add_one_group "${group}" "${gid}" done - # Then, create all the main groups which gid *is* automatic + # Then, create all the main groups where gid is *automatic*. for line in "${ENTRIES[@]}"; do read username uid group gid passwd home shell groups comment <<<"${line}" - [ ${gid} -eq -1 ] || continue # Non-automatic gid + [ ${gid} -eq ${NEW_NORMAL_GID} -o ${gid} -eq ${NEW_SYSTEM_GID} ] || continue # Non-automatic gid add_one_group "${group}" "${gid}" done - # Then, create all the additional groups + # Then, create all the additional groups. # If any additional group is already a main group, we should use - # the gid of that main group; otherwise, we can use any gid + # the gid of that main group; otherwise, we create a normal or system gid, see below. for line in "${ENTRIES[@]}"; do read username uid group gid passwd home shell groups comment <<<"${line}" if [ "${groups}" != "-" ]; then for g in ${groups//,/ }; do - add_one_group "${g}" -1 + # If the uid or gid is already a system uid or gid, then create a system gid too; + # otherwise create normal gid + if [ ${uid} -eq ${NEW_SYSTEM_GID} -o ${gid} -eq ${NEW_SYSTEM_GID} ]; then + v "creating system group, uid=$uid, gid=$gid" + gid=${NEW_SYSTEM_GID} + else + v "creating normal group, uid=$uid, gid=$gid" + gid=${NEW_NORMAL_GID} + fi + + add_one_group "${g}" ${gid} done fi done @@ -433,7 +539,7 @@ main() { for line in "${ENTRIES[@]}"; do read username uid group gid passwd home shell groups comment <<<"${line}" [ "${username}" != "-" ] || continue # Magic string to skip user creation - [ ${uid} -eq -1 ] || continue # Non-automatic uid + [ ${uid} -eq ${NEW_NORMAL_UID} -o ${uid} -eq ${NEW_SYSTEM_UID} ] || continue # Non-automatic gid add_one_user "${username}" "${uid}" "${group}" "${gid}" "${passwd}" \ "${home}" "${shell}" "${groups}" "${comment}" done