openembedded-core.lists.openembedded.org archive mirror
 help / color / mirror / Atom feed
From: Louis Rannou <lrannou@baylibre.com>
To: tgamblin@baylibre.com,
	"openembedded-core@lists.openembedded.org"
	<openembedded-core@lists.openembedded.org>
Subject: Re: [RFC] incorrect parsing of sysusers.d in rootfs generation
Date: Wed, 7 Jun 2023 17:16:08 +0200	[thread overview]
Message-ID: <08e9842b-0288-92c9-6327-a82e37f4af99@baylibre.com> (raw)
In-Reply-To: <b02fd7f2-b6f7-01f6-256a-d1bf9f7aa91a@baylibre.com>

Hello again,

a python solution could be one below.

Also, I found that most of users/groups defined there are redundant as 
they already exist (such as root). I guess they are defined from 
base-passwd. I am not sure which recipe (base-passwd or systemd) should 
have the precedence on this. If it's base-passwd, perhaps this 
postcommand should check first if the user does already exist.

Regards,
Louis

---

  meta/classes/rootfs-postcommands.bbclass | 69 ++++++++++++++++--------
  1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/meta/classes/rootfs-postcommands.bbclass 
b/meta/classes/rootfs-postcommands.bbclass
index 5c0b3ec37c..1741919918 100644
--- a/meta/classes/rootfs-postcommands.bbclass
+++ b/meta/classes/rootfs-postcommands.bbclass
@@ -61,29 +61,52 @@ python () {
      d.appendVar('ROOTFS_POSTPROCESS_COMMAND', 'rootfs_reproducible;')
  }

-systemd_create_users () {
-	for conffile in ${IMAGE_ROOTFS}/usr/lib/sysusers.d/*.conf; do
-		[ -e $conffile ] || continue
-		grep -v "^#" $conffile | sed -e '/^$/d' | while read type name id 
comment; do
-		if [ "$type" = "u" ]; then
-			useradd_params="--shell /sbin/nologin"
-			[ "$id" != "-" ] && useradd_params="$useradd_params --uid $id"
-			[ "$comment" != "-" ] && useradd_params="$useradd_params --comment 
$comment"
-			useradd_params="$useradd_params --system $name"
-			eval useradd --root ${IMAGE_ROOTFS} $useradd_params || true
-		elif [ "$type" = "g" ]; then
-			groupadd_params=""
-			[ "$id" != "-" ] && groupadd_params="$groupadd_params --gid $id"
-			groupadd_params="$groupadd_params --system $name"
-			eval groupadd --root ${IMAGE_ROOTFS} $groupadd_params || true
-		elif [ "$type" = "m" ]; then
-			group=$id
-			eval groupadd --root ${IMAGE_ROOTFS} --system $group || true
-			eval useradd --root ${IMAGE_ROOTFS} --shell /sbin/nologin --system 
$name --no-user-group || true
-			eval usermod --root ${IMAGE_ROOTFS} -a -G $group $name
-		fi
-		done
-	done
+python systemd_create_users() {
+    import glob
+    import re
+    import subprocess
+
+    pattern_comment = r'(-|\"[^:\"]+\")'
+    pattern_word    = r'[^\s]+'
+    pattern_line   = r'(' + pattern_word + r')\s+(' + pattern_word + 
r')\s+(' + pattern_word + r')(\s+' \
+        + pattern_comment + r')?' + r'(\s+(' + pattern_word + r'))?' + 
r'(\s+(' + pattern_word + r'))?'
+
+    IMAGE_ROOTFS = d.getVar('IMAGE_ROOTFS')
+
+    for conffile in glob.glob(os.path.join(IMAGE_ROOTFS, 
'usr/lib/sysusers.d/*.conf')):
+        with open(conffile, 'r') as f:
+            for line in f:
+                line = line.strip()
+                if not len(line) or line[0] == '#': continue
+                ret = re.fullmatch(pattern_line, line.strip())
+                if not ret: continue
+                (stype, sname, sid, _, scomment, _, shomedir, _, 
sshell) = ret.groups()
+                if stype == 'u':
+                    useradd_command = ['useradd']
+                    if sid != '-':
+                        useradd_command.extend(['--uid', sid])
+                    if scomment and scomment != '-':
+                        useradd_command.extend(['--comment', scomment])
+                    if shomedir and shomedir != '-':
+                        useradd_command.extend(['--root', IMAGE_ROOTFS 
+ shomedir])
+                    else:
+                        useradd_command.extend(['--root', IMAGE_ROOTFS])
+                    if sshell and sshell != '-':
+                        useradd_command.extend(['--shell', sshell])
+                    else:
+                        useradd_command.extend(['--shell', 
'/sbin/nologin'])
+                    useradd_command.extend(['--system', sname])
+                    subprocess.run(useradd_command)
+                elif stype == 'g':
+                    groupadd_command = ['groupadd']
+                    if sid != '-':
+                        groupadd_command.extend(['--gid', sid])
+                    groupadd_command.extend(['--system', sname])
+                    subprocess.run(groupadd_command)
+                elif stype == 'm':
+                    subprocess.run(['groupadd', '--root', IMAGE_ROOTFS, 
'--system', sid])
+                    subprocess.run(['useradd', '--root', IMAGE_ROOTFS, 
'--shell', '/sbin/nologin', '--system', name, 'no-user-group'])
+                    subprocess.run(['usermod', '-a', '-G', sid, sname])
  }

  #



On 05/06/2023 17:55, Louis Rannou wrote:> Hello,
 >
 > I have found an issue in the rootfs routine. The
 > rootfs-postcommands.bbclass has a funtion systemd_create_users that
 > reads /etc/sysusers.d/*.conf files and parses lines as 'type name id
 > comment'.
 >
 > However, the sysusers.d manual says, those lines can be 'type name id
 > comment home_dir shell'. If a home directory of shell is defined, they
 > are considered as part of the comment, and we run incorrect commands
 > such as the one below :
 >
 > useradd --shell /sbin/nologin --uid 0 --comment "Super User" /root
 > --system root
 >
 > To fix that, we require a stronger parsing. Several options look
 > possible to me, but I am not sure which one is preferred.
 >
 > 1. sed with a regular expression that returns something that still needs
 > parsing
 > 2. awk with a step by step script that returns something that still
 > needs to be parsed
 > 3. use python and regexp module
 >
 > Also I don't know if the parsing should completely check the sysusers
 > syntax as said in the manual (first field is [urgm], second is
 > alphanum_-, etc.). In my opinion it should not as this will be made by
 > the useradd command.
 >
 > Do you think it worth to add some testing about that ? I am not sure how
 > to do that.
 >
 > Regards,
 > Louis Rannou


  reply	other threads:[~2023-06-07 15:16 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-05 15:55 [RFC] incorrect parsing of sysusers.d in rootfs generation Louis Rannou
2023-06-07 15:16 ` Louis Rannou [this message]
2023-06-08  9:19   ` [OE-core] " Richard Purdie
2023-06-08 10:28     ` Louis Rannou
2023-06-08 10:36       ` Richard Purdie
2023-06-08 11:56         ` Louis Rannou
2023-06-09 11:06           ` Louis Rannou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=08e9842b-0288-92c9-6327-a82e37f4af99@baylibre.com \
    --to=lrannou@baylibre.com \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=tgamblin@baylibre.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).