Skip to contentSkip to conversation

Pull request for branch yem-package-create-user

GIT PULL New Yann E. MORIN 4 participants 13 messages Jan 1, 2013 – Jan 3, 2013 VFS

lore
Share & tools
lore
#0 lore raw

Hello All!

Here is a series that allows packages to create users.

Packages that install daemons may well want to run those daemons as non-root users to avoid security issues. Currently, there are two users of choice to run 'generic' daemons: root or daemon (although there are a few dedicated users to run a few services: mail, sshd, ftp...).

This series builds upon both the package infrastrucutre to define the user(s) a package may want to create, and the filesystem infrastructure to actually generate these users, and chown their ${HOME}s.

Documentation is updated accordingly.

Note: for now, users' passwords are md5-encrypted. Once the pending change to introduce alternative password-encryption schemes is applied, we can use that to encode users' passwords, too.

As a proof of concept, the package tvheadend has been updated to use a dedicated user to run its daemon as (call me stubborn! ;-] ).

Changes v1 -. v2:
- drop the gshadow patch (Thomas)
- tvheadend user is now part of the video secondary group

The following changes since commit 560e7db37433fc82760f71557dbc3e495f05f909:

efl/libecore: fix build with gcrypt (2013-01-01 15:34:40 +0100)

are available in the git repository at:
git://gitorious.org/buildroot/buildroot.git yem-package-create-user

Yann E. MORIN (2):
packages: add ability for packages to create users package/tvheadend: use a non-root user to run the daemon

 docs/manual/adding-packages-generic.txt |   16 ++-
 docs/manual/makedev-syntax.txt          |   65 ++++++
 fs/common.mk                            |    5 +-
 package/pkg-generic.mk                  |    1 +
 package/tvheadend/etc.default.tvheadend |    5 +-
 package/tvheadend/tvheadend.mk          |   10 +-
 support/scripts/mkusers                 |  348 +++++++++++++++++++++++++++++++
 7 files changed, 442 insertions(+), 8 deletions(-)
 create mode 100755 support/scripts/mkusers

Regards,
Yann E. MORIN

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#1 lore raw

PATCH 1/2 packages: add ability for packages to create users

Packages that install daemons may need those daemons to run as a non-root, or an otherwise non-system (eg. 'daemon'), user.

Add infrastructure for packages to create users, by declaring the FOO_USERS variable that conatin a makedev-syntax-like description of the user(s) to add.

---
 docs/manual/adding-packages-generic.txt |   16 ++-
 docs/manual/makedev-syntax.txt          |   65 ++++++
 fs/common.mk                            |    5 +-
 package/pkg-generic.mk                  |    1 +
 support/scripts/mkusers                 |  348 +++++++++++++++++++++++++++++++
 5 files changed, 432 insertions(+), 3 deletions(-)
 create mode 100755 support/scripts/mkusers
docs/manual/adding-packages-generic.txt +14 -2
index 0759d4f..1adf424 100644
@@ -50,7 +50,11 @@ system is based on hand-written Makefiles or shell scripts.
 34:	/bin/foo  f  4755  0  0	 -  -  -  -  -
 35: endef
 36:
-37: $(eval $(generic-package))
+37: define LIBFOO_USERS
+38: foo -1 libfoo -1 * - - - LibFoo daemon
+39: endef
+40
+41: $(eval $(generic-package))
 --------------------------------
 
 The Makefile begins on line 6 to 10 with metadata information: the
@@ -95,7 +99,10 @@ On line 29..31, we define a device-node file used by this package
 On line 33..35, we define the permissions to set to specific files
 installed by this package (+LIBFOO_PERMISSIONS+).
 
-Finally, on line 37, we call the +generic-package+ function, which
+On lines 37..39, we define a user that is used by this package (eg.
+to run a daemon as non-root).
+
+Finally, on line 41, we call the +generic-package+ function, which
 generates, according to the variables defined previously, all the
 Makefile code necessary to make your package working.
 
@@ -252,6 +259,11 @@ information is (assuming the package name is +libfoo+) :
   You can find some documentation for this syntax in the xref:makedev-syntax[].
   This variable is optional.
 
+* +LIBFOO_USERS+ lists the users to create for this package, if it installs
+  a daemon you want to run with a specific user. The syntax is similar in
+  spirit to the makedevs one, and is described in the xref:makeuser-syntax[].
+  This variable is optional.
+
 * +LIBFOO_LICENSE+ defines the license (or licenses) under which the package
   is released.
   This name will appear in the manifest file produced by +make legal-info+.
docs/manual/makedev-syntax.txt +65 -0

68 lines not on this page · raw message

fs/common.mk +4 -1
index b1512dd..b5a7950 100644
@@ -35,6 +35,7 @@ FAKEROOT_SCRIPT = $(BUILD_DIR)/_fakeroot.fs
 FULL_DEVICE_TABLE = $(BUILD_DIR)/_device_table.txt
 ROOTFS_DEVICE_TABLES = $(call qstrip,$(BR2_ROOTFS_DEVICE_TABLE)) \
 	$(call qstrip,$(BR2_ROOTFS_STATIC_DEVICE_TABLE))
+USERS_TABLE = $(BUILD_DIR)/_users_table.txt
 
 define ROOTFS_TARGET_INTERNAL
 
@@ -55,11 +56,13 @@ endif
 	printf '$(subst $(sep),\n,$(PACKAGES_PERMISSIONS_TABLE))' >> $(FULL_DEVICE_TABLE)
 	echo "$(HOST_DIR)/usr/bin/makedevs -d $(FULL_DEVICE_TABLE) $(TARGET_DIR)" >> $(FAKEROOT_SCRIPT)
 endif
+	printf '$(subst $(sep),\n,$(PACKAGES_USERS))' > $(USERS_TABLE)
+	$(TOPDIR)/support/scripts/mkusers $(USERS_TABLE) $(TARGET_DIR) >> $(FAKEROOT_SCRIPT)
 	echo "$(ROOTFS_$(2)_CMD)" >> $(FAKEROOT_SCRIPT)
 	chmod a+x $(FAKEROOT_SCRIPT)
 	$(HOST_DIR)/usr/bin/fakeroot -- $(FAKEROOT_SCRIPT)
 	cp support/misc/target-dir-warning.txt $(TARGET_DIR_WARNING_FILE)
-	- at rm -f $(FAKEROOT_SCRIPT) $(FULL_DEVICE_TABLE)
+	- at rm -f $(FAKEROOT_SCRIPT) $(FULL_DEVICE_TABLE) $(USERS_TABLE)
 	$(foreach hook,$(ROOTFS_$(2)_POST_GEN_HOOKS),$(call $(hook))$(sep))
 ifeq ($$(BR2_TARGET_ROOTFS_$(2)_GZIP),y)
 	gzip -9 -c $$@ > [email protected]
package/pkg-generic.mk +1 -0
index a570ad7..871544c 100644
@@ -510,6 +510,7 @@ ifeq ($$($$($(2)_KCONFIG_VAR)),y)
 TARGETS += $(1)
 PACKAGES_PERMISSIONS_TABLE += $$($(2)_PERMISSIONS)$$(sep)
 PACKAGES_DEVICES_TABLE += $$($(2)_DEVICES)$$(sep)
+PACKAGES_USERS += $$($(2)_USERS)$$(sep)
 
 ifeq ($$($(2)_SITE_METHOD),svn)
 DL_TOOLS_DEPENDENCIES += svn
support/scripts/mkusers new file +348 -0

348 lines not on this page · raw message

Signature · 1 line
1.7.2.5
#2 lore raw

PATCH 1/2 packages: add ability for packages to create users

Hi Yann, all,

2013/1/1 Yann E. MORIN <[email protected]>:

Quoted 9 lines

Packages that install daemons may need those daemons to run as a non-root, or an otherwise non-system (eg. 'daemon'), user.

Add infrastructure for packages to create users, by declaring the FOO_USERS variable that conatin a makedev-syntax-like description of the user(s) to add.

---

[snip]

docs/manual/makedev-syntax.txt

Quoted 16 lines
docs/manual/adding-packages-generic.txt +5 -0
@@ -252,6 +259,11 @@ information is (assuming the package name is +libfoo+) :
   You can find some documentation for this syntax in the xref:makedev-syntax[].
   This variable is optional.
 
+* +LIBFOO_USERS+ lists the users to create for this package, if it installs
+  a daemon you want to run with a specific user. The syntax is similar in
+  spirit to the makedevs one, and is described in the xref:makeuser-syntax[].
+  This variable is optional.
+
 * +LIBFOO_LICENSE+ defines the license (or licenses) under which the package
   is released.
   This name will appear in the manifest file produced by +make legal-info+.
docs/manual/makedev-syntax.txt +0 -0
index 27517b3..fffdac9 100644

You could add this in a new file...
Why should makedev-syntax.txt contain syntax details for makedev and mkusers?

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 63

Quoted 11 lines
docs/manual/makedev-syntax.txt +7 -0
@@ -54,3 +54,68 @@ and then for device files corresponding to the partitions of
 /dev/hda       b       640     0       0       3       1       1       1       15
 -------------------------------------------------------------------
 
+
+[[makeuser-syntax]]
+Makeuser syntax documentation
+-----------------------------
+
+The syntax to create users is inspired by the makedev syntax, above, but
+is psecific to buildroot.

s/psecific/specific/

Quoted 4 lines
docs/manual/makedev-syntax.txt +4 -0
+
+The syntax for adding a user is a space-separated list of fields, one
+user per-line; the fields are:
+

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 77

Quoted 10 lines
docs/manual/makedev-syntax.txt +10 -0
+|=================================================================
+|username |uid |group |gid |password |home |shell |groups |comment
+|=================================================================
+
+Where:
+
+- +username+ is the desired user name (aka login name) for the user.
+  It must be unique.
+- +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.

s/buildroot/Buildroot/

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 81

Quoted 4 lines
docs/manual/makedev-syntax.txt +4 -0
+- +group+ is the desired name for the user's main group.
+- +gid+ is the desired GID for the user's main group. It must be unique,
+  and not +0+. If set to +-1+, then a unique GID will be computed by
+  buildroot.

ditto

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 83

Quoted 2 lines
docs/manual/makedev-syntax.txt +2 -0
+- +password+ is the crypt(3)-encrypted password. If prefixed with +=+,
+  then it is interpreted as clear-text, and will be cypt-encoded. If

s/cypt-encoded/crypt-encoded/

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 85

Quoted 2 lines
docs/manual/makedev-syntax.txt +2 -0
+  prefixed with +!+, then login is disabled. If set to +*+, then login
+  is not allowed.

Multiple prefix is allowed/supported; it could be explicitly mentioned. Is the prefix order important?

So, the clear-text password itself should not starts with any prefix character?

Quoted 19 lines
docs/manual/makedev-syntax.txt +19 -0
+- +home+ is the desired home directory for the user. If set to '-', no
+  home directory will be created, and the user's home will be +/+.
+  Explicitly setting +home+ to +/+ is not allowed.
+- +shell+ is the desired shell for the user. If set to +-+, then
+  +/bin/false+ is set as the user's shell.
+- +groups+ is the comma-separated list of additional groups the user
+  should be part of. If set to +-+, then the user will be a member of
+  no additional group.
+- +comment+ is an almost-free-form text.
+
+There are a few restrictions on the content of each field:
+
+* except for +comment+, all fields are mandatory.
+* except for +comment+, fields may not contain spaces.
+* no field may contain a column (+:+).
+
+If +home+ is not +-+, then the home directory, and all files below,
+will belong to the user and its main group.
+

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 114

Quoted 10 lines
docs/manual/makedev-syntax.txt +10 -0
+Example:
+
+----
+foo -1 bar -1 !=blabla /home/foo /bin/sh alpha,bravo Foo user
+----
+
+This will create this user:
+
+- +username+ (aka login name) is: +foo+
+- +uid+ is computed by buildroot

ditto

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 116

Quoted 2 lines
docs/manual/makedev-syntax.txt +2 -0
+- main +group+ is: +bar+
+- main group +gid+ is computed by buildroot

ditto

Quoted 5 lines
docs/manual/makedev-syntax.txt +5 -0
+- clear-text +password+ is: +blabla+, will be crypt(3)-encrypted, but login is disabled.
+- +home+ is: +/home/foo+
+- +shell+ is: +/bin/sh+
+- +foo+ is also a member of +groups+: +alpha+ and +bravo+
+- +comment+ is: +Foo user+

[snip]

Quoted 15 lines
support/scripts/mkusers new file +12 -0
@@ -0,0 +1,348 @@
+#!/bin/bash
+set -e
+myname="${0##*/}"
+
+#----------------------------------------------------------------------------
+# Configurable items
+MIN_UID=1000
+MAX_UID=1999
+MIN_GID=1000
+MAX_GID=1999
+# No more is configurable below this point
+#----------------------------------------------------------------------------

support/scripts/mkusers line 22

Quoted 10 lines
support/scripts/mkusers new file +10 -0
+
+#----------------------------------------------------------------------------
+USERS_TABLE="${1}"
+TARGET_DIR="${2}"
+shift 2
+PASSWD="${TARGET_DIR}/etc/passwd"
+SHADOW="${TARGET_DIR}/etc/shadow"
+GROUP="${TARGET_DIR}/etc/group"
+# /etc/gsahdow is not part of the standard skeleton, so not everybody
+# will have it, but some may hav it, and its content must be in sync

s/hav/have/

Regards,

Signature · 1 line
Samuel
#3 lore raw

PATCH 1/2 packages: add ability for packages to create users

Smartin, All,

Quoted 7 lines · On Tuesday 01 January 2013 Samuel Martin wrote:

2013/1/1 Yann E. MORIN <[email protected]>:

Quoted 6 lines

Packages that install daemons may need those daemons to run as a non-root, or an otherwise non-system (eg. 'daemon'), user.

Add infrastructure for packages to create users, by declaring the FOO_USERS variable that conatin a makedev-syntax-like description of the user(s) to add.

[--SNIP--]

Quoted 6 lines

docs/manual/makedev-syntax.txt

Quoted 4 lines
docs/manual/makedev-syntax.txt +0 -0
index 27517b3..fffdac9 100644

You could add this in a new file...
Why should makedev-syntax.txt contain syntax details for makedev and mkusers?

Right, I'll do.

Quoted 8 lines

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 85

Quoted 4 lines

+- +password+ is the crypt(3)-encrypted password. If prefixed with +=+,

docs/manual/makedev-syntax.txt +3 -0
+  then it is interpreted as clear-text, and will be cypt-encoded. If
+  prefixed with +!+, then login is disabled. If set to +*+, then login
+  is not allowed.

Multiple prefix is allowed/supported; it could be explicitly mentioned. Is the prefix order important?

So, the clear-text password itself should not starts with any prefix character?

Oh! You raise a valid point here. In fact, I coded '=!' as being the same as '!=' , which it clearly is not.

So, valid combinations are:

    *           no password, login not allowed
    XXXX        crypt-encoded password
    !XXXX       crypt-encoded password, login disabled
    =1234       clear-text password
    !=1234      clear-text password, login disabled

Thank you!

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#4 lore raw

PATCH 1/2 packages: add ability for packages to create users

Samuel, All,

Quoted 2 lines · On Tuesday 01 January 2013 Yann E. MORIN wrote:
Quoted 1 line · On Tuesday 01 January 2013 Samuel Martin wrote:

2013/1/1 Yann E. MORIN <[email protected]>:

[--SNIP--]

Quoted 8 lines
Quoted 8 lines

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 85

Quoted 4 lines

+- +password+ is the crypt(3)-encrypted password. If prefixed with +=+,

docs/manual/makedev-syntax.txt +3 -0
+  then it is interpreted as clear-text, and will be cypt-encoded. If
+  prefixed with +!+, then login is disabled. If set to +*+, then login
+  is not allowed.

Multiple prefix is allowed/supported; it could be explicitly mentioned. Is the prefix order important?

So, the clear-text password itself should not starts with any prefix character?

[--SNIP--]

Quoted 6 lines

So, valid combinations are:

    *           no password, login not allowed
    XXXX        crypt-encoded password
    !XXXX       crypt-encoded password, login disabled
    =1234       clear-text password
    !=1234      clear-text password, login disabled

And of course, '!' and '=' are not in the set of characters that crypt can emit for an encoded password, so it is legit to write:

    =           empty password
    =!foo       clear-text password starts with a '!'
    ==bar       clear-text password starts with a '='
    !=          empty password                       , login is disabled
    !=!foo      clear-text password starts with a '!', login is disabled
    !==bar      clear-text password starts with a '=', login is disabled

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#5 lore raw

PATCH 1/2 packages: add ability for packages to create users

In reply to Yann E. MORIN

docs/manual/adding-packages-generic.txt information is (assuming the package name is +libfoo+) : · line 263

Quoted 2 lines · Yann E. MORIN
docs/manual/adding-packages-generic.txt +2 -0
+* +LIBFOO_USERS+ lists the users to create for this package, if it installs
+  a daemon you want to run with a specific user. The syntax is similar in

"if it installs a program you want to run as a specific user"

that is, s/daemon/program/ and s/with/as/

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 81

Quoted 4 lines
+- +group+ is the desired name for the user's main group.
+- +gid+ is the desired GID for the user's main group. It must be unique,
docs/manual/makedev-syntax.txt +2 -0
+  and not +0+. If set to +-1+, then a unique GID will be computed by
+  buildroot.

I think this is saying it creates groups as well as users. If so, the documentation should say so.

Also, how do you specifiy that you do not want a group created - such as when you want a new user in an existing system group. I would assume something like

foo -1 daemon -1 ...

to create user "foo" in the system "daemon" group, but the documentation implies a new GID will be allocated.

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 85

Quoted 4 lines

+- +password+ is the crypt(3)-encrypted password. If prefixed with +=+,

docs/manual/makedev-syntax.txt +3 -0
+  then it is interpreted as clear-text, and will be cypt-encoded. If
+  prefixed with +!+, then login is disabled. If set to +*+, then login
+  is not allowed.

What is the status of the support of other encryption algorithms? e.g. $6$salt$enc for SHA-512 encrypted passwords? This will depend on settings in BuildRoot itself, but it would be worth making a reference here since it is relevant to a user providing encrypted user passwords.

Quoted 1 line

+set -e

....

support/scripts/mkusers line 17

Quoted 3 lines
support/scripts/mkusers new file +3 -0
+USERS_TABLE="${1}"
+TARGET_DIR="${2}"
+shift 2

This will fail under 'set -e' if there are less than two parameters, but fail without any useful diagnostics. An error/usage message here would be useful.

support/scripts/mkusers line 32

Quoted 7 lines
support/scripts/mkusers new file +7 -0
+#----------------------------------------------------------------------------
+error() {
+    local fmt="${1}"
+    shift
+
+    printf "%s: " "${myname}" >&2
+    printf "${fmt}" "${@}" >&2

I think you should put a \n in the format string here. Every call to this function (via fail) includes a \n, so it seems redundant require each caller to put a \n on the string. In fact, the last call to fail does not have a \n in the string which it should, so this will also fix what would probably become a common error.

support/scripts/mkusers line 43

Quoted 11 lines
support/scripts/mkusers new file +11 -0
+}
+fail() {
+    error "$@"
+    exit 1
+}
+
+#----------------------------------------------------------------------------
+get_uid() {
+    local username="${1}"
+
+    grep -r -E "${username}:" "${PASSWD}" |cut -d: -f3

Why grep -r? A recursive grep with a filename (non-directory) as an argument does not do anything different without -r. Ditto for get_ugid and get_gid.

Why grep -E? You are not using any features of extended regular expressions. An argument could be made that you should be using grep -F.

You should also anchor ${username} to the start of the line or you may get false matches:

  grep "^${username}:" "${PASSWD}"

ditto get_ugid and get_gid.

Quoted 11 lines
support/scripts/mkusers new file +11 -0
+}
+
+#----------------------------------------------------------------------------
+get_ugid() {
+    local username="${1}"
+
+    grep -r -E "${username}:" "${PASSWD}" |cut -d: -f4
+}
+
+#----------------------------------------------------------------------------
+get_gid() {

support/scripts/mkusers line 64

Quoted 10 lines
support/scripts/mkusers new file +10 -0
+    local group="${1}"
+
+    grep -r -E "${group}:" "${GROUP}" |cut -d: -f3
+}
+
+#----------------------------------------------------------------------------
+get_username() {
+    local uid="${1}"
+
+    sed -r -e '/^([^:]+):[^:]+:'"${uid}"':.*/!d; s//\1/;' "${PASSWD}"

Is awk available in the host toolchain? If so, this would be much clearer with awk:

  awk -F: '$3 == '"${uid}"' { print $1 }' "${PASSWD}"

ditto get_group

Quoted 33 lines
support/scripts/mkusers new file +33 -0
+}
+
+#----------------------------------------------------------------------------
+get_group() {
+    local gid="${1}"
+
+    sed -r -e '/^([^:]+):[^:]+:'"${gid}"':/!d; s//\1/;' "${GROUP}"
+}
+
+#----------------------------------------------------------------------------
+get_ugroup() {
+    local username="${1}"
+    local ugid
+
+    ugid="$( get_ugid "${username}" )"
+    if [ -n "${ugid}" ]; then
+        get_group "${ugid}"
+    fi
+}
+
+#----------------------------------------------------------------------------
+# Sanity-check the new user/group:
+#   - check the gid is not already used for another group
+#   - check the group does not already exist with another gid
+#   - check the user does not already exist with another gid
+#   - check the uid is not already used for another user
+#   - check the user does not already exist with another uid
+#   - check the user does not already exist in another group
+check_user_validity() {
+    local username="${1}"
+    local uid="${2}"
+    local group="${3}"
+    local gid="${4}"

support/scripts/mkusers line 107

Quoted 10 lines
support/scripts/mkusers new file +10 -0
+    local _uid _ugid _gid _username _group _ugroup
+
+    _group="$( get_group "${gid}" )"
+    _gid="$( get_gid "${group}" )"
+    _ugid="$( get_ugid "${username}" )"
+    _username="$( get_username "${uid}" )"
+    _uid="$( get_uid "${username}" )"
+    _ugroup="$( get_ugroup "${username}" )"
+
+    if [ ${gid} -ge 0 ]; then

Elsewhere in this script you check uid/gid against -1, not >= 0. This should be changed to "${gid} -eq -1" to be consistent with that and the documentation.

support/scripts/mkusers line 272

Quoted 5 lines
support/scripts/mkusers new file +5 -0
+    case "${home}" in
+        -)  _home="/";;
+        /)  fail "home can not be explicitly '/'\n";;
+        /*) _home="${home}";;
+        *)  fail "home must be an absolute path";;

This is where you missed the \n in the error message.

There is also another spelling mistake somewhere :-) I noticed three when I first skimmed this patch; two have already been pointed out; and I did not see the third when I went through to comment.

#6 lore raw

PATCH 1/2 packages: add ability for packages to create users

Cam, All,

Quoted 8 lines · On Wednesday 02 January 2013 Cam Hutchison wrote:

docs/manual/adding-packages-generic.txt information is (assuming the package name is +libfoo+) : · line 263

Quoted 2 lines · Yann E. MORIN
docs/manual/adding-packages-generic.txt +2 -0
+* +LIBFOO_USERS+ lists the users to create for this package, if it installs
+  a daemon you want to run with a specific user. The syntax is similar in

"if it installs a program you want to run as a specific user"

that is, s/daemon/program/ and s/with/as/

Well, I would like to emphasise that this is primarily for running programs as daemons (ie. started by startup scripts). It does not really make sense to run program as a specific user when logged in, especially for embedded systems, where logging in a seldom done.

What about:

... if it installs a daemon program you want to run as ...

Quoted 7 lines

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 81

Quoted 4 lines
+- +group+ is the desired name for the user's main group.
+- +gid+ is the desired GID for the user's main group. It must be unique,
docs/manual/makedev-syntax.txt +2 -0
+  and not +0+. If set to +-1+, then a unique GID will be computed by
+  buildroot.

I think this is saying it creates groups as well as users. If so, the documentation should say so.

OK.

Quoted 8 lines

Also, how do you specifiy that you do not want a group created - such as when you want a new user in an existing system group. I would assume something like

foo -1 daemon -1 ...

to create user "foo" in the system "daemon" group, but the documentation implies a new GID will be allocated.

Ah, yes. If the group already exists (because it is in the skeleton, or because a previous user added it), then the GID for that group is used, no new GID is created, of course.

I'll add this to the doc. Good catch!

Quoted 9 lines

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 85

Quoted 4 lines

+- +password+ is the crypt(3)-encrypted password. If prefixed with +=+,

docs/manual/makedev-syntax.txt +3 -0
+  then it is interpreted as clear-text, and will be cypt-encoded. If
+  prefixed with +!+, then login is disabled. If set to +*+, then login
+  is not allowed.

What is the status of the support of other encryption algorithms? e.g. $6$salt$enc for SHA-512 encrypted passwords? This will depend on settings in BuildRoot itself, but it would be worth making a reference here since it is relevant to a user providing encrypted user passwords.

First, this is not meant for buildroot users, but for buildroot developpers. This makes a huge difference, but shall be documented nonetheless, of course.

If the developper enters an already-encoded des/md5/sha256/sha512 pasword (ie. a password that does not start with '=') then the content is used as-is.

The current password encoding is md5 ($1$salt$...).

Once my other patch to add selection of an alternative encoding, I'll use that here, too:

    http://lists.busybox.net/pipermail/buildroot/2012-December/064411.html
Quoted 8 lines
Quoted 1 line

+set -e

....

support/scripts/mkusers line 17

Quoted 3 lines
support/scripts/mkusers new file +3 -0
+USERS_TABLE="${1}"
+TARGET_DIR="${2}"
+shift 2

This will fail under 'set -e' if there are less than two parameters, but fail without any useful diagnostics. An error/usage message here would be useful.

OK.

Quoted 5 lines
Quoted 5 lines
support/scripts/mkusers new file +5 -0
+#----------------------------------------------------------------------------
+error() {
+    local fmt="${1}"
+    shift
+
Quoted 8 lines

support/scripts/mkusers line 32

Quoted 2 lines
support/scripts/mkusers new file +2 -0
+    printf "%s: " "${myname}" >&2
+    printf "${fmt}" "${@}" >&2

I think you should put a \n in the format string here. Every call to this function (via fail) includes a \n, so it seems redundant require each caller to put a \n on the string. In fact, the last call to fail does not have a \n in the string which it should, so this will also fix what would probably become a common error.

I prefer to keep the \n is every calls. The missing one is an bug.

Quoted 5 lines
Quoted 5 lines
support/scripts/mkusers new file +5 -0
+}
+fail() {
+    error "$@"
+    exit 1
+}
Quoted 8 lines

support/scripts/mkusers line 43

Quoted 6 lines
support/scripts/mkusers new file +6 -0
+
+#----------------------------------------------------------------------------
+get_uid() {
+    local username="${1}"
+
+    grep -r -E "${username}:" "${PASSWD}" |cut -d: -f3

Why grep -r?

Indeed.

Quoted 1 line

Why grep -E? You are not using any features of extended regular expressions.

Because I *always* use 'grep -E', and I /forgot/ what is a standard regexp. But I can remove, yes.

Quoted 1 line

An argument could be made that you should be using grep -F.

I don't know (ie. I don't usualy use) this switch, so I am not confident in using it here. If plain 'grep' does the job, lets just use that.

Quoted 1 line

You should also anchor ${username}

Yes, indeed.

Quoted 6 lines

support/scripts/mkusers line 64

Quoted 4 lines
support/scripts/mkusers new file +4 -0
+get_username() {
+    local uid="${1}"
+
+    sed -r -e '/^([^:]+):[^:]+:'"${uid}"':.*/!d; s//\1/;' "${PASSWD}"

Is awk available in the host toolchain?

Nopt systematically. There's host-gawk that package can depend on. If we were to use awk instead of sed, then host-gawk would always be built as soon as a rootfs image (fs/tarball/...) is generated.

So, I prefer to keep using sed for now, unless Peter agrees we can build always build host-gawk.

Quoted 11 lines
Quoted 11 lines
support/scripts/mkusers new file +11 -0
+check_user_validity() {
+    local username="${1}"
+    local uid="${2}"
+    local group="${3}"
+    local gid="${4}"
+    local _uid _ugid _gid _username _group _ugroup
+
+    _group="$( get_group "${gid}" )"
+    _gid="$( get_gid "${group}" )"
+    _ugid="$( get_ugid "${username}" )"
+    _username="$( get_username "${uid}" )"
Quoted 8 lines

support/scripts/mkusers line 107

Quoted 4 lines
support/scripts/mkusers new file +4 -0
+    _uid="$( get_uid "${username}" )"
+    _ugroup="$( get_ugroup "${username}" )"
+
+    if [ ${gid} -ge 0 ]; then

Elsewhere in this script you check uid/gid against -1, not >= 0. This should be changed to "${gid} -eq -1" to be consistent with that and the documentation.

OK. Should also check for invalid (ie. -lt -1).

Quoted 7 lines

support/scripts/mkusers line 272

Quoted 5 lines
support/scripts/mkusers new file +5 -0
+    case "${home}" in
+        -)  _home="/";;
+        /)  fail "home can not be explicitly '/'\n";;
+        /*) _home="${home}";;
+        *)  fail "home must be an absolute path";;

This is where you missed the \n in the error message.

OK.

Quoted 3 lines

There is also another spelling mistake somewhere :-) I noticed three when I first skimmed this patch; two have already been pointed out; and I did not see the third when I went through to comment.

Fixed! ;-)

Thank you!

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#7 lore raw

PATCH 1/2 packages: add ability for packages to create users

Quoted 12 lines · Yann E. MORIN

Cam, All,

Quoted 8 lines · On Wednesday 02 January 2013 Cam Hutchison wrote:

docs/manual/adding-packages-generic.txt information is (assuming the package name is +libfoo+) : · line 263

Quoted 2 lines · Yann E. MORIN
docs/manual/adding-packages-generic.txt +2 -0
+* +LIBFOO_USERS+ lists the users to create for this package, if it installs
+  a daemon you want to run with a specific user. The syntax is similar in

"if it installs a program you want to run as a specific user"

that is, s/daemon/program/ and s/with/as/

Quoted 8 lines

Well, I would like to emphasise that this is primarily for running programs as daemons (ie. started by startup scripts). It does not really make sense to run program as a specific user when logged in, especially for embedded systems, where logging in a seldom done.

What about:

.... if it installs a daemon program you want to run as ...

I was considering a case of a periodic cron job running as a non-root user - that is not a daemon, and is not related to logged-in users.

Since there are no actual constraints that require that the user added be used only by a daemon, I figured the documentation should not introduce that constraint. But documenting intentions is fine and I have no strong feeling either way.

Quoted 11 lines
Quoted 8 lines

support/scripts/mkusers line 43

Quoted 5 lines
support/scripts/mkusers new file +5 -0
+#----------------------------------------------------------------------------
+get_uid() {
+    local username="${1}"
+
+    grep -r -E "${username}:" "${PASSWD}" |cut -d: -f3

An argument could be made that you should be using grep -F.

I don't know (ie. I don't usualy use) this switch, so I am not confident in using it here. If plain 'grep' does the job, lets just use that.

The problem with plain grep is that if the username contains a regular expression metachar, then grep will not work as expected in some cases. The most likely one is a period - a username of foo.bar will match an existing user of fooxbar and will not allow the creation of the user foo.bar.

More strictly, it is a matter of handling user input correctly. The user was not expecting a username to be a regular expression, so it should not be treated as such ...

Quoted 3 lines
Quoted 1 line

You should also anchor ${username}

Yes, indeed.

.... but a start-of-line anchor will not work with grep -F :-(

Another +1 for awk here - processing record-oriented files is what awk is good at, but I can understand not wanting to introduce that dependency.

#8 lore raw

PATCH 1/2 packages: add ability for packages to create users

Dear Cam Hutchison,

Quoted 3 lines · Cam Hutchison

Another +1 for awk here - processing record-oriented files is what awk is good at, but I can understand not wanting to introduce that dependency.

We already depend on awk:

http://git.buildroot.net/buildroot/tree/support/dependencies/dependencies.sh#n133

Best regards,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#9 lore raw

PATCH 1/2 packages: add ability for packages to create users

Thomas, All,

Quoted 7 lines · On Thursday 03 January 2013 Thomas Petazzoni wrote:
Quoted 3 lines · Cam Hutchison

Another +1 for awk here - processing record-oriented files is what awk is good at, but I can understand not wanting to introduce that dependency.

We already depend on awk:
http://git.buildroot.net/buildroot/tree/support/dependencies/dependencies.sh#n133

OK, I'll update the script, then.

Thanks!

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#10 lore raw

PATCH 1/2 packages: add ability for packages to create users

In reply to Yann E. MORIN

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 66

Quoted 2 lines · Yann E. MORIN
docs/manual/makedev-syntax.txt +2 -0
+The syntax for adding a user is a space-separated list of fields, one
+user per-line; the fields are:

per line - no hyphen here.

Quoted 1 line

+* no field may contain a column (+:+).

Found it - this is the third spelling mistake I referred to earlier. s/column/colon/

#11 lore raw

PATCH 1/2 packages: add ability for packages to create users

Cam, All,

Quoted 11 lines · On Wednesday 02 January 2013 Cam Hutchison wrote:

docs/manual/makedev-syntax.txt and then for device files corresponding to the partitions of · line 66

Quoted 2 lines · Yann E. MORIN
docs/manual/makedev-syntax.txt +2 -0
+The syntax for adding a user is a space-separated list of fields, one
+user per-line; the fields are:

per line - no hyphen here.

Quoted 1 line

+* no field may contain a column (+:+).

Found it - this is the third spelling mistake I referred to earlier. s/column/colon/

Thank you!

Regards,
Yann E. MORIN.

Signature · 6 lines
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| +33 223 225 172 `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |
'------------------------------^-------^------------------^--------------------'
#12 lore raw

PATCH 2/2 package/tvheadend: use a non-root user to run the daemon

In reply to Yann E. MORIN
---
 package/tvheadend/etc.default.tvheadend |    5 ++---
 package/tvheadend/tvheadend.mk          |   10 ++++++++--
 2 files changed, 10 insertions(+), 5 deletions(-)
package/tvheadend/etc.default.tvheadend +2 -3
index c769055..253f832 100644
@@ -1,6 +1,5 @@
-# Once we have a real user, we'll use it
-TVH_USER=root
-TVH_GROUP=root
+TVH_USER=tvheadend
+TVH_GROUP=tvheadend
 #TVH_ADAPTERS=
 #TVH_HTTP_PORT=9981
 #TVH_HTSP_PORT=9982
package/tvheadend/tvheadend.mk +8 -2
index 5100781..4a3f882 100644
@@ -26,9 +26,11 @@ TVHEADEND_DEPENDENCIES     += dvb-apps
 # To run tvheadend, we need:
 #  - a startup script, and its config file
 #  - a default DB with a tvheadend admin
+#  - a non-root user to run as
 define TVHEADEND_INSTALL_DB
-	$(INSTALL) -D package/tvheadend/accesscontrol.1     \
-	              $(TARGET_DIR)/root/.hts/tvheadend/accesscontrol/1
+	$(INSTALL) -D -m 0600 package/tvheadend/accesscontrol.1     \
+	              $(TARGET_DIR)/home/tvheadend/.hts/tvheadend/accesscontrol/1
+	chmod -R go-rwx $(TARGET_DIR)/home/tvheadend
 endef
 TVHEADEND_POST_INSTALL_TARGET_HOOKS  = TVHEADEND_INSTALL_DB
 
@@ -37,6 +39,10 @@ define TVHEADEND_INSTALL_INIT_SYSV
 	$(INSTALL) -D package/tvheadend/S99tvheadend          $(TARGET_DIR)/etc/init.d/S99tvheadend
 endef
 
+define TVHEADEND_USERS
+tvheadend -1 tvheadend -1 * /home/tvheadend - video TVHeadend daemon
+endef
+
 #----------------------------------------------------------------------------
 # tvheadend is not an autotools-based package, but it is possible to
 # call its ./configure script as if it were an autotools one.
Signature · 1 line
1.7.2.5