From mboxrd@z Thu Jan 1 00:00:00 1970 X-GM-THRID: 6680759771290664960 X-Received: by 2002:a5d:4087:: with SMTP id o7mr2968661wrp.9.1555586752897; Thu, 18 Apr 2019 04:25:52 -0700 (PDT) X-BeenThere: isar-users@googlegroups.com Received: by 2002:a05:600c:2292:: with SMTP id 18ls564731wmf.3.canary-gmail; Thu, 18 Apr 2019 04:25:52 -0700 (PDT) X-Google-Smtp-Source: APXvYqxlJxEZ3Hv8ae/UHxw5ecW+I/D1mhl5uDbRUKOwtADU5+wcX/ObqzKP07UfDlyZAZ+ecQgB X-Received: by 2002:a1c:7e10:: with SMTP id z16mr2848801wmc.117.1555586752453; Thu, 18 Apr 2019 04:25:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555586752; cv=none; d=google.com; s=arc-20160816; b=k/DDAl/2xcRhshUvV3odq0ocP2mxLFjOX7WGevCIk6V3MnJ++Q3olTCA02KrTMHYSX 2lkdX1r6pHTijjGBKx2M+gYRiLonMnjMnxCqAu7ke4Ra78HdlrhMfC19A4nwWHThGGLC hiRA0907GQD1n90YEJ3wBSQZHAB+iET3gMmqaThzs+uM6Yme/5y6uhNI6xVppqy+GtBZ O42ZhzuLcmTbEkPK+gQuGMlNCdq3XWa138aT3IipAaMeoKxTXMCHoTYCN2+nVtb5tJCj PPhtXyfOskS70LaFwNPuQ597XTZGqUhaWThrexHRSpcRgzgOROxv3CYrdmGz1WD7lOv0 B9HQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=khAIu9qCRQEkQysP/EDF2jK739XOBEF7q/xCei15/Co=; b=AEJgbjG8UOs6tDFZLeVBWWWssZuzAzGHZm4MKC7DVYGY9tQOvUq7fRfADAEK6OGHcH hwg3k5KG6dDFyU85B0rVo5772DcogLCis/lXrYwR5W8T5V2Bahonw413AZMW524h3EKD as4TTCn2wn2xWHMnro3NDAJpEBaEtUDRq+K/GZWoS1/z6ZSfoWoyApyGrgIYNN8ISHFB zjwpGl+4+50NISolwcmlz1QYp2mbsRCCLNq2WHVB7GzXe0CRz8ONPSZRNdARiQiyYy9G CBd9hJry1pTc6ipT+CDySZQrXLWi5SuEV34LipiDKKdRQTzYJnNMyyLnBi6kGAIGsj// iaqg== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 192.35.17.28 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com Return-Path: Received: from goliath.siemens.de (goliath.siemens.de. [192.35.17.28]) by gmr-mx.google.com with ESMTPS id z185si463814wmb.0.2019.04.18.04.25.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Apr 2019 04:25:52 -0700 (PDT) Received-SPF: pass (google.com: domain of claudius.heine.ext@siemens.com designates 192.35.17.28 as permitted sender) client-ip=192.35.17.28; Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 192.35.17.28 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com Received: from mail1.sbs.de (mail1.sbs.de [192.129.41.35]) by goliath.siemens.de (8.15.2/8.15.2) with ESMTPS id x3IBPoXI018063 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Apr 2019 13:25:51 +0200 Received: from ring.ppmd.siemens.net (linux-ses-ext02.ppmd.siemens.net [139.25.69.232]) by mail1.sbs.de (8.15.2/8.15.2) with ESMTP id x3IBPolK014428; Thu, 18 Apr 2019 13:25:50 +0200 From: claudius.heine.ext@siemens.com To: isar-users@googlegroups.com Cc: Claudius Heine Subject: [PATCH 4/6] meta/classes: add image-account-extension class Date: Thu, 18 Apr 2019 13:25:43 +0200 Message-Id: <20190418112545.1201-5-claudius.heine.ext@siemens.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190418112545.1201-1-claudius.heine.ext@siemens.com> References: <20190418112545.1201-1-claudius.heine.ext@siemens.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TUID: E0UM4knnkb63 From: Claudius Heine This class allows to configure user and group accounts of the image. Groups or users that should be configured/created are added into the `GROUPS` or `USERS` variable. The configuration itself is then added to each groups or users `GROUP_` or `USER_` flags. The flags available for groups are `gid` and `flags`. The `flags` variable contains some additional options for the group. With this patch only `system` is supported for groups, allowing to create groups with `groupadd` with the `--system` parameter. The flags available for users are `password`, `expire`, `inactive`, `uid`, `gid`, `comment`, `home`, `shell`, `groups` and `flags`. The additional flags for users are `nohome`, `system` and `allowemptypassword`. Signed-off-by: Claudius Heine --- meta/classes/image-account-extension.bbclass | 253 +++++++++++++++++++ meta/classes/image.bbclass | 1 + 2 files changed, 254 insertions(+) create mode 100644 meta/classes/image-account-extension.bbclass diff --git a/meta/classes/image-account-extension.bbclass b/meta/classes/image-account-extension.bbclass new file mode 100644 index 0000000..f1eec50 --- /dev/null +++ b/meta/classes/image-account-extension.bbclass @@ -0,0 +1,253 @@ +# This software is a part of ISAR. +# Copyright (C) Siemens AG, 2019 +# +# SPDX-License-Identifier: MIT +# +# This class extends the image.bbclass for creating user accounts and groups. + +USERS ??= "" + +#USERS += "root" +#USER_root[password] = "" # Encrypted password +#USER_root[expire] = "" +#USER_root[inactive] = "" +#USER_root[uid] = "" +#USER_root[gid] = "" # If first character is a number: gid, otherwise groupname +#USER_root[comment] = "The ultimate root user" +#USER_root[home] = "/home/root" +#USER_root[shell] = "/bin/sh" +#USER_root[groups] = "audio video" +#USER_root[flags] = "nohome system allowemptypassword" + +GROUPS ??= "" + +#GROUPS += "root" +#GROUP_root[gid] = "" +#GROUP_root[flags] = "system" + +def gen_accounts_array(d, listname, entryname, flags, verb_flags=None): + from itertools import chain + + entries = (d.getVar(listname, True) or "").split() + return " ".join( + ":".join( + chain( + (entry,), + ( + (",".join( + ( + d.getVarFlag(entryname + "_" + entry, flag, True) or "" + ).split() + ) if flag not in (verb_flags or []) else ( + d.getVarFlag(entryname + "_" + entry, flag, True) or "" + )).replace(":","=") + for flag in flags + ), + ) + ) + for entry in entries + ) + +# List of space separated entries, where each entry has the format: +# username:encryptedpassword:expiredate:inactivenumber:userid:groupid:comment:homedir:shell:group1,group2:flag1,flag2 +IMAGE_ACCOUNTS_USERS =+ "${@gen_accounts_array(d, 'USERS', 'USER', ['password', 'expire', 'inactive', 'uid', 'gid', 'comment', 'home', 'shell', 'groups', 'flags'], ['password', 'comment', 'home', 'shell'])}" + +# List of space separated entries, where each entry has the format: +# groupname:groupid:flag1,flag2 +IMAGE_ACCOUNTS_GROUPS =+ "${@gen_accounts_array(d, 'GROUPS', 'GROUP', ['gid', 'flags'])}" + +ROOTFS_CONFIGURE_COMMAND += "image_configure_accounts" +image_configure_accounts[weight] = "3" +image_configure_accounts() { + # Create groups + # Add space to the end of the list: + list='${@" ".join(d.getVar('IMAGE_ACCOUNTS_GROUPS', True).split())} ' + while true; do + # Pop first group entry: + list_rest="${list#*:*:* }" + entry="${list%%${list_rest}}" + list="${list_rest}" + + if [ -z "${entry}" ]; then + break + fi + + # Add colon to the end of the entry and remove trailing space: + entry="${entry% }:" + + # Decode entries: + name="${entry%%:*}" + entry="${entry#${name}:}" + + gid="${entry%%:*}" + entry="${entry#${gid}:}" + + flags="${entry%%:*}" + entry="${entry#${flags}:}" + + flags=",${flags}," # Needed for searching for substrings + + # Check if user already exists: + if grep -q "^${name}:" '${ROOTFSDIR}/etc/group'; then + exists="y" + else + exists="n" + fi + + # Create arguments: + set -- # clear arguments + + if [ -n "$gid" ]; then + set -- "$@" --gid "$gid" + fi + + if [ "n" = "$exists" ]; then + if [ "${flags}" != "${flags%*,system,*}" ]; then + set -- "$@" --system + fi + fi + + # Create or modify groups: + if [ "y" = "$exists" ]; then + if [ -z "$@" ]; then + echo "Do not execute groupmod (no changes)." + else + echo "Execute groupmod with \"$@\" for \"$name\"" + sudo -E chroot '${ROOTFSDIR}' \ + /usr/sbin/groupmod "$@" "$name" + fi + else + echo "Execute groupadd with \"$@\" for \"$name\"" + sudo -E chroot '${ROOTFSDIR}' \ + /usr/sbin/groupadd "$@" "$name" + fi + done + + # Create users + list='${@" ".join(d.getVar('IMAGE_ACCOUNTS_USERS', True).split())} ' + while true; do + # Pop first user entry: + list_rest="${list#*:*:*:*:*:*:*:*:*:*:* }" + entry="${list%%${list_rest}}" + list="${list_rest}" + + if [ -z "${entry}" ]; then + break + fi + + # Add colon to the end of the entry and remove trailing space: + entry="${entry% }:" + + # Decode entries: + name="${entry%%:*}" + entry="${entry#${name}:}" + + password="${entry%%:*}" + entry="${entry#${password}:}" + + expire="${entry%%:*}" + entry="${entry#${expire}:}" + + inactive="${entry%%:*}" + entry="${entry#${inactive}:}" + + uid="${entry%%:*}" + entry="${entry#${uid}:}" + + gid="${entry%%:*}" + entry="${entry#${gid}:}" + + comment="${entry%%:*}" + entry="${entry#${comment}:}" + + home="${entry%%:*}" + entry="${entry#${home}:}" + + shell="${entry%%:*}" + entry="${entry#${shell}:}" + + groups="${entry%%:*}" + entry="${entry#${groups}:}" + + flags="${entry%%:*}" + entry="${entry#${flags}:}" + + flags=",${flags}," # Needed for searching for substrings + + # Check if user already exists: + if grep -q "^${name}:" '${ROOTFSDIR}/etc/passwd'; then + exists="y" + else + exists="n" + fi + + # Create arguments: + set -- # clear arguments + + if [ -n "$expire" ]; then + set -- "$@" --expiredate "$expire" + fi + + if [ -n "$inactive" ]; then + set -- "$@" --inactive "$inactive" + fi + + if [ -n "$uid" ]; then + set -- "$@" --uid "$uid" + fi + + if [ -n "$gid" ]; then + set -- "$@" --gid "$gid" + fi + + if [ -n "$comment" ]; then + set -- "$@" --comment "$comment" + fi + + if [ -n "$home" ]; then + if [ "y" = "$exists" ]; then + set -- "$@" --home "$home" --move-home + else + set -- "$@" --home-dir "$home" + fi + fi + + if [ -n "$shell" ]; then + set -- "$@" --shell "$shell" + fi + + if [ -n "$groups" ]; then + set -- "$@" --groups "$groups" + fi + + if [ "n" = "$exists" ]; then + if [ "${flags}" != "${flags%*,system,*}" ]; then + set -- "$@" --system + fi + if [ "${flags}" != "${flags%*,nohome,*}" ]; then + set -- "$@" --no-create-home + fi + fi + + # Create or modify users: + if [ "y" = "$exists" ]; then + if [ -z "$@" ]; then + echo "Do not execute usermod (no changes)." + else + echo "Execute usermod with \"$@\" for \"$name\"" + sudo -E chroot '${ROOTFSDIR}' \ + /usr/sbin/usermod "$@" "$name" + fi + else + echo "Execute useradd with \"$@\" for \"$name\"" + sudo -E chroot '${ROOTFSDIR}' \ + /usr/sbin/useradd "$@" "$name" + fi + + # Set password: + if [ -n "$password" -o "${flags}" != "${flags%*,allowemptypassword,*}" ]; then + printf '%s:%s' "$name" "$password" | sudo chroot '${ROOTFSDIR}' \ + /usr/sbin/chpasswd -e + fi + done +} diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass index c1ae4f6..67c86b7 100644 --- a/meta/classes/image.bbclass +++ b/meta/classes/image.bbclass @@ -61,6 +61,7 @@ inherit image-cache-extension inherit image-tools-extension inherit image-postproc-extension inherit image-locales-extension +inherit image-account-extension # Extra space for rootfs in MB ROOTFS_EXTRA ?= "64" -- 2.20.1