Message ID | 20191023211313.6758-1-stephan+buildroot@asklandd.dk |
---|---|
State | Superseded |
Headers | show |
Series | [1/1] support/scripts: added support for system and normal uid/gid. | expand |
Hi Stephan,
On 23/10/2019 23:13, Stephan Henningsen wrote:
> Signed-off-by: Stephan Henningsen <stephan+buildroot@asklandd.dk>
What exactly is the difference between a system uid and a normal uid?
I remember back in the days before dynamic uid assignment, it was customary to
make sure that the uids created by the sysadmin were in a high range, distinct
from the uids created by the package manager. I guess this was because the
package manager's uids are always local, while the sysadmin's uids could be used
over NFS. But I'm not a sysadmin :-)
However, I don't see how this could ever be relevant in a Buildroot context.
Can you give an example of how this is supposed to be used?
Regards,
Arnout
Hi. First of all: Sorry for the spam! I'm...new here. There's no technical difference between the two. It's purely organizational. Also, it's standard on all the Linux dists I've used; all except Buildroot. Yet I made this change because I was annoyed with how my /etc/passwd and /etc/group looked; my normal, real, login users were mixed up with system uids and gids (sshd, sudo, kvm, etc). At first glance user 'sshd' looks like a normal user; it has a uid of 1001 right above the normal login user at 1000 which I'd intentionally added. I'm sorry, but I think it's messy, and I'd like to clean it up. I like that uid/gid are within their usual system/normal regions; it makes it easier to see what's going on, specifically which users and groups belong to the system, and which groups that are main user groups. Just because it's an embedded system, doesn't mean we have to be sloppy about this ;) I know it may sound subjective and based on personal opinion, but it is actually conforming to standard, and I'm inclined to think it's for a reason. Also note, this change doesn't require any of the current packages to take any action; they'll simply have their users and groups moved into the normal system region from now on. My guess is that this will fit perfectly for the majority of packages. Of course, if any packages provide normal, login users, these ought to be changed to -2 instead. But nothing will break. So, that's it. Some quick links on the topic to move you in the right direction ;) - https://unix.stackexchange.com/a/80279/61306 - https://geek-university.com/linux/uid-user-identifier-gid-group-identifier/ Yours, Stephan On Thu, Oct 24, 2019 at 12:27 AM Arnout Vandecappelle <arnout@mind.be> wrote: > Hi Stephan, > > On 23/10/2019 23:13, Stephan Henningsen wrote: > > Signed-off-by: Stephan Henningsen <stephan+buildroot@asklandd.dk> > > What exactly is the difference between a system uid and a normal uid? > > I remember back in the days before dynamic uid assignment, it was > customary to > make sure that the uids created by the sysadmin were in a high range, > distinct > from the uids created by the package manager. I guess this was because the > package manager's uids are always local, while the sysadmin's uids could > be used > over NFS. But I'm not a sysadmin :-) > > However, I don't see how this could ever be relevant in a Buildroot > context. > Can you give an example of how this is supposed to be used? > > Regards, > Arnout >
Stephan, All, Please, don't top-post, that's bad etiquette; instead, intersperse your replies in the text you are replying to (like I do below). Also, do not post HTML mails, try to send only plain-text mails (html is ugly to read in a terminal, even if there's a plain0text alternative). On 2019-10-24 01:03 +0200, Stephan Henningsen spake thusly: > There's no technical difference between the two. It's purely > organizational. Also, it's standard on all the Linux dists I've used; all > except Buildroot. Buildroot is not a distribution; it is a buildsystem to generate firmware images for embedded devices. > Yet I made this change because I was annoyed with how my /etc/passwd and > /etc/group looked; my normal, real, login users were mixed up with system > uids and gids (sshd, sudo, kvm, etc). > At first glance user 'sshd' looks like a normal user; it has a uid of 1001 > right above the normal login user at 1000 which I'd intentionally added. As I already explained twice on IRC (to which you did not answer), if you have specific requirements about uids/gids, you can already provide your own /etc/passwd and /etc/group files, with the uids and gids you need. Also beware about automatic uid/gid assignent: they are not guaranteed to be stable between two versions of Buildroot and/or two different configurations. For example, consider that you do a first build with sshd (or whatever else, just an example) enabled, and it gets uid 27. You deploy this build in production, and sshd created files on a remanent filesystem. Then you decide to add new features to your device, and enable httpd (another example). httpd sorts before sshd, so will be first to get assigned a uid, and thus gets 27, while sshd now gets 42. Then you deploy your new build in production. Boom. The new sshd user can't read/write the files created by the previous sshd user, because it is no longer the same uid. To fix that, you really want to provide your own /etc/paswd and /etc/group files when you have requirements on the uid and gid assignemnts. The auto-assignment by Buildroot is a best-effort, and exists just as a starting point, but mostly as a check that no two-or-more usernames use the same uid (ditto gid). > I'm sorry, but I think it's messy, and I'd like to clean it up. I like that > uid/gid are within their usual system/normal regions; it makes it easier to > see what's going on, specifically which users and groups belong to the > system, and which groups that are main user groups. And again, as I said on IRC, the "usual system/normal regions" don't mean anything. For my use-case, I have to generate all users in the range 10000..10999. So your patches do not cover this use-case either. An alternate solution I've been working on sometime ago, was to have two new config entries: config BR2_UID_AUTO_MIN bool "lowest uid" int default 1000 help The lowest UID assigned automatically by Buildroot. config BR2_UID_AUTO_MAX bool "highest uid" int default 1999 help The gighest UID assigned automatically by Buildroot. Which would be much more interesting to have (ditto gid). Maybe I'll have time to finish it in the coming days... > Just because it's an embedded system, doesn't mean we have to be sloppy > about this ;) I know it may sound subjective and based on personal Sorry, but we're not beig sloppy. What are a "system user" or a "non-system user"? The definition is not clear at all. On an embedded device, I would argue that all users are system users, because there is no human interacting with the device like they would interact with a traditional distro. > opinion, but it is actually conforming to standard, and I'm inclined to > think it's for a reason. What standard are you refering to? > Also note, this change doesn't require any of the current packages to take > any action; they'll simply have their users and groups moved into the > normal system region from now on. My guess is that this will fit perfectly > for the majority of packages. Of course, if any packages provide normal, > login users, these ought to be changed to -2 instead. But nothing will > break. Still, I don't think that "system" vs. "non-system" users make sense, and moreover, the stability of uids/gids is much more important, and requires that packages either provide an explixit uid/gid, or that the /etc/passwd and /etc/group be provided. Regards, Yann E. MORIN.
Hi, Long mail, lots of reluctancy and personal feelings about my patch. I try to reply as good as I can. On Thu, Oct 24, 2019 at 9:11 AM Yann E. MORIN <yann.morin.1998@free.fr> wrote: > > Please, don't top-post, that's bad etiquette; instead, intersperse your > replies in the text you are replying to (like I do below). Sorry, it was not my intention. > Also, do not > post HTML mails, try to send only plain-text mails (html is ugly to read > in a terminal, even if there's a plain0text alternative). I'll try. > On 2019-10-24 01:03 +0200, Stephan Henningsen spake thusly: > > There's no technical difference between the two. It's purely > > organizational. Also, it's standard on all the Linux dists I've used; all > > except Buildroot. > > Buildroot is not a distribution; it is a buildsystem to generate > firmware images for embedded devices. It does build a Linux system, and there are best practices, conventions, and even standard for Linux systems. This is what I meant when I said "standards". I'll use the term "well-known convention", from now on; it sounds less bossy, and gives you more room for doubt =). It's far from everyday I study uid/gids. But when I do, it's typically because I need to fix some permission issue, And then a well-known convention is gold! I know exactly who uid 1000 is, I have a good idea of who uid 100 is, and an even better feeling of who 3 is. > > Yet I made this change because I was annoyed with how my /etc/passwd and > > /etc/group looked; my normal, real, login users were mixed up with system > > uids and gids (sshd, sudo, kvm, etc). > > At first glance user 'sshd' looks like a normal user; it has a uid of 1001 > > right above the normal login user at 1000 which I'd intentionally added. > > As I already explained twice on IRC (to which you did not answer), I must have overlooked it, don't take it personal. > if you have specific requirements about uids/gids, you can already provide > your own /etc/passwd and /etc/group files, with the uids and gids you > need. Oh, that. I'm not discussing special requirements. I simply argue that well-known conventions should apply to Buildroot too. Why shouldn't it? It's quite simple to correct too. And believe my patch just did that. I still hope we can discuss it at some point. > Also beware about automatic uid/gid assignent: they are not guaranteed > to be stable between two versions of Buildroot and/or two different > configurations. > > For example, consider that you do a first build with sshd (or whatever > else, just an example) enabled, and it gets uid 27. You deploy this > build in production, and sshd created files on a remanent filesystem. > Then you decide to add new features to your device, and enable httpd > (another example). httpd sorts before sshd, so will be first to get > assigned a uid, and thus gets 27, while sshd now gets 42. Then you > deploy your new build in production. > > Boom. The new sshd user can't read/write the files created by the > previous sshd user, because it is no longer the same uid. > > To fix that, you really want to provide your own /etc/paswd and > /etc/group files when you have requirements on the uid and gid > assignemnts. > > The auto-assignment by Buildroot is a best-effort, and exists just as a > starting point, but mostly as a check that no two-or-more usernames use > the same uid (ditto gid). How does offsetting the uid/gids from 1000 to 100 in Buildroot's mkusers script change any of this? > > I'm sorry, but I think it's messy, and I'd like to clean it up. I like that > > uid/gid are within their usual system/normal regions; it makes it easier to > > see what's going on, specifically which users and groups belong to the > > system, and which groups that are main user groups. > > And again, as I said on IRC, the "usual system/normal regions" don't > mean anything. But that's where you're wrong; they do mean something. I already explained it. I gave examples. Both here and on IRC. I'm aware that from the system's perspective, their numerical region is of no importance, only their value is. However, don't care about the system's perspective; I'm speaking from the user's perspective. That's why we both keep referring to /etc/passwd and /etc/group; their purpose is to map system's ids to names meaningful to the user (the admin). And here regions make sense. And if there are users that don't care about regions, I don't see there should a problem with my patch. > For my use-case, I have to generate all users in the > range 10000..10999. So your patches do not cover this use-case either. So the regions do have meaning for you too! I'm guessing that the reason you blow your user region off-chart like that, is because Buildroot has already occupied the standard user region with its system users. And you want that numerical space so you can clearly differ system users from your normal users. And you're right, my patch doesn't support your special requirements. But it doesn't interfere with them either. I could argue that it actually helps you, as you would no longer have to add fixed uids but could use -2 to have them auto generated into user region (if that's an option). > An alternate solution I've been working on sometime ago, was to have two > new config entries: > > config BR2_UID_AUTO_MIN > bool "lowest uid" > int > default 1000 > help > The lowest UID assigned automatically by Buildroot. > > config BR2_UID_AUTO_MAX > bool "highest uid" > int > default 1999 > help > The gighest UID assigned automatically by Buildroot. > > Which would be much more interesting to have (ditto gid). So not 2 but 4 new configuration entries. > Maybe I'll have time to finish it in the coming days... I'd advise you correct your defaults to standard. Still I think it's a lot of configuration options just to allow someone to break the standard and configure for special requirements. This should be fixed by adding custom /etc/passwd and /etc/group files. You said so yourself. > > Just because it's an embedded system, doesn't mean we have to be sloppy > > about this ;) I know it may sound subjective and based on personal > > Sorry, but we're not beig sloppy. What are a "system user" or a > "non-system user"? The definition is not clear at all. Oh yes you do, mr. +10000 uid. > On an embedded > device, I would argue that all users are system users, because there is > no human interacting with the device like they would interact with a > traditional distro. Then it would be sane to move the default users into the system uid/gid region. On a side note: I'm currently working on creating a light-weight Linux that boots of a USB, and it will require a normal user login. And guessing by your 10000..10999 uid range I suspect you're familiar with user interaction. In any case, people use Buildroot to create all sorts of systems. > > opinion, but it is actually conforming to standard, and I'm inclined to > > think it's for a reason. > > What standard are you refering to? Yes, well I was mostly referring to my observations of a "best practice" or "common approach" on various Linux dists I've come across. But it appears Debian has a standard: https://www.debian.org/doc/debian-policy/ch-opersys.html#uid-and-gid-classes There's a nice write-up here: https://unix.stackexchange.com/a/319751/61306 > > Also note, this change doesn't require any of the current packages to take > > any action; they'll simply have their users and groups moved into the > > normal system region from now on. My guess is that this will fit perfectly > > for the majority of packages. Of course, if any packages provide normal, > > login users, these ought to be changed to -2 instead. But nothing will > > break. > > Still, I don't think that "system" vs. "non-system" users make sense, Still? Another option could also be to just offset the autogenerated uid/gids from 1000 into 100, and don't add that -2 fix. I still think it would be a nice addition to help users create normal users. I even updated the documentation about it. Oh this reminds me, that I or we should probably have a look that /etc/adduser.conf or its equivalent on Buildroot. It should match the mkusers script I think, but I don't have a running system, so I'm just speculating. > and moreover, the stability of uids/gids is much more important, and > requires that packages either provide an explixit uid/gid, or that the > /etc/passwd and /etc/group be provided. Sorry I'm misunderstanding you here and not answering within context: But all my script does, it offset the autogenerated uid/gid into the right region; I'm not touching packages' explicit uid/gid. I haven't touched any packages at all. I'm aware that you don't agree to the well-known notion - or even the Debian standard - of system and normal user id ranges. But how is it you find that my patch *breaks* anything? -- Yours, Stephan
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
Signed-off-by: Stephan Henningsen <stephan+buildroot@asklandd.dk> --- docs/manual/makeusers-syntax.txt | 18 +-- support/scripts/mkusers | 196 ++++++++++++++++++++++++------- 2 files changed, 162 insertions(+), 52 deletions(-)