From mboxrd@z Thu Jan 1 00:00:00 1970 X-GM-THRID: 6691586504498610176 X-Received: by 2002:a17:906:f148:: with SMTP id gw8mr24469203ejb.145.1558623325554; Thu, 23 May 2019 07:55:25 -0700 (PDT) X-BeenThere: isar-users@googlegroups.com Received: by 2002:a17:906:6995:: with SMTP id i21ls1433698ejr.15.gmail; Thu, 23 May 2019 07:55:25 -0700 (PDT) X-Google-Smtp-Source: APXvYqyafVMKv7NTHZnH8BrGn2tadXALmmfxXxqIt5dkCmgLBxxGw4HTrJyHfZGwczGWcwPJpUJm X-Received: by 2002:a17:906:f84a:: with SMTP id ks10mr59333062ejb.65.1558623325133; Thu, 23 May 2019 07:55:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558623325; cv=none; d=google.com; s=arc-20160816; b=odrHdZy97w7hNSrGDZpxlSFGsuYsHYxJzEE4iWtngDVw7IAsHmwAeqHrvxBqYMJUx0 KmFD26aQmg3N/A9lbODORB8B2dW30YZruvdHUY5/F4jme/vbd1b3IPtSuZ6vjZ3JVrDN z+u/ZtHAmUzrkkPpOgYepRpLZIf3XbcRL8S3gQQsQUTSEfXTxoG8ssNTP9FTfvBNof9B 5CAukbM+al9Wzz92JnfeaFLklTLqjxUnP3NJP5DYF8vhQtVfqZdSzSMS5cbZAxByWI7V PBORC2Gdd4oRs7xa2xREFMjfB2VlK/1eRCdCoIqa95goZOb/Gmn6dDqvbGOhol+Q/ZaE j0hg== 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=dDLDF9ziFNJ0cnRmszWLjeIo8HO3uOOCnQDHwZMIgRo=; b=K0IfakC3AKZmUOpxbAzDhloMzyjusKgYk6LZrJGFnV574wcX8shfgVLNXz3C4n5T5E aiueTJuryNQXTEzPGXrGsu6vE0bcEisyoyWFIUt6lCtTZRikNBdePS/wBOUX0Ucd5oHd aR3d9suWUfaEijG/bvQE9EQNpsDaJfE11XOzRwuVNDRtrJ/lekJujVCTnW9FiF662l+9 1h0+eEkO0yA6EY2uq23KoDBoUjwRwszgCVwmgCliqERFRuNrWUtmhfDMksJxs4TOmomR TJAEVS0lXCo807Sc6Q600yt5pokmv5hKRIEPcEjbEMOx7ESP8Qh59khcgdMg7FkgnS8S Muxg== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.39 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Return-Path: Received: from lizzard.sbs.de (lizzard.sbs.de. [194.138.37.39]) by gmr-mx.google.com with ESMTPS id y22si96874edd.2.2019.05.23.07.55.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 May 2019 07:55:25 -0700 (PDT) Received-SPF: pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.39 as permitted sender) client-ip=194.138.37.39; Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of claudius.heine.ext@siemens.com designates 194.138.37.39 as permitted sender) smtp.mailfrom=claudius.heine.ext@siemens.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=siemens.com Received: from mail1.sbs.de (mail1.sbs.de [192.129.41.35]) by lizzard.sbs.de (8.15.2/8.15.2) with ESMTPS id x4NEtOvF027868 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 23 May 2019 16:55:24 +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 x4NEtNgD014892; Thu, 23 May 2019 16:55:24 +0200 From: claudius.heine.ext@siemens.com To: isar-users@googlegroups.com Cc: Claudius Heine Subject: [PATCH v4 4/8] meta/classes: add image-account-extension class Date: Thu, 23 May 2019 16:55:17 +0200 Message-Id: <20190523145521.23050-5-claudius.heine.ext@siemens.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190523145521.23050-1-claudius.heine.ext@siemens.com> References: <20190523145521.23050-1-claudius.heine.ext@siemens.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TUID: 3Oa/PEms4uYk 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 `no-create-home`, `create-home`, `system` and `allow-empty-password`. Signed-off-by: Claudius Heine --- meta/classes/image-account-extension.bbclass | 257 +++++++++++++++++++ meta/classes/image.bbclass | 1 + 2 files changed, 258 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..22754da --- /dev/null +++ b/meta/classes/image-account-extension.bbclass @@ -0,0 +1,257 @@ +# 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] = "no-create-home create-home system allow-empty-password" + +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%*,no-create-home,*}" ]; then + set -- "$@" --no-create-home + else + if [ "${flags}" != "${flags%*,create-home,*}" ]; then + set -- "$@" --create-home + fi + 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%*,allow-empty-password,*}" ]; 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 dce6638..ef7983b 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