From mboxrd@z Thu Jan 1 00:00:00 1970 X-GM-THRID: 6680759771290664960 X-Received: by 2002:a2e:910d:: with SMTP id m13mr4202511ljg.30.1555485599514; Wed, 17 Apr 2019 00:19:59 -0700 (PDT) X-BeenThere: isar-users@googlegroups.com Received: by 2002:ac2:55ae:: with SMTP id y14ls1819839lfg.7.gmail; Wed, 17 Apr 2019 00:19:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqzgGXjH76dubPNKlkaLmciIy1ci4OZ54lrCL3Q3wZlzw5eH5T4JViJFvj7+uDJkdtc8b6Br X-Received: by 2002:ac2:4896:: with SMTP id x22mr769665lfc.17.1555485598957; Wed, 17 Apr 2019 00:19:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555485598; cv=none; d=google.com; s=arc-20160816; b=fQxoj21aTNS8mak6vt7DY5z7C6tlP+B1zZF8m9px6baY/tTCmSagkGthdKODl8nGCy FdvgM62Yxz7g5DhOh8ZK8P7YPgY5Nu1phC9Aqo490jEmv+mbUrARMtYWPFHSqDxlHEff jVqK5ILc83qPO4/oIwLbShzKtKfpL1uP3/K/oqH8uDHigJmxPDTIr5RqbcD/dgvzpUyD ioInYPhkybeKbOngZ11oJHZbQ16e++60PNn7Ef7fMW+s99V0EnZ0KcPYJMsi+mE42bmY 9CbkMcmONzXY3WVVNFnm/WnwKUSwN87cwffupfCvPTJBp5nYtdgWotLh82Bu4W1b7I/R vN1Q== 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=ECv17u6bE7LIo1+yZZhafdWdCvqy+gqJ3OmKn714wxE=; b=kuaNkgTgmJmlRUSwHX0BPur4h4Ks8eU+O9v3FkBlETdD/Ty5tjCo96E8TmerzYQkLE J4BSZPI5LsPkKNg6PyPZbIjPMZ+rI8Hzp8S2hrLhmHw59uu+E1LPIs8OsD8dAXTPBcJe lUDWHckHmiAY0iEc77vJTOzFVGIhNUIBfDfJJfTqpbWRNuoAUZgFlEk3WAfInIKQiPj5 ml4tWNi1/QWcj0VugpOZIwLKAd9+lOZJ2RMpqd6D6OCckLYcxd7dez3R7re1Ma7hK5Tm QigXarcjIGITUl9nJw1tycUYJmxms2zdlLHG2wGdrpBrx5Io6TyxlxVn0+behAW5fE7x GNNQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.40 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com Return-Path: Received: from gecko.sbs.de (gecko.sbs.de. [194.138.37.40]) by gmr-mx.google.com with ESMTPS id o16si3326852lji.0.2019.04.17.00.19.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Apr 2019 00:19:58 -0700 (PDT) Received-SPF: pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.40 as permitted sender) client-ip=194.138.37.40; Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.40 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com Received: from mail2.sbs.de (mail2.sbs.de [192.129.41.66]) by gecko.sbs.de (8.15.2/8.15.2) with ESMTPS id x3H7JvoP020607 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 17 Apr 2019 09:19:57 +0200 Received: from ring.ppmd.siemens.net (linux-ses-ext02.ppmd.siemens.net [139.25.69.232]) by mail2.sbs.de (8.15.2/8.15.2) with ESMTP id x3H7JtaO013048; Wed, 17 Apr 2019 09:19:57 +0200 From: claudius.heine.ext@siemens.com To: isar-users@googlegroups.com Cc: Claudius Heine Subject: [RFC PATCH 4/4] meta/classes: add image-account-extension class Date: Wed, 17 Apr 2019 09:19:52 +0200 Message-Id: <20190417071952.6723-5-claudius.heine.ext@siemens.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190417071952.6723-1-claudius.heine.ext@siemens.com> References: <20190417071952.6723-1-claudius.heine.ext@siemens.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TUID: mPCCmrqIc+Be From: Claudius Heine This class allows to configure user and group accounts of the image. Signed-off-by: Claudius Heine --- meta/classes/image-account-extension.bbclass | 252 +++++++++++++++++++ meta/classes/image.bbclass | 1 + 2 files changed, 253 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..ad295ea --- /dev/null +++ b/meta/classes/image-account-extension.bbclass @@ -0,0 +1,252 @@ +# 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() { + # 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 8bd1f26..4abab09 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