All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] User/group creation at preinstall v2
@ 2011-06-02 23:50 Scott Garman
  2011-06-02 23:50 ` [PATCH 1/7] shadow: recipe and patch cleanup Scott Garman
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

Hello world,

This pull request includes everything needed to create custom users
and groups in our images/packages and the corresponding ability to
set custom ownership permissions. 

There is a useradd-example.bb file in meta-skeleton which provides
a heavily-commented example recipe to demonstrate how this feature
can be used.

This v2 pull request incorporates changes Mark Hatle suggested to
improve the useradd-example recipe, removes the base-passwd-cross
recipe and puts the sysroot population code into base-passwd
(requested by Richard Purdie), and fixes a critical bug where some
packages were not getting populated with the preinst scripts.

The following changes since commit 1169f1b066d0028bd2ef7915440450bd42ef165e:

  license.bbclass: Sane Parsing of licenses (2011-05-27 23:36:24 +0100)

are available in the git repository at:
  git://git.pokylinux.org/poky-contrib sgarman/user-group-creation
  http://git.pokylinux.org/cgit.cgi/poky-contrib/log/?h=sgarman/user-group-creation

Scott Garman (7):
  shadow: recipe and patch cleanup
  shadow: add a -native recipe with customized utilities
  base-passwd: populate the target sysroot with passwd/group/login.defs
  useradd.bbclass: new class for managing user/group permissions
  useradd-example: example recipe for using inherit useradd
  bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV
  package_rpm.bbclass: make RPM use on-disk permissions

 .../recipes-skeleton/useradd/useradd-example.bb    |   72 ++
 meta/classes/package_rpm.bbclass                   |    2 +
 meta/classes/useradd.bbclass                       |  163 +++
 meta/conf/bitbake.conf                             |    2 +-
 .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++
 .../recipes-core/base-passwd/base-passwd_3.5.22.bb |   27 +-
 .../shadow/files/add_root_cmd_options.patch        | 1296 ++++++++++++++++++++
 .../files/shadow-4.1.3-dots-in-usernames.patch     |    4 +
 .../shadow-4.1.4.2-env-reset-keep-locale.patch     |    4 +
 .../files/shadow-4.1.4.2-groupmod-pam-check.patch  |    4 +
 .../files/shadow-4.1.4.2-su_no_sanitize_env.patch  |    4 +
 .../shadow/files/shadow.automake-1.11.patch        |    4 +
 .../shadow/shadow-native_4.1.4.3.bb                |   66 +
 meta/recipes-extended/shadow/shadow.inc            |  121 --
 meta/recipes-extended/shadow/shadow_4.1.4.3.bb     |  141 ++-
 15 files changed, 2163 insertions(+), 133 deletions(-)
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example.bb
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file1
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file2
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file3
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file4
 create mode 100644 meta/classes/useradd.bbclass
 create mode 100644 meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs
 create mode 100644 meta/recipes-extended/shadow/files/add_root_cmd_options.patch
 create mode 100644 meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb
 delete mode 100644 meta/recipes-extended/shadow/shadow.inc




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/7] shadow: recipe and patch cleanup
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-02 23:50 ` [PATCH 2/7] shadow: add a -native recipe with customized utilities Scott Garman
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

Taking over maintenance of the shadow recipe. Cleaning it up in
preparation of adding a -native version that will be used to add
users/groups during postinstall.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 .../files/shadow-4.1.3-dots-in-usernames.patch     |    4 +
 .../shadow-4.1.4.2-env-reset-keep-locale.patch     |    4 +
 .../files/shadow-4.1.4.2-groupmod-pam-check.patch  |    4 +
 .../files/shadow-4.1.4.2-su_no_sanitize_env.patch  |    4 +
 .../shadow/files/shadow.automake-1.11.patch        |    4 +
 meta/recipes-extended/shadow/shadow.inc            |  121 -----------------
 meta/recipes-extended/shadow/shadow_4.1.4.3.bb     |  141 ++++++++++++++++++--
 7 files changed, 152 insertions(+), 130 deletions(-)
 delete mode 100644 meta/recipes-extended/shadow/shadow.inc

diff --git a/meta/recipes-extended/shadow/files/shadow-4.1.3-dots-in-usernames.patch b/meta/recipes-extended/shadow/files/shadow-4.1.3-dots-in-usernames.patch
index 7a2ff2e..a7bb0a9 100644
--- a/meta/recipes-extended/shadow/files/shadow-4.1.3-dots-in-usernames.patch
+++ b/meta/recipes-extended/shadow/files/shadow-4.1.3-dots-in-usernames.patch
@@ -9,6 +9,10 @@
 #
 # comment added by Kevin Tian <kevin.tian@intel.com>, 2010-08-11
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
 Index: shadow-4.1.4.2/libmisc/chkname.c
 ===================================================================
 --- shadow-4.1.4.2.orig/libmisc/chkname.c	2009-04-28 12:14:04.000000000 -0700
diff --git a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-env-reset-keep-locale.patch b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-env-reset-keep-locale.patch
index 124065c..6514746 100644
--- a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-env-reset-keep-locale.patch
+++ b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-env-reset-keep-locale.patch
@@ -12,6 +12,10 @@
 http://bugs.gentoo.org/283725
 https://alioth.debian.org/tracker/index.php?func=detail&aid=311740&group_id=30580&atid=411480
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
 Index: shadow-4.1.4.2/libmisc/env.c
 ===================================================================
 --- shadow-4.1.4.2.orig/libmisc/env.c	2009-04-27 13:07:56.000000000 -0700
diff --git a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-groupmod-pam-check.patch b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-groupmod-pam-check.patch
index 6682fe8..640200b 100644
--- a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-groupmod-pam-check.patch
+++ b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-groupmod-pam-check.patch
@@ -17,6 +17,10 @@ http://lists.alioth.debian.org/pipermail/pkg-shadow-devel/2009-November/007850.h
 	* NEWS, src/groupmod.c: Fixed groupmod when configured with
 	--enable-account-tools-setuid.
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
 Index: shadow-4.1.4.2/src/groupmod.c
 ===================================================================
 --- shadow-4.1.4.2.orig/src/groupmod.c	2009-06-05 15:16:58.000000000 -0700
diff --git a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-su_no_sanitize_env.patch b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-su_no_sanitize_env.patch
index f67251c..0dc4d75 100644
--- a/meta/recipes-extended/shadow/files/shadow-4.1.4.2-su_no_sanitize_env.patch
+++ b/meta/recipes-extended/shadow/files/shadow-4.1.4.2-su_no_sanitize_env.patch
@@ -12,6 +12,10 @@
 http://bugs.gentoo.org/show_bug.cgi?id=301957
 https://alioth.debian.org/scm/browser.php?group_id=30580
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
 Index: shadow-4.1.4.2/src/su.c
 ===================================================================
 --- shadow-4.1.4.2.orig/src/su.c	2009-07-23 13:38:56.000000000 -0700
diff --git a/meta/recipes-extended/shadow/files/shadow.automake-1.11.patch b/meta/recipes-extended/shadow/files/shadow.automake-1.11.patch
index 36d7be6..a793f09 100644
--- a/meta/recipes-extended/shadow/files/shadow.automake-1.11.patch
+++ b/meta/recipes-extended/shadow/files/shadow.automake-1.11.patch
@@ -11,6 +11,10 @@
 
 man_nopan is for !USE_PAM already included in man_MANS and automake-1.11 hates to install some file twice
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
 diff -uNr shadow-4.1.4.2.orig/man/Makefile.am shadow-4.1.4.2/man/Makefile.am
 --- shadow-4.1.4.2.orig/man/Makefile.am	2009-03-14 15:40:10.000000000 +0100
 +++ shadow-4.1.4.2/man/Makefile.am	2010-04-02 07:31:17.000000000 +0200
diff --git a/meta/recipes-extended/shadow/shadow.inc b/meta/recipes-extended/shadow/shadow.inc
deleted file mode 100644
index 42f92a7..0000000
--- a/meta/recipes-extended/shadow/shadow.inc
+++ /dev/null
@@ -1,121 +0,0 @@
-DESCRIPTION = "Tools to change and administer password and group data."
-HOMEPAGE = "http://pkg-shadow.alioth.debian.org/"
-BUGTRACKER = "https://alioth.debian.org/tracker/?group_id=30580"
-SECTION = "base utils"
-LICENSE = "BSD | Artistic"
-LIC_FILES_CHKSUM = "file://COPYING;md5=08c553a87d4e51bbed50b20e0adcaede \
-                    file://src/passwd.c;firstline=8;endline=30;md5=2899a045e90511d0e043b85a7db7e2fe"
-
-PAM_PLUGINS = "  libpam-runtime \
-                 pam-plugin-faildelay \
-                 pam-plugin-securetty \
-                 pam-plugin-nologin \
-                 pam-plugin-env \
-                 pam-plugin-group \
-                 pam-plugin-limits \
-                 pam-plugin-lastlog \
-                 pam-plugin-motd \
-                 pam-plugin-mail \
-                 pam-plugin-shells \
-                 pam-plugin-rootok"
-                 
-DEPENDS = "${@base_contains('DISTRO_FEATURES', 'pam', 'libpam', '', d)}"
-RDEPENDS_${PN} = "${@base_contains('DISTRO_FEATURES', 'pam', '${PAM_PLUGINS}', '', d)}"
-
-# since we deduce from ${SERIAL_CONSOLE}
-PACKAGE_ARCH = "${MACHINE_ARCH}"
-
-# Additional Policy files for PAM
-PAM_SRC_URI = "file://pam.d/chfn \
-               file://pam.d/chpasswd \
-               file://pam.d/chsh \
-               file://pam.d/login \
-               file://pam.d/newusers \
-               file://pam.d/passwd \
-               file://pam.d/su"
-
-SRC_URI = "ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-${PV}.tar.bz2 \
-           file://login_defs_pam.sed \
-           ${@base_contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
-           file://securetty"
-
-inherit autotools gettext
-
-EXTRA_OECONF += "--without-audit \
-                 --without-libcrack \
-                 ${@base_contains('DISTRO_FEATURES', 'pam', '--with-libpam', '--without-libpam', d)} \
-                 --without-selinux"
-
-do_install_append() {
-	# Ensure that the image has as /var/spool/mail dir so shadow can put mailboxes there if the user
-	# reconfigures Shadow to default (see sed below).
-	install -d ${D}${localstatedir}/spool/mail
-
-	if [ -e ${WORKDIR}/pam.d ]; then
-		install -d ${D}${sysconfdir}/pam.d/
-		install -m 0644 ${WORKDIR}/pam.d/* ${D}${sysconfdir}/pam.d/
-		# Remove defaults that are not used when supporting PAM
-		sed -i -f ${WORKDIR}/login_defs_pam.sed ${D}${sysconfdir}/login.defs
-	fi
-
-	# Enable CREATE_HOME by default.
-	sed -i 's/#CREATE_HOME/CREATE_HOME/g' ${D}${sysconfdir}/login.defs
-
-	# As we are on an embedded system ensure the users mailbox is in ~/ not
-	# /var/spool/mail by default as who knows where or how big /var is.
-	# The system MDA will set this later anyway.
-	sed -i 's/MAIL_DIR/#MAIL_DIR/g' ${D}${sysconfdir}/login.defs
-	sed -i 's/#MAIL_FILE/MAIL_FILE/g' ${D}${sysconfdir}/login.defs
-
-	# disable checking emails at all
-	sed -i 's/MAIL_CHECK_ENAB/#MAIL_CHECK_ENAB/g' ${D}${sysconfdir}/login.defs
-
-	# now we don't have a mail system. disable mail creation for now
-	sed -i 's:/bin/bash:/bin/sh:g' ${D}${sysconfdir}/default/useradd
-	sed -i '/^CREATE_MAIL_SPOOL/ s:^:#:' ${D}${sysconfdir}/default/useradd
-
-	install -d ${D}${sbindir} ${D}${base_sbindir} ${D}${base_bindir} 
-	for i in passwd chfn newgrp chsh ; do
-		mv ${D}${bindir}/$i ${D}${bindir}/$i.${PN}
-	done
-
-	mv ${D}${sbindir}/chpasswd ${D}${sbindir}/chpasswd.${PN}
-	mv ${D}${sbindir}/vigr ${D}${base_sbindir}/vigr.${PN}
-	mv ${D}${sbindir}/vipw ${D}${base_sbindir}/vipw.${PN}
-	mv ${D}${bindir}/login ${D}${base_bindir}/login.${PN}
-
-	# Ensure we add a suitable securetty file to the package that has most common embedded TTYs defined.
-	if [ ! -z "${SERIAL_CONSOLE}" ]; then
-	# our SERIAL_CONSOLE contains baud rate too and sometime -L option as well.
-	# the following pearl :) takes that and converts it into newline sepated tty's and appends
-	# them into securetty. So if a machine has a weird looking console device node (e.g. ttyAMA0) that securetty
-	# does not know then it will get appended to securetty and root login will be allowed on
-	# that console.
-		echo "${SERIAL_CONSOLE}" | sed -e 's/[0-9][0-9]\|\-L//g'|tr "[ ]" "[\n]"  >> ${WORKDIR}/securetty
-	fi
-	install -m 0400 ${WORKDIR}/securetty ${D}${sysconfdir}/securetty 
-}
-
-pkg_postinst_${PN} () {
-	update-alternatives --install ${bindir}/passwd passwd passwd.${PN} 200
-	update-alternatives --install ${sbindir}/chpasswd chpasswd chpasswd.${PN} 200
-	update-alternatives --install ${bindir}/chfn chfn chfn.${PN} 200
-	update-alternatives --install ${bindir}/newgrp newgrp newgrp.${PN} 200
-	update-alternatives --install ${bindir}/chsh chsh chsh.${PN} 200
-	update-alternatives --install ${base_bindir}/login login login.${PN} 200
-	update-alternatives --install ${base_sbindir}/vipw vipw vipw.${PN} 200
-	update-alternatives --install ${base_sbindir}/vigr vigr vigr.${PN} 200
-
-	if [ "x$D" != "x" ]; then
-		exit 1
-	fi  
-
-	pwconv
-	grpconv
-}
-
-pkg_prerm_${PN} () {
-	for i in passwd chpasswd chfn newgrp chsh login vipw vigr ; do
-		update-alternatives --remove $i $i.${PN}
-	done
-}
diff --git a/meta/recipes-extended/shadow/shadow_4.1.4.3.bb b/meta/recipes-extended/shadow/shadow_4.1.4.3.bb
index c8aa223..25b7bca 100644
--- a/meta/recipes-extended/shadow/shadow_4.1.4.3.bb
+++ b/meta/recipes-extended/shadow/shadow_4.1.4.3.bb
@@ -1,14 +1,137 @@
-require shadow.inc
+SUMMARY = "Tools to change and administer password and group data"
+DESCRIPTION = "Tools to change and administer password and group data"
+HOMEPAGE = "http://pkg-shadow.alioth.debian.org"
+BUGTRACKER = "https://alioth.debian.org/tracker/?group_id=30580"
+SECTION = "base utils"
+PRIORITY = "optional"
+LICENSE = "BSD | Artistic"
+LIC_FILES_CHKSUM = "file://COPYING;md5=08c553a87d4e51bbed50b20e0adcaede \
+                    file://src/passwd.c;firstline=8;endline=30;md5=2899a045e90511d0e043b85a7db7e2fe"
 
-PR = "r1"
+DEPENDS = "${@base_contains('DISTRO_FEATURES', 'pam', 'libpam', '', d)}"
+RDEPENDS_${PN} = "${@base_contains('DISTRO_FEATURES', 'pam', '${PAM_PLUGINS}', '', d)}"
+PR = "r2"
 
-SRC_URI += "file://shadow.automake-1.11.patch \
-	    file://shadow-4.1.3-dots-in-usernames.patch \
-	    file://shadow-4.1.4.2-env-reset-keep-locale.patch \
-	    file://shadow-4.1.4.2-groupmod-pam-check.patch \
-	    file://shadow-4.1.4.2-su_no_sanitize_env.patch"
+SRC_URI = "ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-${PV}.tar.bz2 \
+           file://login_defs_pam.sed \
+           ${@base_contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
+           file://securetty \
+           file://shadow.automake-1.11.patch \
+           file://shadow-4.1.3-dots-in-usernames.patch \
+           file://shadow-4.1.4.2-env-reset-keep-locale.patch \
+           file://shadow-4.1.4.2-groupmod-pam-check.patch \
+           file://shadow-4.1.4.2-su_no_sanitize_env.patch"
 
 SRC_URI[md5sum] = "b8608d8294ac88974f27b20f991c0e79"
-SRC_URI[sha256sum] = "633f5bb4ea0c88c55f3642c97f9d25cbef74f82e0b4cf8d54e7ad6f9f9caa778"
+SRC_URI[sha256sum] = "633f5bb4ea0c88c55f3642c97f9d25cbef74f82e0b4cf8d54e7ad6f9f9caa778" 
 
-EXTRA_OECONF_libc-uclibc += " --with-nscd=no "
+inherit autotools gettext
+
+# Since we deduce our arch from ${SERIAL_CONSOLE}
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+EXTRA_OECONF += "--without-audit \
+                 --without-libcrack \
+                 ${@base_contains('DISTRO_FEATURES', 'pam', '--with-libpam', '--without-libpam', d)} \
+                 --without-selinux"
+EXTRA_OECONF_libc-uclibc += "--with-nscd=no"
+
+PAM_PLUGINS = "libpam-runtime \
+               pam-plugin-faildelay \
+               pam-plugin-securetty \
+               pam-plugin-nologin \
+               pam-plugin-env \
+               pam-plugin-group \
+               pam-plugin-limits \
+               pam-plugin-lastlog \
+               pam-plugin-motd \
+               pam-plugin-mail \
+               pam-plugin-shells \
+               pam-plugin-rootok"
+                 
+# Additional Policy files for PAM
+PAM_SRC_URI = "file://pam.d/chfn \
+               file://pam.d/chpasswd \
+               file://pam.d/chsh \
+               file://pam.d/login \
+               file://pam.d/newusers \
+               file://pam.d/passwd \
+               file://pam.d/su"
+
+do_install_append() {
+	# Ensure that the image has as a /var/spool/mail dir so shadow can
+	# put mailboxes there if the user reconfigures shadow to its
+	# defaults (see sed below).
+	install -d ${D}${localstatedir}/spool/mail
+
+	if [ -e ${WORKDIR}/pam.d ]; then
+		install -d ${D}${sysconfdir}/pam.d/
+		install -m 0644 ${WORKDIR}/pam.d/* ${D}${sysconfdir}/pam.d/
+		# Remove defaults that are not used when supporting PAM.
+		sed -i -f ${WORKDIR}/login_defs_pam.sed ${D}${sysconfdir}/login.defs
+	fi
+
+	# Enable CREATE_HOME by default.
+	sed -i 's/#CREATE_HOME/CREATE_HOME/g' ${D}${sysconfdir}/login.defs
+
+	# As we are on an embedded system, ensure the users mailbox is in
+	# ~/ not /var/spool/mail by default, as who knows where or how big
+	# /var is. The system MDA will set this later anyway.
+	sed -i 's/MAIL_DIR/#MAIL_DIR/g' ${D}${sysconfdir}/login.defs
+	sed -i 's/#MAIL_FILE/MAIL_FILE/g' ${D}${sysconfdir}/login.defs
+
+	# Disable checking emails.
+	sed -i 's/MAIL_CHECK_ENAB/#MAIL_CHECK_ENAB/g' ${D}${sysconfdir}/login.defs
+
+	# Now we don't have a mail system. Disable mail creation for now.
+	sed -i 's:/bin/bash:/bin/sh:g' ${D}${sysconfdir}/default/useradd
+	sed -i '/^CREATE_MAIL_SPOOL/ s:^:#:' ${D}${sysconfdir}/default/useradd
+
+	install -d ${D}${sbindir} ${D}${base_sbindir} ${D}${base_bindir} 
+	for i in passwd chfn newgrp chsh ; do
+		mv ${D}${bindir}/$i ${D}${bindir}/$i.${PN}
+	done
+
+	mv ${D}${sbindir}/chpasswd ${D}${sbindir}/chpasswd.${PN}
+	mv ${D}${sbindir}/vigr ${D}${base_sbindir}/vigr.${PN}
+	mv ${D}${sbindir}/vipw ${D}${base_sbindir}/vipw.${PN}
+	mv ${D}${bindir}/login ${D}${base_bindir}/login.${PN}
+
+	# Ensure we add a suitable securetty file to the package that has
+	# most common embedded TTYs defined.
+	if [ ! -z "${SERIAL_CONSOLE}" ]; then
+		# Our SERIAL_CONSOLE contains a baud rate and sometimes a -L
+		# option as well. The following pearl :) takes that and converts
+		# it into newline-separated tty's and appends them into
+		# securetty. So if a machine has a weird looking console device
+		# node (e.g. ttyAMA0) that securetty does not know, it will get
+		# appended to securetty and root logins will be allowed on that
+		# console.
+		echo "${SERIAL_CONSOLE}" | sed -e 's/[0-9][0-9]\|\-L//g'|tr "[ ]" "[\n]"  >> ${WORKDIR}/securetty
+	fi
+	install -m 0400 ${WORKDIR}/securetty ${D}${sysconfdir}/securetty 
+}
+
+pkg_postinst_${PN} () {
+	update-alternatives --install ${bindir}/passwd passwd passwd.${PN} 200
+	update-alternatives --install ${sbindir}/chpasswd chpasswd chpasswd.${PN} 200
+	update-alternatives --install ${bindir}/chfn chfn chfn.${PN} 200
+	update-alternatives --install ${bindir}/newgrp newgrp newgrp.${PN} 200
+	update-alternatives --install ${bindir}/chsh chsh chsh.${PN} 200
+	update-alternatives --install ${base_bindir}/login login login.${PN} 200
+	update-alternatives --install ${base_sbindir}/vipw vipw vipw.${PN} 200
+	update-alternatives --install ${base_sbindir}/vigr vigr vigr.${PN} 200
+
+	if [ "x$D" != "x" ]; then
+		exit 1
+	fi  
+
+	pwconv
+	grpconv
+}
+
+pkg_prerm_${PN} () {
+	for i in passwd chpasswd chfn newgrp chsh login vipw vigr ; do
+		update-alternatives --remove $i $i.${PN}
+	done
+}
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/7] shadow: add a -native recipe with customized utilities
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
  2011-06-02 23:50 ` [PATCH 1/7] shadow: recipe and patch cleanup Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-02 23:50 ` [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs Scott Garman
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

This adds a -native recipe for the shadow utilities.

The custom --root option allows the the following utilities to be
run within a chroot when invoked under pseudo:

* useradd
* groupadd
* usermod
* groupmod
* userdel
* groupdel
* passwd
* gpasswd
* pwconv
* pwunconv
* grpconv
* grpunconv

They can then be used to manipulate user and group account information
in target sysroots.

useradd was also modified to create home directories recursively when
necessary.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 .../shadow/files/add_root_cmd_options.patch        | 1296 ++++++++++++++++++++
 .../shadow/shadow-native_4.1.4.3.bb                |   66 +
 2 files changed, 1362 insertions(+), 0 deletions(-)
 create mode 100644 meta/recipes-extended/shadow/files/add_root_cmd_options.patch
 create mode 100644 meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb

diff --git a/meta/recipes-extended/shadow/files/add_root_cmd_options.patch b/meta/recipes-extended/shadow/files/add_root_cmd_options.patch
new file mode 100644
index 0000000..db969bb
--- /dev/null
+++ b/meta/recipes-extended/shadow/files/add_root_cmd_options.patch
@@ -0,0 +1,1296 @@
+Add a --root command option to the following utilties:
+
+* useradd
+* groupadd
+* usermod
+* groupmod
+* userdel
+* groupdel
+* passwd
+* gpasswd
+* pwconv
+* pwunconv
+* grpconv
+* grpunconv
+
+This option allows the utilities to be chrooted when run under pseudo.
+They can then be used to manipulate user and group account information
+in target sysroots.
+
+The useradd utility was also modified to create home directories
+recursively when necessary.
+
+Upstream-Status: Inappropriate [Other]
+Workaround is specific to our build system.
+
+Signed-off-by: Scott Garman <scott.a.garman@intel.com>
+
+diff -urN shadow-4.1.4.3.orig//src/gpasswd.c shadow-4.1.4.3//src/gpasswd.c
+--- shadow-4.1.4.3.orig//src/gpasswd.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/gpasswd.c	2011-05-28 17:09:52.346013331 -0700
+@@ -63,6 +63,7 @@
+  * (/etc/gshadow present) */
+ static bool is_shadowgrp;
+ #endif
++static const char *newroot = "";
+ 
+ /* Flags set by options */
+ static bool aflg = false;
+@@ -97,6 +98,7 @@
+ static void usage (void);
+ static RETSIGTYPE catch_signals (int killed);
+ static bool is_valid_user_list (const char *users);
++static void process_root_flag (int argc, char **argv);
+ static void process_flags (int argc, char **argv);
+ static void check_flags (int argc, int opt_index);
+ static void open_files (void);
+@@ -136,6 +138,7 @@
+ 	           "Options:\n"
+ 	           "  -a, --add USER                add USER to GROUP\n"
+ 	           "  -d, --delete USER             remove USER from GROUP\n"
++	           "  -Q  --root CHROOT_DIR         directory to chroot into\n"
+ 	           "  -r, --remove-password         remove the GROUP's password\n"
+ 	           "  -R, --restrict                restrict access to GROUP to its members\n"
+ 	           "  -M, --members USER,...        set the list of members of GROUP\n"
+@@ -226,6 +229,55 @@
+ }
+ 
+ /*
++ * process_root_flag - chroot if given the --root option
++ *
++ * We do this outside of process_flags() because
++ * the is_shadow_pwd boolean needs to be set before
++ * process_flags(), and if we do need to chroot() we
++ * must do so before is_shadow_pwd gets set.
++ */
++static void process_root_flag (int argc, char **argv)
++{
++	/*
++	 * Parse the command line options.
++	 */
++	int flag;
++	int option_index = 0;
++	static struct option long_options[] = {
++		{"root", required_argument, NULL, 'Q'},
++		{NULL, 0, NULL, '\0'}
++	};
++
++	while ((flag = getopt_long (argc, argv, "a:A:d:gM:Q:rR", long_options, &option_index)) != -1) {
++		switch (flag) {
++		case 'Q':
++			if ('/' != optarg[0]) {
++				fprintf (stderr,
++				         _("%s: invalid chroot path '%s'\n"),
++				         Prog, optarg);
++				exit (E_BAD_ARG);
++			}
++			newroot = optarg;
++
++			if (access (newroot, F_OK) != 0) {
++				fprintf(stderr,
++				        _("%s: chroot directory %s does not exist\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			if ( chroot(newroot) != 0 ) {
++				fprintf(stderr,
++				        _("%s: unable to chroot to directory %s\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			break;
++		/* no-op on everything else - they will be hanled by process_flags() */
++		}
++	}
++}
++
++/*
+  * process_flags - process the command line options and arguments
+  */
+ static void process_flags (int argc, char **argv)
+@@ -235,6 +287,7 @@
+ 	static struct option long_options[] = {
+ 		{"add", required_argument, NULL, 'a'},
+ 		{"delete", required_argument, NULL, 'd'},
++		{"root", required_argument, NULL, 'Q'},
+ 		{"remove-password", no_argument, NULL, 'r'},
+ 		{"restrict", no_argument, NULL, 'R'},
+ 		{"administrators", required_argument, NULL, 'A'},
+@@ -242,7 +295,7 @@
+ 		{NULL, 0, NULL, '\0'}
+ 		};
+ 
+-	while ((flag = getopt_long (argc, argv, "a:A:d:gM:rR", long_options, &option_index)) != -1) {
++	while ((flag = getopt_long (argc, argv, "a:A:d:gM:Q:rR", long_options, &option_index)) != -1) {
+ 		switch (flag) {
+ 		case 'a':	/* add a user */
+ 			aflg = true;
+@@ -283,6 +336,9 @@
+ 			}
+ 			Mflg = true;
+ 			break;
++		case 'Q':
++			/* no-op since we handled this in process_root_flag() earlier */
++			break;
+ 		case 'r':	/* remove group password */
+ 			rflg = true;
+ 			break;
+@@ -995,6 +1051,8 @@
+ 	setbuf (stdout, NULL);
+ 	setbuf (stderr, NULL);
+ 
++	process_root_flag (argc, argv);
++
+ #ifdef SHADOWGRP
+ 	is_shadowgrp = sgr_file_present ();
+ #endif
+diff -urN shadow-4.1.4.3.orig//src/groupadd.c shadow-4.1.4.3//src/groupadd.c
+--- shadow-4.1.4.3.orig//src/groupadd.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/groupadd.c	2011-05-28 17:09:52.346013331 -0700
+@@ -76,6 +76,7 @@
+ static gid_t group_id;
+ static /*@null@*/char *group_passwd;
+ static /*@null@*/char *empty_list = NULL;
++static const char *newroot = "";
+ 
+ static bool oflg = false;	/* permit non-unique group ID to be specified with -g */
+ static bool gflg = false;	/* ID value for the new group */
+@@ -120,6 +121,7 @@
+ 	(void) fputs (_("  -o, --non-unique              allow to create groups with duplicate\n"
+ 	                "                                (non-unique) GID\n"), stderr);
+ 	(void) fputs (_("  -p, --password PASSWORD       use this encrypted password for the new group\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
+ 	(void) fputs (_("  -r, --system                  create a system account\n"), stderr);
+ 	(void) fputs ("\n", stderr);
+ 	exit (E_USAGE);
+@@ -383,12 +385,13 @@
+ 		{"key", required_argument, NULL, 'K'},
+ 		{"non-unique", no_argument, NULL, 'o'},
+ 		{"password", required_argument, NULL, 'p'},
++		{"root", required_argument, NULL, 'R'},
+ 		{"system", no_argument, NULL, 'r'},
+ 		{NULL, 0, NULL, '\0'}
+ 	};
+ 
+ 	while ((c =
+-		getopt_long (argc, argv, "fg:hK:op:r", long_options,
++		getopt_long (argc, argv, "fg:hK:op:R:r", long_options,
+ 		             &option_index)) != -1) {
+ 		switch (c) {
+ 		case 'f':
+@@ -440,6 +443,28 @@
+ 			pflg = true;
+ 			group_passwd = optarg;
+ 			break;
++		case 'R':
++			if ('/' != optarg[0]) {
++				fprintf (stderr,
++				         _("%s: invalid chroot path '%s'\n"),
++				         Prog, optarg);
++				exit (E_BAD_ARG);
++			}
++			newroot = optarg;
++
++			if (access (newroot, F_OK) != 0) {
++				fprintf(stderr,
++				        _("%s: chroot directory %s does not exist\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			if ( chroot(newroot) != 0 ) {
++				fprintf(stderr,
++				        _("%s: unable to chroot to directory %s\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			break;
+ 		case 'r':
+ 			rflg = true;
+ 			break;
+diff -urN shadow-4.1.4.3.orig//src/groupdel.c shadow-4.1.4.3//src/groupdel.c
+--- shadow-4.1.4.3.orig//src/groupdel.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/groupdel.c	2011-05-28 17:09:52.346013331 -0700
+@@ -36,6 +36,7 @@
+ 
+ #include <ctype.h>
+ #include <fcntl.h>
++#include <getopt.h>
+ #include <grp.h>
+ #include <pwd.h>
+ #ifdef ACCT_TOOLS_SETUID
+@@ -59,6 +60,7 @@
+ 
+ static char *group_name;
+ static gid_t group_id = -1;
++static const char *newroot = "";
+ 
+ #ifdef	SHADOWGRP
+ static bool is_shadow_grp;
+@@ -70,12 +72,14 @@
+ /*@-exitarg@*/
+ #define E_SUCCESS	0	/* success */
+ #define E_USAGE		2	/* invalid command syntax */
++#define E_BAD_ARG	3	/* invalid argument to option */
+ #define E_NOTFOUND	6	/* specified group doesn't exist */
+ #define E_GROUP_BUSY	8	/* can't remove user's primary group */
+ #define E_GRP_UPDATE	10	/* can't update group file */
+ 
+ /* local function prototypes */
+ static void usage (void);
++static void process_flags (int argc, char **argv);
+ static void grp_update (void);
+ static void close_files (void);
+ static void open_files (void);
+@@ -86,11 +90,78 @@
+  */
+ static void usage (void)
+ {
+-	fputs (_("Usage: groupdel group\n"), stderr);
++	(void) fprintf (stderr,
++					_("Usage: groupdel [options]\n"
++					  "\n"
++					  "Options:\n"),
++					Prog);
++	(void) fputs (_("  -g, --group GROUP            group name to delete\n"), stderr);
++	(void) fputs (_("  -h, --help                   display this help message and exit\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR        directory to chroot into\n"), stderr);
++	(void) fputs ("\n", stderr);
+ 	exit (E_USAGE);
+ }
+ 
+ /*
++ * process_flags - perform command line argument setting
++ *
++ *	process_flags() interprets the command line arguments and sets
++ *	the values that the user will be created with accordingly. The
++ *	values are checked for sanity.
++ */
++static void process_flags (int argc, char **argv)
++{
++	{
++		/*
++		 * Parse the command line options.
++		 */
++		int c;
++		static struct option long_options[] = {
++			{"group", required_argument, NULL, 'g'},
++			{"help", no_argument, NULL, 'h'},
++			{"root", required_argument, NULL, 'R'},
++			{NULL, 0, NULL, '\0'}
++		};
++		while ((c = getopt_long (argc, argv,
++								 "g:R:",
++								 long_options, NULL)) != -1) {
++			switch (c) {
++			case 'g':
++				group_name = optarg;
++				break;
++			case 'h':
++				usage ();
++				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++							_("%s: invalid chroot path '%s'\n"),
++							Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++							_("%s: chroot directory %s does not exist\n"),
++							Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++							_("%s: unable to chroot to directory %s\n"),
++							Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
++			default:
++				usage ();
++			}
++		}
++	}
++}
++
++/*
+  * grp_update - update group file entries
+  *
+  *	grp_update() writes the new records to the group files.
+@@ -328,14 +399,14 @@
+ 	(void) bindtextdomain (PACKAGE, LOCALEDIR);
+ 	(void) textdomain (PACKAGE);
+ 
+-	if (argc != 2) {
++   if (argc == 1) {
+ 		usage ();
+ 	}
+ 
+-	group_name = argv[1];
+-
+ 	OPENLOG ("groupdel");
+ 
++	process_flags (argc, argv);
++
+ #ifdef ACCT_TOOLS_SETUID
+ #ifdef USE_PAM
+ 	{
+diff -urN shadow-4.1.4.3.orig//src/groupmod.c shadow-4.1.4.3//src/groupmod.c
+--- shadow-4.1.4.3.orig//src/groupmod.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/groupmod.c	2011-05-28 17:09:52.346013331 -0700
+@@ -79,6 +79,7 @@
+ static char *group_passwd;
+ static gid_t group_id;
+ static gid_t group_newid;
++static char *newroot = "";
+ 
+ struct cleanup_info_mod info_passwd;
+ struct cleanup_info_mod info_group;
+@@ -126,6 +127,7 @@
+ 	(void) fputs (_("  -o, --non-unique              allow to use a duplicate (non-unique) GID\n"), stderr);
+ 	(void) fputs (_("  -p, --password PASSWORD       change the password to this (encrypted)\n"
+ 	                "                                PASSWORD\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
+ 	(void) fputs ("\n", stderr);
+ 	exit (E_USAGE);
+ }
+@@ -346,10 +348,11 @@
+ 		{"new-name", required_argument, NULL, 'n'},
+ 		{"non-unique", no_argument, NULL, 'o'},
+ 		{"password", required_argument, NULL, 'p'},
++		{"root", required_argument, NULL, 'R'},
+ 		{NULL, 0, NULL, '\0'}
+ 	};
+ 	while ((c =
+-		getopt_long (argc, argv, "g:hn:op:",
++		getopt_long (argc, argv, "g:hn:op:R:",
+ 		             long_options, &option_index)) != -1) {
+ 		switch (c) {
+ 		case 'g':
+@@ -373,6 +376,28 @@
+ 			group_passwd = optarg;
+ 			pflg = true;
+ 			break;
++		case 'R':
++			if ('/' != optarg[0]) {
++				fprintf (stderr,
++				         _("%s: invalid chroot path '%s'\n"),
++				         Prog, optarg);
++				exit (E_BAD_ARG);
++			}
++			newroot = optarg;
++
++			if (access (newroot, F_OK) != 0) {
++				fprintf(stderr,
++				        _("%s: chroot directory %s does not exist\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			if ( chroot(newroot) != 0 ) {
++				fprintf(stderr,
++				        _("%s: unable to chroot to directory %s\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			break;
+ 		default:
+ 			usage ();
+ 		}
+diff -urN shadow-4.1.4.3.orig//src/grpconv.c shadow-4.1.4.3//src/grpconv.c
+--- shadow-4.1.4.3.orig//src/grpconv.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/grpconv.c	2011-05-28 17:09:52.346013331 -0700
+@@ -39,6 +39,7 @@
+ 
+ #include <errno.h>
+ #include <fcntl.h>
++#include <getopt.h>
+ #include <grp.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -50,6 +51,14 @@
+ #ifdef SHADOWGRP
+ #include "groupio.h"
+ #include "sgroupio.h"
++
++/*
++ * exit status values
++ */
++/*@-exitarg@*/
++#define E_USAGE		2	/* invalid command syntax */
++#define E_BAD_ARG	3	/* invalid argument to option */
++
+ /*
+  * Global variables
+  */
+@@ -57,9 +66,12 @@
+ 
+ static bool gr_locked  = false;
+ static bool sgr_locked = false;
++static const char *newroot = "";
+ 
+ /* local function prototypes */
+ static void fail_exit (int status);
++static void usage (void);
++static void process_flags (int argc, char **argv);
+ 
+ static void fail_exit (int status)
+ {
+@@ -82,6 +94,77 @@
+ 	exit (status);
+ }
+ 
++/*
++ * usage - display usage message and exit
++ */
++static void usage (void)
++{
++	(void) fprintf (stderr,
++					_("Usage: grpconv [options]\n"
++					  "\n"
++					  "Options:\n"),
++					Prog);
++	(void) fputs (_("  -h, --help                    display this help message and exit\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
++	(void) fputs ("\n", stderr);
++	exit (E_USAGE);
++}
++
++/*
++ * process_flags - perform command line argument setting
++ *
++ *	process_flags() interprets the command line arguments and sets
++ *	the values that the user will be created with accordingly. The
++ *	values are checked for sanity.
++ */
++static void process_flags (int argc, char **argv)
++{
++	{
++		/*
++		 * Parse the command line options.
++		 */
++		int c;
++		static struct option long_options[] = {
++			{"help", no_argument, NULL, 'h'},
++			{"root", required_argument, NULL, 'R'},
++			{NULL, 0, NULL, '\0'}
++		};
++		while ((c = getopt_long (argc, argv,
++								 "R:",
++								 long_options, NULL)) != -1) {
++			switch (c) {
++			case 'h':
++				usage ();
++				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++					        _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
++			default:
++				usage ();
++			}
++		}
++	}
++}
++
+ int main (int argc, char **argv)
+ {
+ 	const struct group *gr;
+@@ -100,6 +183,8 @@
+ 
+ 	OPENLOG ("grpconv");
+ 
++	process_flags (argc, argv);
++
+ 	if (gr_lock () == 0) {
+ 		fprintf (stderr,
+ 		         _("%s: cannot lock %s; try again later.\n"),
+diff -urN shadow-4.1.4.3.orig//src/grpunconv.c shadow-4.1.4.3//src/grpunconv.c
+--- shadow-4.1.4.3.orig//src/grpunconv.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/grpunconv.c	2011-05-28 17:09:52.346013331 -0700
+@@ -43,6 +43,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <fcntl.h>
++#include <getopt.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <grp.h>
+@@ -51,6 +52,14 @@
+ #ifdef SHADOWGRP
+ #include "groupio.h"
+ #include "sgroupio.h"
++
++/*
++ * exit status values
++ */
++/*@-exitarg@*/
++#define E_USAGE		2	/* invalid command syntax */
++#define E_BAD_ARG	3	/* invalid argument to option */
++
+ /*
+  * Global variables
+  */
+@@ -58,9 +67,12 @@
+ 
+ static bool gr_locked  = false;
+ static bool sgr_locked = false;
++static const char *newroot = "";
+ 
+ /* local function prototypes */
+ static void fail_exit (int status);
++static void usage (void);
++static void process_flags (int argc, char **argv);
+ 
+ static void fail_exit (int status)
+ {
+@@ -83,6 +95,77 @@
+ 	exit (status);
+ }
+ 
++/*
++ * usage - display usage message and exit
++ */
++static void usage (void)
++{
++	(void) fprintf (stderr,
++					_("Usage: grpunconv [options]\n"
++					  "\n"
++					  "Options:\n"),
++					Prog);
++	(void) fputs (_("  -h, --help                    display this help message and exit\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
++	(void) fputs ("\n", stderr);
++	exit (E_USAGE);
++}
++
++/*
++ * process_flags - perform command line argument setting
++ *
++ * process_flags() interprets the command line arguments and sets
++ * the values that the user will be created with accordingly. The
++ * values are checked for sanity.
++ */
++static void process_flags (int argc, char **argv)
++{
++	{
++		/*
++		 * Parse the command line options.
++		 */
++		int c;
++		static struct option long_options[] = {
++			{"help", no_argument, NULL, 'h'},
++			{"root", required_argument, NULL, 'R'},
++			{NULL, 0, NULL, '\0'}
++		};
++		while ((c = getopt_long (argc, argv,
++								 "R:",
++								 long_options, NULL)) != -1) {
++			switch (c) {
++			case 'h':
++				usage ();
++				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++					        _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
++			default:
++				usage ();
++			}
++		}
++	}
++}
++
+ int main (int argc, char **argv)
+ {
+ 	const struct group *gr;
+@@ -100,6 +183,8 @@
+ 
+ 	OPENLOG ("grpunconv");
+ 
++	process_flags (argc, argv);
++
+ 	if (sgr_file_present () == 0) {
+ 		exit (0);	/* no /etc/gshadow, nothing to do */
+ 	}
+diff -urN shadow-4.1.4.3.orig//src/passwd.c shadow-4.1.4.3//src/passwd.c
+--- shadow-4.1.4.3.orig//src/passwd.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/passwd.c	2011-05-28 17:09:52.346013331 -0700
+@@ -75,6 +75,7 @@
+ static char *name;		/* The name of user whose password is being changed */
+ static char *myname;		/* The current user's name */
+ static bool amroot;		/* The caller's real UID was 0 */
++static const char *newroot = "";
+ 
+ static bool
+     aflg = false,			/* -a - show status for all users */
+@@ -174,6 +175,7 @@
+ 	         "  -n, --mindays MIN_DAYS        set minimum number of days before password\n"
+ 	         "                                change to MIN_DAYS\n"
+ 	         "  -q, --quiet                   quiet mode\n"
++	         "  -R, --root CHROOT_DIR         directory to chroot into\n"
+ 	         "  -r, --repository REPOSITORY   change password in REPOSITORY repository\n"
+ 	         "  -S, --status                  report password status on the named account\n"
+ 	         "  -u, --unlock                  unlock the password of the named account\n"
+@@ -803,6 +805,7 @@
+ 			{"lock", no_argument, NULL, 'l'},
+ 			{"mindays", required_argument, NULL, 'n'},
+ 			{"quiet", no_argument, NULL, 'q'},
++			{"root", required_argument, NULL, 'R'},
+ 			{"repository", required_argument, NULL, 'r'},
+ 			{"status", no_argument, NULL, 'S'},
+ 			{"unlock", no_argument, NULL, 'u'},
+@@ -811,7 +814,7 @@
+ 			{NULL, 0, NULL, '\0'}
+ 		};
+ 
+-		while ((c = getopt_long (argc, argv, "adei:kln:qr:Suw:x:",
++		while ((c = getopt_long (argc, argv, "adei:kln:qR:r:Suw:x:",
+ 		                         long_options, &option_index)) != -1) {
+ 			switch (c) {
+ 			case 'a':
+@@ -858,6 +861,28 @@
+ 			case 'q':
+ 				qflg = true;	/* ok for users */
+ 				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++				            _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
+ 			case 'r':
+ 				/* -r repository (files|nis|nisplus) */
+ 				/* only "files" supported for now */
+diff -urN shadow-4.1.4.3.orig//src/pwconv.c shadow-4.1.4.3//src/pwconv.c
+--- shadow-4.1.4.3.orig//src/pwconv.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/pwconv.c	2011-05-28 17:09:52.346013331 -0700
+@@ -59,6 +59,7 @@
+ 
+ #include <errno.h>
+ #include <fcntl.h>
++#include <getopt.h>
+ #include <pwd.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -79,6 +80,7 @@
+ #define E_SUCCESS	0	/* success */
+ #define E_NOPERM	1	/* permission denied */
+ #define E_USAGE		2	/* invalid command syntax */
++#define E_BAD_ARG	3	/* invalid argument to option */
+ #define E_FAILURE	3	/* unexpected failure, nothing done */
+ #define E_MISSING	4	/* unexpected failure, passwd file missing */
+ #define E_PWDBUSY	5	/* passwd file(s) busy */
+@@ -90,9 +92,12 @@
+ 
+ static bool spw_locked = false;
+ static bool pw_locked = false;
++static const char *newroot = "";
+ 
+ /* local function prototypes */
+ static void fail_exit (int status);
++static void usage (void);
++static void process_flags (int argc, char **argv);
+ 
+ static void fail_exit (int status)
+ {
+@@ -115,6 +120,77 @@
+ 	exit (status);
+ }
+ 
++/*
++ * usage - display usage message and exit
++ */
++static void usage (void)
++{
++	(void) fprintf (stderr,
++					_("Usage: pwconv [options]\n"
++					  "\n"
++					  "Options:\n"),
++					Prog);
++	(void) fputs (_("  -h, --help                    display this help message and exit\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
++	(void) fputs ("\n", stderr);
++	exit (E_USAGE);
++}
++
++/*
++ * process_flags - perform command line argument setting
++ *
++ *	process_flags() interprets the command line arguments and sets
++ *	the values that the user will be created with accordingly. The
++ *	values are checked for sanity.
++ */
++static void process_flags (int argc, char **argv)
++{
++	{
++		/*
++		 * Parse the command line options.
++		 */
++		int c;
++		static struct option long_options[] = {
++			{"help", no_argument, NULL, 'h'},
++			{"root", required_argument, NULL, 'R'},
++			{NULL, 0, NULL, '\0'}
++		};
++		while ((c = getopt_long (argc, argv,
++								 "R:",
++								 long_options, NULL)) != -1) {
++			switch (c) {
++			case 'h':
++				usage ();
++				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++					        _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
++			default:
++				usage ();
++			}
++		}
++	}
++}
++
+ int main (int argc, char **argv)
+ {
+ 	const struct passwd *pw;
+@@ -122,9 +198,6 @@
+ 	const struct spwd *sp;
+ 	struct spwd spent;
+ 
+-	if (1 != argc) {
+-		(void) fputs (_("Usage: pwconv\n"), stderr);
+-	}
+ 	Prog = Basename (argv[0]);
+ 
+ 	(void) setlocale (LC_ALL, "");
+@@ -133,6 +206,8 @@
+ 
+ 	OPENLOG ("pwconv");
+ 
++	process_flags (argc, argv);
++
+ 	if (pw_lock () == 0) {
+ 		fprintf (stderr,
+ 		         _("%s: cannot lock %s; try again later.\n"),
+diff -urN shadow-4.1.4.3.orig//src/pwunconv.c shadow-4.1.4.3//src/pwunconv.c
+--- shadow-4.1.4.3.orig//src/pwunconv.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/pwunconv.c	2011-05-28 17:09:52.356013600 -0700
+@@ -35,6 +35,7 @@
+ #ident "$Id: pwunconv.c 2852 2009-04-30 21:44:35Z nekral-guest $"
+ 
+ #include <fcntl.h>
++#include <getopt.h>
+ #include <pwd.h>
+ #include <stdio.h>
+ #include <sys/types.h>
+@@ -46,15 +47,24 @@
+ #include "shadowio.h"
+ 
+ /*
++ * exit status values
++ */
++/*@-exitarg@*/
++#define E_USAGE		2	/* invalid command syntax */
++#define E_BAD_ARG	3	/* invalid argument to option */
++/*
+  * Global variables
+  */
+ char *Prog;
+ 
+ static bool spw_locked = false;
+ static bool pw_locked = false;
++static const char *newroot = "";
+ 
+ /* local function prototypes */
+ static void fail_exit (int status);
++static void usage (void);
++static void process_flags (int argc, char **argv);
+ 
+ static void fail_exit (int status)
+ {
+@@ -75,6 +85,76 @@
+ 	exit (status);
+ }
+ 
++/*
++ * usage - display usage message and exit
++ */
++static void usage (void)
++{
++	(void) fprintf (stderr,
++					_("Usage: pwunconv [options]\n"
++					  "\n"
++					  "Options:\n"),
++					Prog);
++	(void) fputs (_("  -h, --help                    display this help message and exit\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
++	(void) fputs ("\n", stderr);
++	exit (E_USAGE);
++}
++
++/*
++ * process_flags - perform command line argument setting
++ *
++ * process_flags() interprets the command line arguments and sets
++ * the values that the user will be created with accordingly. The
++ * values are checked for sanity.
++ */
++static void process_flags (int argc, char **argv)
++{
++	{
++		/*
++		 * Parse the command line options.
++		 */
++		int c;
++		static struct option long_options[] = {
++			{"help", no_argument, NULL, 'h'},
++			{"root", required_argument, NULL, 'R'},
++			{NULL, 0, NULL, '\0'}
++		};
++		while ((c = getopt_long (argc, argv,
++								 "R:",
++								 long_options, NULL)) != -1) {
++			switch (c) {
++			case 'h':
++				usage ();
++				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++					        _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
++			default:
++				usage ();
++			}
++		}
++	}
++}
+ 
+ int main (int argc, char **argv)
+ {
+@@ -93,6 +173,8 @@
+ 
+ 	OPENLOG ("pwunconv");
+ 
++	process_flags (argc, argv);
++
+ 	if (!spw_file_present ()) {
+ 		/* shadow not installed, do nothing */
+ 		exit (0);
+diff -urN shadow-4.1.4.3.orig//src/useradd.c shadow-4.1.4.3//src/useradd.c
+--- shadow-4.1.4.3.orig//src/useradd.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/useradd.c	2011-05-28 17:10:25.446909971 -0700
+@@ -112,6 +112,7 @@
+ #ifdef WITH_SELINUX
+ static const char *user_selinux = "";
+ #endif
++static const char *newroot = "";
+ 
+ static long user_expire = -1;
+ static bool is_shadow_pwd;
+@@ -189,6 +190,7 @@
+ static void new_spent (struct spwd *);
+ static void grp_update (void);
+ 
++static void process_root_flag (int argc, char **argv);
+ static void process_flags (int argc, char **argv);
+ static void close_files (void);
+ static void open_files (void);
+@@ -711,6 +713,7 @@
+ 	(void) fputs (_("  -o, --non-unique              allow to create users with duplicate\n"
+ 	                "                                (non-unique) UID\n"), stderr);
+ 	(void) fputs (_("  -p, --password PASSWORD       encrypted password of the new account\n"), stderr);
++	(void) fputs (_("  -R, --root CHROOT_DIR         directory to chroot into\n"), stderr);
+ 	(void) fputs (_("  -r, --system                  create a system account\n"), stderr);
+ 	(void) fputs (_("  -s, --shell SHELL             login shell of the new account\n"), stderr);
+ 	(void) fputs (_("  -u, --uid UID                 user ID of the new account\n"), stderr);
+@@ -943,6 +946,59 @@
+ }
+ 
+ /*
++ * process_root_flag - chroot if given the --root option
++ *
++ * We do this outside of process_flags() because
++ * the is_shadow_pwd boolean needs to be set before
++ * process_flags(), and if we do need to chroot() we
++ * must do so before is_shadow_pwd gets set.
++ */
++static void process_root_flag (int argc, char **argv)
++{
++	/*
++	 * Parse the command line options.
++	 */
++	int c;
++	static struct option long_options[] = {
++		{"root", required_argument, NULL, 'R'},
++		{NULL, 0, NULL, '\0'}
++	};
++	while ((c = getopt_long (argc, argv,
++#ifdef WITH_SELINUX
++	                         "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:UZ:",
++#else
++	                         "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:U",
++#endif
++	                         long_options, NULL)) != -1) {
++		switch (c) {
++		case 'R':
++			if ('/' != optarg[0]) {
++				fprintf (stderr,
++				         _("%s: invalid chroot path '%s'\n"),
++				         Prog, optarg);
++				exit (E_BAD_ARG);
++			}
++			newroot = optarg;
++
++			if (access (newroot, F_OK) != 0) {
++				fprintf(stderr,
++				        _("%s: chroot directory %s does not exist\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			if ( chroot(newroot) != 0 ) {
++				fprintf(stderr,
++				        _("%s: unable to chroot to directory %s\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			break;
++		/* no-op on everything else - they will be hanled by process_flags() */
++		}
++	}
++}
++
++/*
+  * process_flags - perform command line argument setting
+  *
+  *	process_flags() interprets the command line arguments and sets
+@@ -978,6 +1034,7 @@
+ 			{"no-user-group", no_argument, NULL, 'N'},
+ 			{"non-unique", no_argument, NULL, 'o'},
+ 			{"password", required_argument, NULL, 'p'},
++			{"root", required_argument, NULL, 'R'},
+ 			{"system", no_argument, NULL, 'r'},
+ 			{"shell", required_argument, NULL, 's'},
+ #ifdef WITH_SELINUX
+@@ -989,9 +1046,9 @@
+ 		};
+ 		while ((c = getopt_long (argc, argv,
+ #ifdef WITH_SELINUX
+-		                         "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:UZ:",
++		                         "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:UZ:",
+ #else
+-		                         "b:c:d:De:f:g:G:k:K:lmMNop:rs:u:U",
++		                         "b:c:d:De:f:g:G:k:K:lmMNop:R:rs:u:U",
+ #endif
+ 		                         long_options, NULL)) != -1) {
+ 			switch (c) {
+@@ -1156,6 +1213,9 @@
+ 				}
+ 				user_pass = optarg;
+ 				break;
++			case 'R':
++				/* no-op since we handled this in process_root_flag() earlier */
++				break;
+ 			case 'r':
+ 				rflg = true;
+ 				break;
+@@ -1748,8 +1808,16 @@
+ #ifdef WITH_SELINUX
+ 		selinux_file_context (user_home);
+ #endif
+-		/* XXX - create missing parent directories.  --marekm */
+-		if (mkdir (user_home, 0) != 0) {
++		/* shell out to invoke mkdir -p 
++		 * creating a subshell under pseudo's chroot() breaks the jail
++		 * (bug in pseudo), so make sure we include the full host path
++		 * to the sysroot when the --root option is in use.
++		 */
++		int sysroot_path_len = strlen(newroot);
++		int home_path_len = strlen(user_home);
++		char cmd[sysroot_path_len + home_path_len + 10];
++		sprintf(cmd, "mkdir -p %s%s", newroot, user_home);
++		if (system (cmd) != 0) {
+ 			fprintf (stderr,
+ 			         _("%s: cannot create directory %s\n"),
+ 			         Prog, user_home);
+@@ -1861,6 +1929,7 @@
+ 	 */
+ 	user_groups[0] = (char *) 0;
+ 
++	process_root_flag (argc, argv);
+ 
+ 	is_shadow_pwd = spw_file_present ();
+ #ifdef SHADOWGRP
+diff -urN shadow-4.1.4.3.orig//src/userdel.c shadow-4.1.4.3//src/userdel.c
+--- shadow-4.1.4.3.orig//src/userdel.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/userdel.c	2011-05-28 17:09:52.356013600 -0700
+@@ -79,6 +79,7 @@
+ static char *user_name;
+ static uid_t user_id;
+ static char *user_home;
++static const char *newroot = "";
+ 
+ static bool fflg = false;
+ static bool rflg = false;
+@@ -119,6 +120,7 @@
+ 	         "  -f, --force                   force removal of files,\n"
+ 	         "                                even if not owned by user\n"
+ 	         "  -h, --help                    display this help message and exit\n"
++	         "  -R, --root CHROOT_DIR         directory to chroot into\n"
+ 	         "  -r, --remove                  remove home directory and mail spool\n"
+ 	         "\n"), stderr);
+ 	exit (E_USAGE);
+@@ -768,12 +770,34 @@
+ 			{"remove", no_argument, NULL, 'r'},
+ 			{NULL, 0, NULL, '\0'}
+ 		};
+-		while ((c = getopt_long (argc, argv, "fhr",
++		while ((c = getopt_long (argc, argv, "fhR:r",
+ 		                         long_options, NULL)) != -1) {
+ 			switch (c) {
+ 			case 'f':	/* force remove even if not owned by user */
+ 				fflg = true;
+ 				break;
++			case 'R':
++				if ('/' != optarg[0]) {
++					fprintf (stderr,
++					         _("%s: invalid chroot path '%s'\n"),
++					         Prog, optarg);
++					exit (E_BAD_ARG);
++				}
++				newroot = optarg;
++
++				if (access (newroot, F_OK) != 0) {
++					fprintf(stderr,
++					        _("%s: chroot directory %s does not exist\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				if ( chroot(newroot) != 0 ) {
++					fprintf(stderr,
++					        _("%s: unable to chroot to directory %s\n"),
++					        Prog, newroot);
++					exit (E_BAD_ARG);
++				}
++				break;
+ 			case 'r':	/* remove home dir and mailbox */
+ 				rflg = true;
+ 				break;
+diff -urN shadow-4.1.4.3.orig//src/usermod.c shadow-4.1.4.3//src/usermod.c
+--- shadow-4.1.4.3.orig//src/usermod.c	2011-02-13 09:58:16.000000000 -0800
++++ shadow-4.1.4.3//src/usermod.c	2011-05-28 17:09:52.356013600 -0700
+@@ -110,6 +110,7 @@
+ static long user_newinactive;
+ static long sys_ngroups;
+ static char **user_groups;	/* NULL-terminated list */
++static const char *newroot = "";
+ 
+ static bool
+     aflg = false,		/* append to existing secondary group set */
+@@ -164,6 +165,7 @@
+ #endif
+ static void grp_update (void);
+ 
++static void process_root_flag (int, char **);
+ static void process_flags (int, char **);
+ static void close_files (void);
+ static void open_files (void);
+@@ -323,6 +325,7 @@
+ 	         "                                new location (use only with -d)\n"
+ 	         "  -o, --non-unique              allow using duplicate (non-unique) UID\n"
+ 	         "  -p, --password PASSWORD       use encrypted password for the new password\n"
++	         "  -R  --root CHROOT_DIR         directory to chroot into\n"
+ 	         "  -s, --shell SHELL             new login shell for the user account\n"
+ 	         "  -u, --uid UID                 new UID for the user account\n"
+ 	         "  -U, --unlock                  unlock the user account\n"
+@@ -802,6 +805,60 @@
+ }
+ 
+ /*
++ * process_root_flag - chroot if given the --root option
++ *
++ * We do this outside of process_flags() because
++ * the is_shadow_pwd boolean needs to be set before
++ * process_flags(), and if we do need to chroot() we
++ * must do so before is_shadow_pwd gets set.
++ */
++static void process_root_flag (int argc, char **argv)
++{
++	/*
++	 * Parse the command line options.
++	 */
++	int c;
++	static struct option long_options[] = {
++		{"root", required_argument, NULL, 'R'},
++		{NULL, 0, NULL, '\0'}
++	};
++	while ((c = getopt_long (argc, argv,
++#ifdef WITH_SELINUX
++                             "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:",
++#else
++	                         "ac:d:e:f:g:G:hl:Lmop:R:s:u:U",
++#endif
++	                         long_options, NULL)) != -1) {
++		switch (c) {
++		case 'R':
++			if (    (!VALID (optarg) ) 
++				|| (   ('/' != optarg[0]) ) ) {
++				fprintf (stderr,
++				         _("%s: invalid chroot path '%s'\n"),
++				         Prog, optarg);
++				exit (E_BAD_ARG);
++			}
++			newroot = optarg;
++
++			if (access (newroot, F_OK) != 0) {
++				fprintf(stderr,
++				        _("%s: chroot directory %s does not exist\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			if ( chroot(newroot) != 0 ) {
++				fprintf(stderr,
++				        _("%s: unable to chroot to directory %s\n"),
++				        Prog, newroot);
++				exit (E_BAD_ARG);
++			}
++			break;
++		/* no-op on everything else - they will be hanled by process_flags() */
++		}
++	}
++}
++
++/*
+  * process_flags - perform command line argument setting
+  *
+  *	process_flags() interprets the command line arguments and sets the
+@@ -895,6 +952,7 @@
+ 			{"move-home", no_argument, NULL, 'm'},
+ 			{"non-unique", no_argument, NULL, 'o'},
+ 			{"password", required_argument, NULL, 'p'},
++			{"root", required_argument, NULL, 'R'},
+ #ifdef WITH_SELINUX
+ 			{"selinux-user", required_argument, NULL, 'Z'},
+ #endif
+@@ -905,9 +963,9 @@
+ 		};
+ 		while ((c = getopt_long (argc, argv,
+ #ifdef WITH_SELINUX
+-			                 "ac:d:e:f:g:G:hl:Lmop:s:u:UZ:",
++			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:",
+ #else
+-			                 "ac:d:e:f:g:G:hl:Lmop:s:u:U",
++			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:U",
+ #endif
+ 			                 long_options, NULL)) != -1) {
+ 			switch (c) {
+@@ -999,6 +1057,9 @@
+ 				user_pass = optarg;
+ 				pflg = true;
+ 				break;
++			case 'R':
++				/* no-op since we handled this in process_root_flag() earlier */
++				break;
+ 			case 's':
+ 				if (!VALID (optarg)) {
+ 					fprintf (stderr,
+@@ -1715,6 +1776,8 @@
+ 
+ 	OPENLOG ("usermod");
+ 
++	process_root_flag (argc, argv);
++
+ 	is_shadow_pwd = spw_file_present ();
+ #ifdef SHADOWGRP
+ 	is_shadow_grp = sgr_file_present ();
diff --git a/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb b/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb
new file mode 100644
index 0000000..2f93e05
--- /dev/null
+++ b/meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb
@@ -0,0 +1,66 @@
+SUMMARY = "Tools to change and administer password and group data"
+DESCRIPTION = "Tools to change and administer password and group data"
+HOMEPAGE = "http://pkg-shadow.alioth.debian.org"
+BUGTRACKER = "https://alioth.debian.org/tracker/?group_id=30580"
+SECTION = "base utils"
+PRIORITY = "optional"
+LICENSE = "BSD | Artistic"
+LIC_FILES_CHKSUM = "file://COPYING;md5=08c553a87d4e51bbed50b20e0adcaede \
+                    file://src/passwd.c;firstline=8;endline=30;md5=2899a045e90511d0e043b85a7db7e2fe"
+
+PR = "r0"
+
+SRC_URI = "ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-${PV}.tar.bz2 \
+           file://shadow.automake-1.11.patch \
+           file://shadow-4.1.3-dots-in-usernames.patch \
+           file://shadow-4.1.4.2-env-reset-keep-locale.patch \
+           file://add_root_cmd_options.patch"
+
+SRC_URI[md5sum] = "b8608d8294ac88974f27b20f991c0e79"
+SRC_URI[sha256sum] = "633f5bb4ea0c88c55f3642c97f9d25cbef74f82e0b4cf8d54e7ad6f9f9caa778" 
+
+inherit autotools gettext native
+
+EXTRA_OECONF += "--without-audit \
+                 --without-libcrack \
+                 --without-libpam \
+                 --without-selinux"
+
+do_install_append() {
+	# Enable CREATE_HOME by default.
+	sed -i 's/#CREATE_HOME/CREATE_HOME/g' ${D}${sysconfdir}/login.defs
+
+	# As we are on an embedded system, ensure the users mailbox is in
+	# ~/ not /var/spool/mail by default, as who knows where or how big
+	# /var is. The system MDA will set this later anyway.
+	sed -i 's/MAIL_DIR/#MAIL_DIR/g' ${D}${sysconfdir}/login.defs
+	sed -i 's/#MAIL_FILE/MAIL_FILE/g' ${D}${sysconfdir}/login.defs
+
+	# Disable checking emails.
+	sed -i 's/MAIL_CHECK_ENAB/#MAIL_CHECK_ENAB/g' ${D}${sysconfdir}/login.defs
+
+	# Now we don't have a mail system. Disable mail creation for now.
+	sed -i 's:/bin/bash:/bin/sh:g' ${D}${sysconfdir}/default/useradd
+	sed -i '/^CREATE_MAIL_SPOOL/ s:^:#:' ${D}${sysconfdir}/default/useradd
+
+	install -d ${D}${sbindir} ${D}${base_sbindir} ${D}${base_bindir} 
+	for i in passwd chfn newgrp chsh ; do
+		mv ${D}${bindir}/$i ${D}${bindir}/$i.${PN}
+	done
+
+	mv ${D}${sbindir}/chpasswd ${D}${sbindir}/chpasswd.${PN}
+}
+
+pkg_postinst_${PN} () {
+	update-alternatives --install ${bindir}/passwd passwd passwd.${PN} 200
+	update-alternatives --install ${sbindir}/chpasswd chpasswd chpasswd.${PN} 200
+	update-alternatives --install ${bindir}/chfn chfn chfn.${PN} 200
+	update-alternatives --install ${bindir}/newgrp newgrp newgrp.${PN} 200
+	update-alternatives --install ${bindir}/chsh chsh chsh.${PN} 200
+}
+
+pkg_prerm_${PN} () {
+	for i in passwd chpasswd chfn newgrp chsh ; do
+		update-alternatives --remove $i $i.${PN}
+	done
+}
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
  2011-06-02 23:50 ` [PATCH 1/7] shadow: recipe and patch cleanup Scott Garman
  2011-06-02 23:50 ` [PATCH 2/7] shadow: add a -native recipe with customized utilities Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-09 20:50   ` Koen Kooi
  2011-06-02 23:50 ` [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions Scott Garman
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

The passwd, group, and login.defs files in the target sysroot will
be used when recipes create custom user and group permissions in
their packages.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
 .../recipes-core/base-passwd/base-passwd_3.5.22.bb |   27 ++-
 2 files changed, 411 insertions(+), 2 deletions(-)
 create mode 100644 meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs

diff --git a/meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs b/meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs
new file mode 100644
index 0000000..1d392ac
--- /dev/null
+++ b/meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs
@@ -0,0 +1,386 @@
+#
+# /etc/login.defs - Configuration control definitions for the shadow package.
+#
+#	$Id: login.defs 3038 2009-07-23 20:41:35Z nekral-guest $
+#
+
+#
+# Delay in seconds before being allowed another attempt after a login failure
+# Note: When PAM is used, some modules may enfore a minimal delay (e.g.
+#       pam_unix enforces a 2s delay)
+#
+FAIL_DELAY		3
+
+#
+# Enable logging and display of /var/log/faillog login failure info.
+#
+FAILLOG_ENAB		yes
+
+#
+# Enable display of unknown usernames when login failures are recorded.
+#
+LOG_UNKFAIL_ENAB	no
+
+#
+# Enable logging of successful logins
+#
+LOG_OK_LOGINS		no
+
+#
+# Enable logging and display of /var/log/lastlog login time info.
+#
+LASTLOG_ENAB		yes
+
+#
+# Enable checking and display of mailbox status upon login.
+#
+# Disable if the shell startup files already check for mail
+# ("mailx -e" or equivalent).
+#
+#MAIL_CHECK_ENAB		yes
+
+#
+# Enable additional checks upon password changes.
+#
+OBSCURE_CHECKS_ENAB	yes
+
+#
+# Enable checking of time restrictions specified in /etc/porttime.
+#
+PORTTIME_CHECKS_ENAB	yes
+
+#
+# Enable setting of ulimit, umask, and niceness from passwd gecos field.
+#
+QUOTAS_ENAB		yes
+
+#
+# Enable "syslog" logging of su activity - in addition to sulog file logging.
+# SYSLOG_SG_ENAB does the same for newgrp and sg.
+#
+SYSLOG_SU_ENAB		yes
+SYSLOG_SG_ENAB		yes
+
+#
+# If defined, either full pathname of a file containing device names or
+# a ":" delimited list of device names.  Root logins will be allowed only
+# upon these devices.
+#
+CONSOLE		/etc/securetty
+#CONSOLE	console:tty01:tty02:tty03:tty04
+
+#
+# If defined, all su activity is logged to this file.
+#
+#SULOG_FILE	/var/log/sulog
+
+#
+# If defined, ":" delimited list of "message of the day" files to
+# be displayed upon login.
+#
+MOTD_FILE	/etc/motd
+#MOTD_FILE	/etc/motd:/usr/lib/news/news-motd
+
+#
+# If defined, this file will be output before each login prompt.
+#
+#ISSUE_FILE	/etc/issue
+
+#
+# If defined, file which maps tty line to TERM environment parameter.
+# Each line of the file is in a format something like "vt100  tty01".
+#
+#TTYTYPE_FILE	/etc/ttytype
+
+#
+# If defined, login failures will be logged here in a utmp format.
+# last, when invoked as lastb, will read /var/log/btmp, so...
+#
+FTMP_FILE	/var/log/btmp
+
+#
+# If defined, name of file whose presence which will inhibit non-root
+# logins.  The contents of this file should be a message indicating
+# why logins are inhibited.
+#
+NOLOGINS_FILE	/etc/nologin
+
+#
+# If defined, the command name to display when running "su -".  For
+# example, if this is defined as "su" then a "ps" will display the
+# command is "-su".  If not defined, then "ps" would display the
+# name of the shell actually being run, e.g. something like "-sh".
+#
+SU_NAME		su
+
+#
+# *REQUIRED*
+#   Directory where mailboxes reside, _or_ name of file, relative to the
+#   home directory.  If you _do_ define both, #MAIL_DIR takes precedence.
+#
+#MAIL_DIR	/var/spool/mail
+MAIL_FILE	.mail
+
+#
+# If defined, file which inhibits all the usual chatter during the login
+# sequence.  If a full pathname, then hushed mode will be enabled if the
+# user's name or shell are found in the file.  If not a full pathname, then
+# hushed mode will be enabled if the file exists in the user's home directory.
+#
+HUSHLOGIN_FILE	.hushlogin
+#HUSHLOGIN_FILE	/etc/hushlogins
+
+#
+# If defined, either a TZ environment parameter spec or the
+# fully-rooted pathname of a file containing such a spec.
+#
+#ENV_TZ		TZ=CST6CDT
+#ENV_TZ		/etc/tzname
+
+#
+# If defined, an HZ environment parameter spec.
+#
+# for Linux/x86
+ENV_HZ		HZ=100
+# For Linux/Alpha...
+#ENV_HZ		HZ=1024
+
+#
+# *REQUIRED*  The default PATH settings, for superuser and normal users.
+#
+# (they are minimal, add the rest in the shell startup files)
+ENV_SUPATH	PATH=/sbin:/bin:/usr/sbin:/usr/bin
+ENV_PATH	PATH=/bin:/usr/bin
+
+#
+# Terminal permissions
+#
+#	TTYGROUP	Login tty will be assigned this group ownership.
+#	TTYPERM		Login tty will be set to this permission.
+#
+# If you have a "write" program which is "setgid" to a special group
+# which owns the terminals, define TTYGROUP to the group number and
+# TTYPERM to 0620.  Otherwise leave TTYGROUP commented out and assign
+# TTYPERM to either 622 or 600.
+#
+TTYGROUP	tty
+TTYPERM		0600
+
+#
+# Login configuration initializations:
+#
+#	ERASECHAR	Terminal ERASE character ('\010' = backspace).
+#	KILLCHAR	Terminal KILL character ('\025' = CTRL/U).
+#	ULIMIT		Default "ulimit" value.
+#
+# The ERASECHAR and KILLCHAR are used only on System V machines.
+# The ULIMIT is used only if the system supports it.
+# (now it works with setrlimit too; ulimit is in 512-byte units)
+#
+# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
+#
+ERASECHAR	0177
+KILLCHAR	025
+#ULIMIT		2097152
+
+# Default initial "umask" value for non-PAM enabled systems.
+# UMASK is also used by useradd and newusers to set the mode of new home
+# directories.
+# 022 is the default value, but 027, or even 077, could be considered
+# better for privacy. There is no One True Answer here: each sysadmin
+# must make up her mind.
+UMASK		022
+
+#
+# Password aging controls:
+#
+#	PASS_MAX_DAYS	Maximum number of days a password may be used.
+#	PASS_MIN_DAYS	Minimum number of days allowed between password changes.
+#	PASS_MIN_LEN	Minimum acceptable password length.
+#	PASS_WARN_AGE	Number of days warning given before a password expires.
+#
+PASS_MAX_DAYS	99999
+PASS_MIN_DAYS	0
+PASS_MIN_LEN	5
+PASS_WARN_AGE	7
+
+#
+# If "yes", the user must be listed as a member of the first gid 0 group
+# in /etc/group (called "root" on most Linux systems) to be able to "su"
+# to uid 0 accounts.  If the group doesn't exist or is empty, no one
+# will be able to "su" to uid 0.
+#
+SU_WHEEL_ONLY	no
+
+#
+# If compiled with cracklib support, where are the dictionaries
+#
+CRACKLIB_DICTPATH	/var/cache/cracklib/cracklib_dict
+
+#
+# Min/max values for automatic uid selection in useradd
+#
+UID_MIN			 1000
+UID_MAX			60000
+# System accounts
+SYS_UID_MIN		  101
+SYS_UID_MAX		  999
+
+#
+# Min/max values for automatic gid selection in groupadd
+#
+GID_MIN			 1000
+GID_MAX			60000
+# System accounts
+SYS_GID_MIN		  101
+SYS_GID_MAX		  999
+
+#
+# Max number of login retries if password is bad
+#
+LOGIN_RETRIES		5
+
+#
+# Max time in seconds for login
+#
+LOGIN_TIMEOUT		60
+
+#
+# Maximum number of attempts to change password if rejected (too easy)
+#
+PASS_CHANGE_TRIES	5
+
+#
+# Warn about weak passwords (but still allow them) if you are root.
+#
+PASS_ALWAYS_WARN	yes
+
+#
+# Number of significant characters in the password for crypt().
+# Default is 8, don't change unless your crypt() is better.
+# Ignored if MD5_CRYPT_ENAB set to "yes".
+#
+#PASS_MAX_LEN		8
+
+#
+# Require password before chfn/chsh can make any changes.
+#
+CHFN_AUTH		yes
+
+#
+# Which fields may be changed by regular users using chfn - use
+# any combination of letters "frwh" (full name, room number, work
+# phone, home phone).  If not defined, no changes are allowed.
+# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
+# 
+CHFN_RESTRICT		rwh
+
+#
+# Password prompt (%s will be replaced by user name).
+#
+# XXX - it doesn't work correctly yet, for now leave it commented out
+# to use the default which is just "Password: ".
+#LOGIN_STRING		"%s's Password: "
+
+#
+# Only works if compiled with MD5_CRYPT defined:
+# If set to "yes", new passwords will be encrypted using the MD5-based
+# algorithm compatible with the one used by recent releases of FreeBSD.
+# It supports passwords of unlimited length and longer salt strings.
+# Set to "no" if you need to copy encrypted passwords to other systems
+# which don't understand the new algorithm.  Default is "no".
+#
+# Note: If you use PAM, it is recommended to use a value consistent with
+# the PAM modules configuration.
+#
+# This variable is deprecated. You should use ENCRYPT_METHOD.
+#
+#MD5_CRYPT_ENAB	no
+
+#
+# Only works if compiled with ENCRYPTMETHOD_SELECT defined:
+# If set to MD5 , MD5-based algorithm will be used for encrypting password
+# If set to SHA256, SHA256-based algorithm will be used for encrypting password
+# If set to SHA512, SHA512-based algorithm will be used for encrypting password
+# If set to DES, DES-based algorithm will be used for encrypting password (default)
+# Overrides the MD5_CRYPT_ENAB option
+#
+# Note: If you use PAM, it is recommended to use a value consistent with
+# the PAM modules configuration.
+#
+#ENCRYPT_METHOD DES
+
+#
+# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512.
+#
+# Define the number of SHA rounds.
+# With a lot of rounds, it is more difficult to brute forcing the password.
+# But note also that it more CPU resources will be needed to authenticate
+# users.
+#
+# If not specified, the libc will choose the default number of rounds (5000).
+# The values must be inside the 1000-999999999 range.
+# If only one of the MIN or MAX values is set, then this value will be used.
+# If MIN > MAX, the highest value will be used.
+#
+# SHA_CRYPT_MIN_ROUNDS 5000
+# SHA_CRYPT_MAX_ROUNDS 5000
+
+#
+# List of groups to add to the user's supplementary group set
+# when logging in on the console (as determined by the CONSOLE
+# setting).  Default is none.
+#
+# Use with caution - it is possible for users to gain permanent
+# access to these groups, even when not logged in on the console.
+# How to do it is left as an exercise for the reader...
+#
+#CONSOLE_GROUPS		floppy:audio:cdrom
+
+#
+# Should login be allowed if we can't cd to the home directory?
+# Default in no.
+#
+DEFAULT_HOME	yes
+
+#
+# If this file exists and is readable, login environment will be
+# read from it.  Every line should be in the form name=value.
+#
+ENVIRON_FILE	/etc/environment
+
+#
+# If defined, this command is run when removing a user.
+# It should remove any at/cron/print jobs etc. owned by
+# the user to be removed (passed as the first argument).
+#
+#USERDEL_CMD	/usr/sbin/userdel_local
+
+#
+# Enable setting of the umask group bits to be the same as owner bits
+# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
+# the same as gid, and username is the same as the primary group name.
+#
+# This also enables userdel to remove user groups if no members exist.
+#
+USERGROUPS_ENAB yes
+
+#
+# If set to a non-nul number, the shadow utilities will make sure that
+# groups never have more than this number of users on one line.
+# This permit to support split groups (groups split into multiple lines,
+# with the same group ID, to avoid limitation of the line length in the
+# group file).
+#
+# 0 is the default value and disables this feature.
+#
+#MAX_MEMBERS_PER_GROUP	0
+
+#
+# If useradd should create home directories for users by default (non
+# system users only)
+# This option is overridden with the -M or -m flags on the useradd command
+# line.
+#
+CREATE_HOME     yes
+
diff --git a/meta/recipes-core/base-passwd/base-passwd_3.5.22.bb b/meta/recipes-core/base-passwd/base-passwd_3.5.22.bb
index 6f768ca..3315c68 100644
--- a/meta/recipes-core/base-passwd/base-passwd_3.5.22.bb
+++ b/meta/recipes-core/base-passwd/base-passwd_3.5.22.bb
@@ -1,13 +1,14 @@
 SUMMARY = "Base system master password/group files."
 DESCRIPTION = "The master copies of the user database files (/etc/passwd and /etc/group).  The update-passwd tool is also provided to keep the system databases synchronized with these master files."
 SECTION = "base"
-PR = "r1"
+PR = "r2"
 LICENSE = "GPLv2+"
 LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a"
 
 SRC_URI = "${DEBIAN_MIRROR}/main/b/base-passwd/base-passwd_${PV}.tar.gz \
            file://nobash.patch \
-           file://root-home.patch"
+           file://root-home.patch \
+           file://login.defs"
 
 SRC_URI[md5sum] = "47f22ab6b572d0133409ff6ad1fab402"
 SRC_URI[sha256sum] = "d34acb35a9f9f221e7e4f642b9ef4b22083dd77bb2fc7216756f445316d842fc"
@@ -16,6 +17,8 @@ S = "${WORKDIR}/base-passwd"
 
 inherit autotools
 
+SSTATEPOSTINSTFUNCS += "base_passwd_sstate_postinst"
+
 do_install () {
 	install -d -m 755 ${D}${sbindir}
 	install -p -m 755 update-passwd ${D}${sbindir}/
@@ -27,6 +30,7 @@ do_install () {
 	install -d -m 755 ${D}${datadir}/base-passwd
 	install -p -m 644 passwd.master ${D}${datadir}/base-passwd/
 	install -p -m 644 group.master ${D}${datadir}/base-passwd/
+	install -p -m 644 ${S}/../login.defs ${D}${datadir}/base-passwd/login.defs
 
 	install -d -m 755 ${D}${docdir}/${PN}
 	install -p -m 644 debian/changelog ${D}${docdir}/${PN}/
@@ -45,5 +49,24 @@ pkg_postinst_${PN} () {
 	if [ ! -e $D${sysconfdir}/group ] ; then
 		cp $D${datadir}/base-passwd/group.master $D${sysconfdir}/group
 	fi
+
+	if [ ! -e $D{sysconfdir}/login.defs ] ; then
+		cp $D${datadir}/base-passwd/login.defs $D${sysconfdir}/login.defs
+	fi
 	exit 0
 }
+
+base_passwd_sstate_postinst() {
+	if [ "${BB_CURRENTTASK}" = "populate_sysroot" -o "${BB_CURRENTTASK}" = "populate_sysroot_setscene" ]
+	then
+		# Staging does not copy ${sysconfdir} files into the
+		# target sysroot, so we need to do so manually. We
+		# put these files in the target sysroot so they can
+		# be used by recipes which use custom user/group
+		# permissions.
+		install -d -m 755 ${STAGING_DIR_TARGET}${sysconfdir}
+		install -p -m 644 ${STAGING_DIR_TARGET}${datadir}/base-passwd/passwd.master ${STAGING_DIR_TARGET}${sysconfdir}/passwd
+		install -p -m 644 ${STAGING_DIR_TARGET}${datadir}/base-passwd/group.master ${STAGING_DIR_TARGET}${sysconfdir}/group
+		install -p -m 644 ${STAGING_DIR_TARGET}${datadir}/base-passwd/login.defs ${STAGING_DIR_TARGET}/${sysconfdir}/login.defs
+	fi
+}
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
                   ` (2 preceding siblings ...)
  2011-06-02 23:50 ` [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-28 13:04   ` Richard Purdie
  2011-06-02 23:50 ` [PATCH 5/7] useradd-example: example recipe for using inherit useradd Scott Garman
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

This class is to be used by recipes that need to set up specific
user/group accounts and set custom file/directory permissions.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 meta/classes/useradd.bbclass

diff --git a/meta/classes/useradd.bbclass b/meta/classes/useradd.bbclass
new file mode 100644
index 0000000..3f07e5e
--- /dev/null
+++ b/meta/classes/useradd.bbclass
@@ -0,0 +1,163 @@
+USERADDPN ?= "${PN}"
+
+# base-passwd-cross provides the default passwd and group files in the
+# target sysroot, and shadow-native provides the utilities needed to
+# add and modify user and group accounts
+DEPENDS_append = " base-passwd shadow-native"
+RDEPENDS_${USERADDPN}_append = " base-passwd shadow"
+
+PSEUDO="${STAGING_DIR_NATIVE}/usr/bin/pseudo"
+export PSEUDO
+PSEUDO_LOCALSTATEDIR="${STAGING_DIR_TARGET}/var/pseudo"
+export PSEUDO_LOCALSTATEDIR
+PSEUDO_PASSWD = "${STAGING_DIR_TARGET}"
+export PSEUDO_PASSWD
+
+useradd_preinst () {
+OPT=""
+SYSROOT=""
+
+if test "x$D" != "x"; then
+	# Installing into a sysroot
+	SYSROOT="${STAGING_DIR_TARGET}"
+	OPT="--root ${STAGING_DIR_TARGET}"
+
+	# Add groups and users defined for all recipe packages
+	GROUPADD_PARAM="${@get_all_cmd_params(d, 'group')}"
+	USERADD_PARAM="${@get_all_cmd_params(d, 'user')}"
+else
+	# Installing onto a target
+	PSEUDO=""
+
+	# Add groups and users defined only for this package
+	GROUPADD_PARAM="${GROUPADD_PARAM}"
+	USERADD_PARAM="${USERADD_PARAM}"
+fi
+
+# Perform group additions first, since user additions may depend
+# on these groups existing
+if test "x$GROUPADD_PARAM" != "x"; then
+	echo "Running groupadd commands..."
+	# Invoke multiple instances of groupadd for parameter lists
+	# separated by ';'
+	opts=`echo "$GROUPADD_PARAM" | cut -d ';' -f 1`
+	remaining=`echo "$GROUPADD_PARAM" | cut -d ';' -f 2-`
+	while test "x$opts" != "x"; do
+		eval $PSEUDO groupadd -f $OPT $opts
+
+		if test "x$opts" = "x$remaining"; then
+			break
+		fi
+		opts=`echo "$remaining" | cut -d ';' -f 1`
+		remaining=`echo "$remaining" | cut -d ';' -f 2-`
+	done
+fi 
+
+if test "x$USERADD_PARAM" != "x"; then
+	echo "Running useradd commands..."
+	# Invoke multiple instances of useradd for parameter lists
+	# separated by ';'
+	opts=`echo "$USERADD_PARAM" | cut -d ';' -f 1`
+	remaining=`echo "$USERADD_PARAM" | cut -d ';' -f 2-`
+	while test "x$opts" != "x"; do
+		# useradd does not have a -f option, so we have to check if the
+		# username already exists manually
+		username=`echo "$opts" | awk '{ print $NF }'`
+		user_exists=`grep "^$username:" $SYSROOT/etc/passwd || true`
+		if test "x$user_exists" = "x"; then
+			eval $PSEUDO useradd $OPT $opts
+		else
+			echo "Note: username $username already exists, not re-creating it"
+		fi
+
+		if test "x$opts" = "x$remaining"; then
+			break
+		fi
+		opts=`echo "$remaining" | cut -d ';' -f 1`
+		remaining=`echo "$remaining" | cut -d ';' -f 2-`
+	done
+fi
+}
+
+useradd_sysroot () {
+	# Explicitly set $D since it isn't set to anything
+	# before do_install
+	D=${D}
+	useradd_preinst
+}
+
+useradd_sysroot_sstate () {
+	if [ "${BB_CURRENTTASK}" = "populate_sysroot_setscene" ]
+	then
+		useradd_sysroot
+	fi
+}
+
+do_install[prefuncs] += "useradd_sysroot"
+SSTATEPOSTINSTFUNCS += "useradd_sysroot_sstate"
+
+# Recipe parse-time sanity checks
+def update_useradd_after_parse(d):
+	if bb.data.getVar('USERADD_PACKAGES', d) == None:
+		if bb.data.getVar('USERADD_PARAM', d) == None and bb.data.getVar('GROUPADD_PARAM', d) == None:
+			raise bb.build.FuncFailed, "%s inherits useradd but doesn't set USERADD_PARAM or GROUPADD_PARAM" % bb.data.getVar('FILE', d)
+
+python __anonymous() {
+	update_useradd_after_parse(d)
+}
+
+# Return a single [GROUP|USER]ADD_PARAM formatted string which includes the
+# [group|user]add parameters for all packages in this recipe
+def get_all_cmd_params(d, cmd_type):
+	import string
+	
+	localdata = bb.data.createCopy(d)
+	param_type = cmd_type.upper() + "ADD_PARAM_%s"
+	params = []
+
+	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)
+	if pkgs == None:
+		pkgs = bb.data.getVar('USERADDPN', d, 1)
+		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
+		if not pkgs in packages and packages != []:
+			pkgs = packages[0]
+
+	for pkg in pkgs.split():
+		param = bb.data.getVar(param_type % pkg, localdata, 1)
+		params.append(param)
+
+	return string.join(params, "; ")
+
+# Adds the preinst script into generated packages
+fakeroot python populate_packages_prepend () {
+	def update_useradd_package(pkg):
+		bb.debug(1, 'adding user/group calls to preinst for %s' % pkg)
+		localdata = bb.data.createCopy(d)
+		overrides = bb.data.getVar("OVERRIDES", localdata, 1)
+		bb.data.setVar("OVERRIDES", "%s:%s" % (pkg, overrides), localdata)
+		bb.data.update_data(localdata)
+
+		"""
+		useradd preinst is appended here because pkg_preinst may be
+		required to execute on the target. Not doing so may cause
+		useradd preinst to be invoked twice, causing unwanted warnings.
+		"""
+		preinst = bb.data.getVar('pkg_preinst', localdata, 1)
+		if not preinst:
+			preinst = '#!/bin/sh\n'
+		preinst += bb.data.getVar('useradd_preinst', localdata, 1)
+		bb.data.setVar('pkg_preinst_%s' % pkg, preinst, d)
+
+	# We add the user/group calls to all packages to allow any package
+	# to contain files owned by the users/groups defined in the recipe.
+	# The user/group addition code is careful not to create duplicate
+	# entries, so this is safe.
+	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)
+	if pkgs == None:
+		pkgs = bb.data.getVar('USERADDPN', d, 1)
+		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
+		if not pkgs in packages and packages != []:
+			pkgs = packages[0]
+	for pkg in pkgs.split():
+		update_useradd_package(pkg)
+}
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/7] useradd-example: example recipe for using inherit useradd
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
                   ` (3 preceding siblings ...)
  2011-06-02 23:50 ` [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-02 23:50 ` [PATCH 6/7] bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV Scott Garman
  2011-06-02 23:50 ` [PATCH 7/7] package_rpm.bbclass: make RPM use on-disk permissions Scott Garman
  6 siblings, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

An example recipe for demonstrating/documenting how user and
group manipulation is done with 'inherit useradd'

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 .../recipes-skeleton/useradd/useradd-example.bb    |   72 ++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example.bb
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file1
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file2
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file3
 create mode 100644 meta-skeleton/recipes-skeleton/useradd/useradd-example/file4

diff --git a/meta-skeleton/recipes-skeleton/useradd/useradd-example.bb b/meta-skeleton/recipes-skeleton/useradd/useradd-example.bb
new file mode 100644
index 0000000..6c6edf0
--- /dev/null
+++ b/meta-skeleton/recipes-skeleton/useradd/useradd-example.bb
@@ -0,0 +1,72 @@
+SUMMARY = "Example recipe for using inherit useradd"
+DESCRIPTION = "This recipe serves as an example for using features from useradd.bbclass"
+SECTION = "examples"
+PR = "r0"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3b58 \
+                    file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+SRC_URI = "file://file1 \
+           file://file2 \
+           file://file3 \
+           file://file4"
+
+S = "${WORKDIR}"
+
+PACKAGES =+ "${PN}-user3"
+
+inherit useradd
+
+# Specify which package(s) should include the user/group code.
+# Make sure that any packages which install files owned by custom
+# users/groups are included here. The code which adds users and
+# groups is idempotent.
+USERADD_PACKAGES = "${PN} ${PN}-user3"
+
+# You *must* set USERADD_PARAM and/or GROUPADD_PARAM when
+# you inherit useradd.
+
+# USERADD_PARAM specifies command line options to pass to the
+# useradd command. Multiple users can be created by separating
+# the commands with a semicolon. Here we'll create two users,
+# user1 and user2:
+USERADD_PARAM_${PN} = "-u 1200 -d /home/user1 -r -s /bin/bash user1; -u 1201 -d /home/user2 -r -s /bin/bash user2"
+
+# user3 will be managed in the useradd-example-user3 pacakge:
+USERADD_PARAM_${PN}-user3 = "-u 1202 -d /home/user3 -r -s /bin/bash user3"
+
+# GROUPADD_PARAM works the same way, which you set to the options
+# you'd normally pass to the groupadd command. This will create
+# groups group1 and group2:
+GROUPADD_PARAM_${PN} = "-g 880 group1; -g 890 group2"
+
+# Likewise, we'll manage group3 in the useradd-example-user3 package:
+GROUPADD_PARAM_${PN}-user3 = "-g 900 group3"
+
+do_install () {
+	install -d -m 755 ${D}/usr/share/user1
+	install -d -m 755 ${D}/usr/share/user2
+	install -d -m 755 ${D}/usr/share/user3
+
+	install -p -m 644 file1 ${D}/usr/share/user1/
+	install -p -m 644 file2 ${D}/usr/share/user1/
+
+	install -p -m 644 file2 ${D}/usr/share/user2/
+	install -p -m 644 file3 ${D}/usr/share/user2/
+
+	install -p -m 644 file3 ${D}/usr/share/user3/
+	install -p -m 644 file4 ${D}/usr/share/user3/
+
+	# The new users and groups are created before the do_install
+	# step, so you are now free to make use of them:
+	chown -R user1 ${D}/usr/share/user1
+	chown -R user2 ${D}/usr/share/user2
+	chown -R user3 ${D}/usr/share/user3
+
+	chgrp -R group1 ${D}/usr/share/user1
+	chgrp -R group2 ${D}/usr/share/user2
+	chgrp -R group3 ${D}/usr/share/user3
+}
+
+FILES_${PN} = "/usr/share/user1/* /usr/share/user2/*"
+FILES_${PN}-user3 = "/usr/share/user3/*"
diff --git a/meta-skeleton/recipes-skeleton/useradd/useradd-example/file1 b/meta-skeleton/recipes-skeleton/useradd/useradd-example/file1
new file mode 100644
index 0000000..e69de29
diff --git a/meta-skeleton/recipes-skeleton/useradd/useradd-example/file2 b/meta-skeleton/recipes-skeleton/useradd/useradd-example/file2
new file mode 100644
index 0000000..e69de29
diff --git a/meta-skeleton/recipes-skeleton/useradd/useradd-example/file3 b/meta-skeleton/recipes-skeleton/useradd/useradd-example/file3
new file mode 100644
index 0000000..e69de29
diff --git a/meta-skeleton/recipes-skeleton/useradd/useradd-example/file4 b/meta-skeleton/recipes-skeleton/useradd/useradd-example/file4
new file mode 100644
index 0000000..e69de29
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/7] bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
                   ` (4 preceding siblings ...)
  2011-06-02 23:50 ` [PATCH 5/7] useradd-example: example recipe for using inherit useradd Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  2011-06-02 23:50 ` [PATCH 7/7] package_rpm.bbclass: make RPM use on-disk permissions Scott Garman
  6 siblings, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

PSEUDO_PASSWD needs to point to the directory where passwd and group
files are kept. This will allow pseudo to use those users and groups
to change file ownership.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 meta/conf/bitbake.conf |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf
index d307385..6f16a65 100644
--- a/meta/conf/bitbake.conf
+++ b/meta/conf/bitbake.conf
@@ -535,7 +535,7 @@ SRC_URI = "file://${FILE}"
 
 # Use pseudo as the fakeroot implementation
 PSEUDO_LOCALSTATEDIR ?= "${WORKDIR}/pseudo/"
-FAKEROOTENV = "PSEUDO_PREFIX=${STAGING_DIR_NATIVE}${prefix_native} PSEUDO_LOCALSTATEDIR=${PSEUDO_LOCALSTATEDIR} PSEUDO_NOSYMLINKEXP=1 PSEUDO_DISABLED=0"
+FAKEROOTENV = "PSEUDO_PREFIX=${STAGING_DIR_NATIVE}${prefix_native} PSEUDO_LOCALSTATEDIR=${PSEUDO_LOCALSTATEDIR} PSEUDO_PASSWD=${STAGING_DIR_TARGET}/etc PSEUDO_NOSYMLINKEXP=1 PSEUDO_DISABLED=0"
 FAKEROOTDIRS = "${PSEUDO_LOCALSTATEDIR}"
 PREFERRED_PROVIDER_virtual/fakeroot-native ?= "pseudo-native"
 
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/7] package_rpm.bbclass: make RPM use on-disk permissions
  2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
                   ` (5 preceding siblings ...)
  2011-06-02 23:50 ` [PATCH 6/7] bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV Scott Garman
@ 2011-06-02 23:50 ` Scott Garman
  6 siblings, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-02 23:50 UTC (permalink / raw)
  To: openembedded-core

Instruct RPM to use the on-disk permissions, owners, groups,
and directory permissions, instead of defaulting to root:root

Code changes suggested by Mark Hatle.

Signed-off-by: Scott Garman <scott.a.garman@intel.com>
---
 meta/classes/package_rpm.bbclass |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/meta/classes/package_rpm.bbclass b/meta/classes/package_rpm.bbclass
index 1d8c686..d124c01 100644
--- a/meta/classes/package_rpm.bbclass
+++ b/meta/classes/package_rpm.bbclass
@@ -484,6 +484,7 @@ python write_specfile () {
 			else:
 				bb.note("Creating RPM package for %s" % splitname)
 				spec_files_top.append('%files')
+				spec_files_top.append('%defattr(-,-,-,-)')
 				if file_list:
 					spec_files_top.extend(file_list)
 				spec_files_top.append('')
@@ -570,6 +571,7 @@ python write_specfile () {
 		else:
 			bb.note("Creating RPM package for %s" % splitname)
 			spec_files_bottom.append('%%files -n %s' % splitname)
+			spec_files_bottom.append('%defattr(-,-,-,-)')
 			if file_list:
 				spec_files_bottom.extend(file_list)
 			spec_files_bottom.append('')
-- 
1.7.1




^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs
  2011-06-02 23:50 ` [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs Scott Garman
@ 2011-06-09 20:50   ` Koen Kooi
  2011-06-09 21:23     ` Scott Garman
  0 siblings, 1 reply; 18+ messages in thread
From: Koen Kooi @ 2011-06-09 20:50 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer


Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:

> The passwd, group, and login.defs files in the target sysroot will
> be used when recipes create custom user and group permissions in
> their packages.
> 
> Signed-off-by: Scott Garman <scott.a.garman@intel.com>
> ---
> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++

I'm now getting tons and tons of the following when using shadow:

[  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
[  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
[  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
[  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
[  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
[  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
[  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
[  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
[  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
[  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
[  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
[  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
[  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
[  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
[  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
[  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'


which seems to be related to the login.defs change.

regards,

Koen


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs
  2011-06-09 20:50   ` Koen Kooi
@ 2011-06-09 21:23     ` Scott Garman
  2011-06-09 21:25       ` Koen Kooi
  0 siblings, 1 reply; 18+ messages in thread
From: Scott Garman @ 2011-06-09 21:23 UTC (permalink / raw)
  To: openembedded-core

On 06/09/2011 01:50 PM, Koen Kooi wrote:
>
> Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:
>
>> The passwd, group, and login.defs files in the target sysroot will
>> be used when recipes create custom user and group permissions in
>> their packages.
>>
>> Signed-off-by: Scott Garman<scott.a.garman@intel.com>
>> ---
>> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
>
> I'm now getting tons and tons of the following when using shadow:
>
> [  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
> [  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
> [  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
> [  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
> [  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
> [  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
> [  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
> [  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
> [  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
> [  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
> [  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
> [  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
> [  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
> [  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
> [  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
> [  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'
>
>
> which seems to be related to the login.defs change.

What context is this happening in? Runtime, or during a buildstep?

Scott

-- 
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs
  2011-06-09 21:23     ` Scott Garman
@ 2011-06-09 21:25       ` Koen Kooi
  2011-06-09 21:29         ` Scott Garman
  2011-06-10 22:22         ` shadow errors related to login.defs Scott Garman
  0 siblings, 2 replies; 18+ messages in thread
From: Koen Kooi @ 2011-06-09 21:25 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer


Op 9 jun 2011, om 23:23 heeft Scott Garman het volgende geschreven:

> On 06/09/2011 01:50 PM, Koen Kooi wrote:
>> 
>> Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:
>> 
>>> The passwd, group, and login.defs files in the target sysroot will
>>> be used when recipes create custom user and group permissions in
>>> their packages.
>>> 
>>> Signed-off-by: Scott Garman<scott.a.garman@intel.com>
>>> ---
>>> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
>> 
>> I'm now getting tons and tons of the following when using shadow:
>> 
>> [  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
>> [  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
>> [  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
>> [  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
>> [  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
>> [  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
>> [  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
>> [  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
>> [  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
>> [  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
>> [  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
>> [  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
>> [  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
>> [  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
>> [  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
>> [  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'
>> 
>> 
>> which seems to be related to the login.defs change.
> 
> What context is this happening in? Runtime, or during a buildstep?

Runtime, during things like adduser and addgroup. I think I'm also seeing it during login, but I need to doublecheck.

regards,

Koen


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs
  2011-06-09 21:25       ` Koen Kooi
@ 2011-06-09 21:29         ` Scott Garman
  2011-06-10 22:22         ` shadow errors related to login.defs Scott Garman
  1 sibling, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-09 21:29 UTC (permalink / raw)
  To: openembedded-core

On 06/09/2011 02:25 PM, Koen Kooi wrote:
>
> Op 9 jun 2011, om 23:23 heeft Scott Garman het volgende geschreven:
>
>> On 06/09/2011 01:50 PM, Koen Kooi wrote:
>>>
>>> Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:
>>>
>>>> The passwd, group, and login.defs files in the target sysroot will
>>>> be used when recipes create custom user and group permissions in
>>>> their packages.
>>>>
>>>> Signed-off-by: Scott Garman<scott.a.garman@intel.com>
>>>> ---
>>>> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
>>>
>>> I'm now getting tons and tons of the following when using shadow:
>>>
>>> [  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
>>> [  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
>>> [  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
>>> [  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
>>> [  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
>>> [  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
>>> [  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
>>> [  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
>>> [  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
>>> [  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
>>> [  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
>>> [  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
>>> [  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
>>> [  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
>>> [  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
>>> [  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'
>>>
>>>
>>> which seems to be related to the login.defs change.
>>
>> What context is this happening in? Runtime, or during a buildstep?
>
> Runtime, during things like adduser and addgroup. I think I'm also seeing it during login, but I need to doublecheck.

Ok, thanks for confirming. I will look into this.

Scott

-- 
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center



^ permalink raw reply	[flat|nested] 18+ messages in thread

* shadow errors related to login.defs
  2011-06-09 21:25       ` Koen Kooi
  2011-06-09 21:29         ` Scott Garman
@ 2011-06-10 22:22         ` Scott Garman
  2011-06-10 22:38           ` Koen Kooi
  1 sibling, 1 reply; 18+ messages in thread
From: Scott Garman @ 2011-06-10 22:22 UTC (permalink / raw)
  To: openembedded-core

On 06/09/2011 02:25 PM, Koen Kooi wrote:
>
> Op 9 jun 2011, om 23:23 heeft Scott Garman het volgende geschreven:
>
>> On 06/09/2011 01:50 PM, Koen Kooi wrote:
>>>
>>> Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:
>>>
>>>> The passwd, group, and login.defs files in the target sysroot will
>>>> be used when recipes create custom user and group permissions in
>>>> their packages.
>>>>
>>>> Signed-off-by: Scott Garman<scott.a.garman@intel.com>
>>>> ---
>>>> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
>>>
>>> I'm now getting tons and tons of the following when using shadow:
>>>
>>> [  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
>>> [  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
>>> [  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
>>> [  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
>>> [  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
>>> [  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
>>> [  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
>>> [  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
>>> [  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
>>> [  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
>>> [  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
>>> [  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
>>> [  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
>>> [  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
>>> [  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
>>> [  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'
>>>
>>>
>>> which seems to be related to the login.defs change.
>>
>> What context is this happening in? Runtime, or during a buildstep?
>
> Runtime, during things like adduser and addgroup. I think I'm also seeing it during login, but I need to doublecheck.

Hmmm...I'm not running into these errors at all. I'm testing it against 
core-image-sato, which does not come with shadow by default. So I copy 
over and install the shadow RPM and start creating users and groups, and 
I'm not getting any errors back. I've also tried running grpconv, with 
the same results.

I need more information about your setup to duplicate the error. Which 
image, how was it built, what customizations, etc.

Scott

-- 
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: shadow errors related to login.defs
  2011-06-10 22:22         ` shadow errors related to login.defs Scott Garman
@ 2011-06-10 22:38           ` Koen Kooi
  0 siblings, 0 replies; 18+ messages in thread
From: Koen Kooi @ 2011-06-10 22:38 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer


Op 11 jun 2011, om 00:22 heeft Scott Garman het volgende geschreven:

> On 06/09/2011 02:25 PM, Koen Kooi wrote:
>> 
>> Op 9 jun 2011, om 23:23 heeft Scott Garman het volgende geschreven:
>> 
>>> On 06/09/2011 01:50 PM, Koen Kooi wrote:
>>>> 
>>>> Op 3 jun 2011, om 01:50 heeft Scott Garman het volgende geschreven:
>>>> 
>>>>> The passwd, group, and login.defs files in the target sysroot will
>>>>> be used when recipes create custom user and group permissions in
>>>>> their packages.
>>>>> 
>>>>> Signed-off-by: Scott Garman<scott.a.garman@intel.com>
>>>>> ---
>>>>> .../base-passwd/base-passwd-3.5.22/login.defs      |  386 ++++++++++++++++++++
>>>> 
>>>> I'm now getting tons and tons of the following when using shadow:
>>>> 
>>>> [  900.349395] grpconv[682]: unknown configuration item `FAILLOG_ENAB'
>>>> [  900.357391] grpconv[682]: unknown configuration item `LASTLOG_ENAB'
>>>> [  900.364196] grpconv[682]: unknown configuration item `OBSCURE_CHECKS_ENAB'
>>>> [  900.371734] grpconv[682]: unknown configuration item `PORTTIME_CHECKS_ENAB'
>>>> [  900.381042] grpconv[682]: unknown configuration item `QUOTAS_ENAB'
>>>> [  900.387878] grpconv[682]: unknown configuration item `MOTD_FILE'
>>>> [  900.394256] grpconv[682]: unknown configuration item `FTMP_FILE'
>>>> [  900.400634] grpconv[682]: unknown configuration item `NOLOGINS_FILE'
>>>> [  900.407348] grpconv[682]: unknown configuration item `ENV_HZ'
>>>> [  900.413452] grpconv[682]: unknown configuration item `PASS_MIN_LEN'
>>>> [  900.420104] grpconv[682]: unknown configuration item `SU_WHEEL_ONLY'
>>>> [  900.426849] grpconv[682]: unknown configuration item `CRACKLIB_DICTPATH'
>>>> [  900.433929] grpconv[682]: unknown configuration item `PASS_CHANGE_TRIES'
>>>> [  900.441040] grpconv[682]: unknown configuration item `PASS_ALWAYS_WARN'
>>>> [  900.448028] grpconv[682]: unknown configuration item `CHFN_AUTH'
>>>> [  900.454376] grpconv[682]: unknown configuration item `ENVIRON_FILE'
>>>> 
>>>> 
>>>> which seems to be related to the login.defs change.
>>> 
>>> What context is this happening in? Runtime, or during a buildstep?
>> 
>> Runtime, during things like adduser and addgroup. I think I'm also seeing it during login, but I need to doublecheck.
> 
> Hmmm...I'm not running into these errors at all. I'm testing it against core-image-sato, which does not come with shadow by default. So I copy over and install the shadow RPM and start creating users and groups, and I'm not getting any errors back. I've also tried running grpconv, with the same results.
> 
> I need more information about your setup to duplicate the error. Which image, how was it built, what customizations, etc.

I get them with any image that has shadow installed, the easiest way to reproduce would be to build systemd-image with an angstrom setup


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions
  2011-06-02 23:50 ` [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions Scott Garman
@ 2011-06-28 13:04   ` Richard Purdie
  2011-06-28 14:42     ` Mark Hatle
  2011-06-29  1:20     ` Scott Garman
  0 siblings, 2 replies; 18+ messages in thread
From: Richard Purdie @ 2011-06-28 13:04 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer

Hi Scott,

Sorry its taken me a while to get to this. Some comments below.

On Thu, 2011-06-02 at 16:50 -0700, Scott Garman wrote:
> This class is to be used by recipes that need to set up specific
> user/group accounts and set custom file/directory permissions.
> 
> Signed-off-by: Scott Garman <scott.a.garman@intel.com>
> ---
>  meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 163 insertions(+), 0 deletions(-)
>  create mode 100644 meta/classes/useradd.bbclass
> 
> diff --git a/meta/classes/useradd.bbclass b/meta/classes/useradd.bbclass
> new file mode 100644
> index 0000000..3f07e5e
> --- /dev/null
> +++ b/meta/classes/useradd.bbclass
> @@ -0,0 +1,163 @@
> +USERADDPN ?= "${PN}"
> +
> +# base-passwd-cross provides the default passwd and group files in the
> +# target sysroot, and shadow-native provides the utilities needed to
> +# add and modify user and group accounts
> +DEPENDS_append = " base-passwd shadow-native"
> +RDEPENDS_${USERADDPN}_append = " base-passwd shadow"
> +
> +PSEUDO="${STAGING_DIR_NATIVE}/usr/bin/pseudo"
> +export PSEUDO

For reference this can be done with:

export PSEUDO = "${STAGING_DIR_NATIVE}/usr/bin/pseudo"

> +PSEUDO_LOCALSTATEDIR="${STAGING_DIR_TARGET}/var/pseudo"
> +export PSEUDO_LOCALSTATEDIR

I'm a little bit puzzled at this point. This is changing the default
PSEUDO state directory to be one shared by many other users rather than
the default of the one in workdir. Is that really what you intend here?

I guess the question is whether we need to preserve these users in the
sysroot or whether preserving them for the install/package/package_write
cycle is enough.

Since tasks don't share the same pseudo context by default, I suspect
we're not preserving users for the sysroot anyhow?

> +PSEUDO_PASSWD = "${STAGING_DIR_TARGET}"
> +export PSEUDO_PASSWD

Should we set this by default as part of the pseudo options in
bitbake.conf?

> +useradd_preinst () {
> +OPT=""
> +SYSROOT=""
> +
> +if test "x$D" != "x"; then
> +	# Installing into a sysroot
> +	SYSROOT="${STAGING_DIR_TARGET}"
> +	OPT="--root ${STAGING_DIR_TARGET}"
> +
> +	# Add groups and users defined for all recipe packages
> +	GROUPADD_PARAM="${@get_all_cmd_params(d, 'group')}"
> +	USERADD_PARAM="${@get_all_cmd_params(d, 'user')}"
> +else
> +	# Installing onto a target
> +	PSEUDO=""
> +
> +	# Add groups and users defined only for this package
> +	GROUPADD_PARAM="${GROUPADD_PARAM}"
> +	USERADD_PARAM="${USERADD_PARAM}"
> +fi
> +
> +# Perform group additions first, since user additions may depend
> +# on these groups existing
> +if test "x$GROUPADD_PARAM" != "x"; then
> +	echo "Running groupadd commands..."
> +	# Invoke multiple instances of groupadd for parameter lists
> +	# separated by ';'
> +	opts=`echo "$GROUPADD_PARAM" | cut -d ';' -f 1`
> +	remaining=`echo "$GROUPADD_PARAM" | cut -d ';' -f 2-`
> +	while test "x$opts" != "x"; do
> +		eval $PSEUDO groupadd -f $OPT $opts

If this task is already running under pseudo, do we specifically need to
run under pseudo here? Is it not already running under pseudo when
needed?

> +		if test "x$opts" = "x$remaining"; then
> +			break
> +		fi
> +		opts=`echo "$remaining" | cut -d ';' -f 1`
> +		remaining=`echo "$remaining" | cut -d ';' -f 2-`
> +	done
> +fi 
> +
> +if test "x$USERADD_PARAM" != "x"; then
> +	echo "Running useradd commands..."
> +	# Invoke multiple instances of useradd for parameter lists
> +	# separated by ';'
> +	opts=`echo "$USERADD_PARAM" | cut -d ';' -f 1`
> +	remaining=`echo "$USERADD_PARAM" | cut -d ';' -f 2-`
> +	while test "x$opts" != "x"; do
> +		# useradd does not have a -f option, so we have to check if the
> +		# username already exists manually
> +		username=`echo "$opts" | awk '{ print $NF }'`
> +		user_exists=`grep "^$username:" $SYSROOT/etc/passwd || true`
> +		if test "x$user_exists" = "x"; then
> +			eval $PSEUDO useradd $OPT $opts
> +		else
> +			echo "Note: username $username already exists, not re-creating it"
> +		fi
> +
> +		if test "x$opts" = "x$remaining"; then
> +			break
> +		fi
> +		opts=`echo "$remaining" | cut -d ';' -f 1`
> +		remaining=`echo "$remaining" | cut -d ';' -f 2-`
> +	done
> +fi
> +}
> +
> +useradd_sysroot () {
> +	# Explicitly set $D since it isn't set to anything
> +	# before do_install
> +	D=${D}
> +	useradd_preinst
> +}
> +
> +useradd_sysroot_sstate () {
> +	if [ "${BB_CURRENTTASK}" = "populate_sysroot_setscene" ]
> +	then
> +		useradd_sysroot
> +	fi
> +}
> +
> +do_install[prefuncs] += "useradd_sysroot"
> +SSTATEPOSTINSTFUNCS += "useradd_sysroot_sstate"
> +
> +# Recipe parse-time sanity checks
> +def update_useradd_after_parse(d):
> +	if bb.data.getVar('USERADD_PACKAGES', d) == None:
> +		if bb.data.getVar('USERADD_PARAM', d) == None and bb.data.getVar('GROUPADD_PARAM', d) == None:
> +			raise bb.build.FuncFailed, "%s inherits useradd but doesn't set USERADD_PARAM or GROUPADD_PARAM" % bb.data.getVar('FILE', d)
> +
> +python __anonymous() {
> +	update_useradd_after_parse(d)
> +}
> +
> +# Return a single [GROUP|USER]ADD_PARAM formatted string which includes the
> +# [group|user]add parameters for all packages in this recipe
> +def get_all_cmd_params(d, cmd_type):
> +	import string
> +	
> +	localdata = bb.data.createCopy(d)
> +	param_type = cmd_type.upper() + "ADD_PARAM_%s"
> +	params = []
> +
> +	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)

Please use True, not 1. Its also simpler to use:

d.getVar('USERADD_PACKAGES', True)

> +	if pkgs == None:

if not pkgs:

> +		pkgs = bb.data.getVar('USERADDPN', d, 1)
> +		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
> +		if not pkgs in packages and packages != []:

if packages and pkgs not in packages:

> +			pkgs = packages[0]
> +
> +	for pkg in pkgs.split():
> +		param = bb.data.getVar(param_type % pkg, localdata, 1)
> +		params.append(param)
> +
> +	return string.join(params, "; ")
> +
> +# Adds the preinst script into generated packages
> +fakeroot python populate_packages_prepend () {
> +	def update_useradd_package(pkg):
> +		bb.debug(1, 'adding user/group calls to preinst for %s' % pkg)
> +		localdata = bb.data.createCopy(d)
> +		overrides = bb.data.getVar("OVERRIDES", localdata, 1)
> +		bb.data.setVar("OVERRIDES", "%s:%s" % (pkg, overrides), localdata)
> +		bb.data.update_data(localdata)
> +
> +		"""
> +		useradd preinst is appended here because pkg_preinst may be
> +		required to execute on the target. Not doing so may cause
> +		useradd preinst to be invoked twice, causing unwanted warnings.
> +		"""
> +		preinst = bb.data.getVar('pkg_preinst', localdata, 1)
> +		if not preinst:
> +			preinst = '#!/bin/sh\n'
> +		preinst += bb.data.getVar('useradd_preinst', localdata, 1)
> +		bb.data.setVar('pkg_preinst_%s' % pkg, preinst, d)
> +
> +	# We add the user/group calls to all packages to allow any package
> +	# to contain files owned by the users/groups defined in the recipe.
> +	# The user/group addition code is careful not to create duplicate
> +	# entries, so this is safe.
> +	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)
> +	if pkgs == None:
> +		pkgs = bb.data.getVar('USERADDPN', d, 1)
> +		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
> +		if not pkgs in packages and packages != []:
> +			pkgs = packages[0]
> +	for pkg in pkgs.split():
> +		update_useradd_package(pkg)
> +}

Cheers,

Richard




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions
  2011-06-28 13:04   ` Richard Purdie
@ 2011-06-28 14:42     ` Mark Hatle
  2011-06-29 14:22       ` Richard Purdie
  2011-06-29  1:20     ` Scott Garman
  1 sibling, 1 reply; 18+ messages in thread
From: Mark Hatle @ 2011-06-28 14:42 UTC (permalink / raw)
  To: openembedded-core

On 6/28/11 8:04 AM, Richard Purdie wrote:
> Hi Scott,
> 
> Sorry its taken me a while to get to this. Some comments below.

I think I know the answer to a few of the issues mentioned below.  Scott can
correct me if I'm wrong.

> On Thu, 2011-06-02 at 16:50 -0700, Scott Garman wrote:
>> This class is to be used by recipes that need to set up specific
>> user/group accounts and set custom file/directory permissions.
>>
>> Signed-off-by: Scott Garman <scott.a.garman@intel.com>
>> ---
>>  meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 163 insertions(+), 0 deletions(-)
>>  create mode 100644 meta/classes/useradd.bbclass
>>
>> diff --git a/meta/classes/useradd.bbclass b/meta/classes/useradd.bbclass
>> new file mode 100644
>> index 0000000..3f07e5e
>> --- /dev/null
>> +++ b/meta/classes/useradd.bbclass
>> @@ -0,0 +1,163 @@
>> +USERADDPN ?= "${PN}"
>> +
>> +# base-passwd-cross provides the default passwd and group files in the
>> +# target sysroot, and shadow-native provides the utilities needed to
>> +# add and modify user and group accounts
>> +DEPENDS_append = " base-passwd shadow-native"
>> +RDEPENDS_${USERADDPN}_append = " base-passwd shadow"
>> +
>> +PSEUDO="${STAGING_DIR_NATIVE}/usr/bin/pseudo"
>> +export PSEUDO
> 
> For reference this can be done with:
> 
> export PSEUDO = "${STAGING_DIR_NATIVE}/usr/bin/pseudo"
> 
>> +PSEUDO_LOCALSTATEDIR="${STAGING_DIR_TARGET}/var/pseudo"
>> +export PSEUDO_LOCALSTATEDIR
> 
> I'm a little bit puzzled at this point. This is changing the default
> PSEUDO state directory to be one shared by many other users rather than
> the default of the one in workdir. Is that really what you intend here?
> 
> I guess the question is whether we need to preserve these users in the
> sysroot or whether preserving them for the install/package/package_write
> cycle is enough.

If we're populating the sysroot, we need to have a pseudo directory setup for it
so that we can run the adduser/group items.  The new adduser/group require the
ability to "chroot" into a (pseudo) root.  The above should only kick in while
working with sysroots.

> Since tasks don't share the same pseudo context by default, I suspect
> we're not preserving users for the sysroot anyhow?

Users are added/preserved within the sysroot /etc/passwd,group in the code.
There is a separate section that runs at sysroot population time that adds the
necessary users/groups... but as mentioned we need the chroot functionality to
do the settings.  (The uid/gid of the files themselves doesn't matter in the
sysroot.)

>> +PSEUDO_PASSWD = "${STAGING_DIR_TARGET}"
>> +export PSEUDO_PASSWD
> 
> Should we set this by default as part of the pseudo options in
> bitbake.conf?

Yes, this likely should go into the bitbake.conf now.  I believe it is in here
though for the same reason that the above was.  It's needed during the sysroot
configuration and the way the utilities work when chrooted.

>> +useradd_preinst () {
>> +OPT=""
>> +SYSROOT=""
>> +
>> +if test "x$D" != "x"; then
>> +	# Installing into a sysroot
>> +	SYSROOT="${STAGING_DIR_TARGET}"
>> +	OPT="--root ${STAGING_DIR_TARGET}"
>> +
>> +	# Add groups and users defined for all recipe packages
>> +	GROUPADD_PARAM="${@get_all_cmd_params(d, 'group')}"
>> +	USERADD_PARAM="${@get_all_cmd_params(d, 'user')}"
>> +else
>> +	# Installing onto a target
>> +	PSEUDO=""
>> +
>> +	# Add groups and users defined only for this package
>> +	GROUPADD_PARAM="${GROUPADD_PARAM}"
>> +	USERADD_PARAM="${USERADD_PARAM}"
>> +fi
>> +
>> +# Perform group additions first, since user additions may depend
>> +# on these groups existing
>> +if test "x$GROUPADD_PARAM" != "x"; then
>> +	echo "Running groupadd commands..."
>> +	# Invoke multiple instances of groupadd for parameter lists
>> +	# separated by ';'
>> +	opts=`echo "$GROUPADD_PARAM" | cut -d ';' -f 1`
>> +	remaining=`echo "$GROUPADD_PARAM" | cut -d ';' -f 2-`
>> +	while test "x$opts" != "x"; do
>> +		eval $PSEUDO groupadd -f $OPT $opts
> 
> If this task is already running under pseudo, do we specifically need to
> run under pseudo here? Is it not already running under pseudo when
> needed?

See answer below...

>> +		if test "x$opts" = "x$remaining"; then
>> +			break
>> +		fi
>> +		opts=`echo "$remaining" | cut -d ';' -f 1`
>> +		remaining=`echo "$remaining" | cut -d ';' -f 2-`
>> +	done
>> +fi 
>> +
>> +if test "x$USERADD_PARAM" != "x"; then
>> +	echo "Running useradd commands..."
>> +	# Invoke multiple instances of useradd for parameter lists
>> +	# separated by ';'
>> +	opts=`echo "$USERADD_PARAM" | cut -d ';' -f 1`
>> +	remaining=`echo "$USERADD_PARAM" | cut -d ';' -f 2-`
>> +	while test "x$opts" != "x"; do
>> +		# useradd does not have a -f option, so we have to check if the
>> +		# username already exists manually
>> +		username=`echo "$opts" | awk '{ print $NF }'`
>> +		user_exists=`grep "^$username:" $SYSROOT/etc/passwd || true`
>> +		if test "x$user_exists" = "x"; then
>> +			eval $PSEUDO useradd $OPT $opts
>> +		else
>> +			echo "Note: username $username already exists, not re-creating it"
>> +		fi
>> +
>> +		if test "x$opts" = "x$remaining"; then
>> +			break
>> +		fi
>> +		opts=`echo "$remaining" | cut -d ';' -f 1`
>> +		remaining=`echo "$remaining" | cut -d ';' -f 2-`
>> +	done
>> +fi
>> +}
>> +
>> +useradd_sysroot () {
>> +	# Explicitly set $D since it isn't set to anything
>> +	# before do_install
>> +	D=${D}
>> +	useradd_preinst
>> +}
>> +
>> +useradd_sysroot_sstate () {
>> +	if [ "${BB_CURRENTTASK}" = "populate_sysroot_setscene" ]
>> +	then
>> +		useradd_sysroot
>> +	fi
>> +}

The way this is implemented the new sysroot tasks call the regular tasks so the
code only has to be implemented once.  Assuming context doesn't change, it
should be possible to move the "PSEUDO" calls down into the _sysroot functions
and remove them from the items that get embedded into the target packages.

>> +
>> +do_install[prefuncs] += "useradd_sysroot"
>> +SSTATEPOSTINSTFUNCS += "useradd_sysroot_sstate"
>> +
>> +# Recipe parse-time sanity checks
>> +def update_useradd_after_parse(d):
>> +	if bb.data.getVar('USERADD_PACKAGES', d) == None:
>> +		if bb.data.getVar('USERADD_PARAM', d) == None and bb.data.getVar('GROUPADD_PARAM', d) == None:
>> +			raise bb.build.FuncFailed, "%s inherits useradd but doesn't set USERADD_PARAM or GROUPADD_PARAM" % bb.data.getVar('FILE', d)
>> +
>> +python __anonymous() {
>> +	update_useradd_after_parse(d)
>> +}
>> +
>> +# Return a single [GROUP|USER]ADD_PARAM formatted string which includes the
>> +# [group|user]add parameters for all packages in this recipe
>> +def get_all_cmd_params(d, cmd_type):
>> +	import string
>> +	
>> +	localdata = bb.data.createCopy(d)
>> +	param_type = cmd_type.upper() + "ADD_PARAM_%s"
>> +	params = []
>> +
>> +	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)
> 
> Please use True, not 1. Its also simpler to use:
> 
> d.getVar('USERADD_PACKAGES', True)

I hadn't noticed this in my earlier review -- but "d" should probably be using
"localdata" instead.  I realize at this point in the code "d" and "localdata"
are the same.... or ...

>> +	if pkgs == None:
> 
> if not pkgs:
> 
>> +		pkgs = bb.data.getVar('USERADDPN', d, 1)
>> +		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
>> +		if not pkgs in packages and packages != []:
> 
> if packages and pkgs not in packages:
> 
>> +			pkgs = packages[0]
>> +
>> +	for pkg in pkgs.split():
>> +		param = bb.data.getVar(param_type % pkg, localdata, 1)
>> +		params.append(param)
>> +
>> +	return string.join(params, "; ")

... it's not clear to me that any of the 'd' elements are changing.  So
localdata may not actually be needed in any way.  Either we should be consistent
and use localdata everywhere or just 'd'.  (Normally I use localdata when I'm
transforming the data "in-place" and using setVar... but I don't see that in here.

>> +# Adds the preinst script into generated packages
>> +fakeroot python populate_packages_prepend () {
>> +	def update_useradd_package(pkg):
>> +		bb.debug(1, 'adding user/group calls to preinst for %s' % pkg)
>> +		localdata = bb.data.createCopy(d)
>> +		overrides = bb.data.getVar("OVERRIDES", localdata, 1)
>> +		bb.data.setVar("OVERRIDES", "%s:%s" % (pkg, overrides), localdata)
>> +		bb.data.update_data(localdata)

However, above we are using setVar, so localdata is correct.

>> +
>> +		"""
>> +		useradd preinst is appended here because pkg_preinst may be
>> +		required to execute on the target. Not doing so may cause
>> +		useradd preinst to be invoked twice, causing unwanted warnings.
>> +		"""
>> +		preinst = bb.data.getVar('pkg_preinst', localdata, 1)
>> +		if not preinst:
>> +			preinst = '#!/bin/sh\n'
>> +		preinst += bb.data.getVar('useradd_preinst', localdata, 1)
>> +		bb.data.setVar('pkg_preinst_%s' % pkg, preinst, d)
>> +
>> +	# We add the user/group calls to all packages to allow any package
>> +	# to contain files owned by the users/groups defined in the recipe.
>> +	# The user/group addition code is careful not to create duplicate
>> +	# entries, so this is safe.
>> +	pkgs = bb.data.getVar('USERADD_PACKAGES', d, 1)
>> +	if pkgs == None:
>> +		pkgs = bb.data.getVar('USERADDPN', d, 1)
>> +		packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
>> +		if not pkgs in packages and packages != []:
>> +			pkgs = packages[0]
>> +	for pkg in pkgs.split():
>> +		update_useradd_package(pkg)
>> +}
> 
> Cheers,
> 
> Richard
> 
> 
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions
  2011-06-28 13:04   ` Richard Purdie
  2011-06-28 14:42     ` Mark Hatle
@ 2011-06-29  1:20     ` Scott Garman
  1 sibling, 0 replies; 18+ messages in thread
From: Scott Garman @ 2011-06-29  1:20 UTC (permalink / raw)
  To: openembedded-core

On 06/28/2011 06:04 AM, Richard Purdie wrote:
> Hi Scott,
>
> Sorry its taken me a while to get to this. Some comments below.

Hi Richard,

Thanks for the feedback. I'm hoping to get you a v2 pull request 
sometime tomorrow which incorporates some of your suggested changes. 
Mark gave good explanations on the points I will not be changing.

Scott

-- 
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions
  2011-06-28 14:42     ` Mark Hatle
@ 2011-06-29 14:22       ` Richard Purdie
  0 siblings, 0 replies; 18+ messages in thread
From: Richard Purdie @ 2011-06-29 14:22 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer

On Tue, 2011-06-28 at 09:42 -0500, Mark Hatle wrote:
> On 6/28/11 8:04 AM, Richard Purdie wrote:
> > Hi Scott,
> > 
> > Sorry its taken me a while to get to this. Some comments below.
> 
> I think I know the answer to a few of the issues mentioned below.  Scott can
> correct me if I'm wrong.
> 
> > On Thu, 2011-06-02 at 16:50 -0700, Scott Garman wrote:
> >> This class is to be used by recipes that need to set up specific
> >> user/group accounts and set custom file/directory permissions.
> >>
> >> Signed-off-by: Scott Garman <scott.a.garman@intel.com>
> >> ---
> >>  meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
> >>  1 files changed, 163 insertions(+), 0 deletions(-)
> >>  create mode 100644 meta/classes/useradd.bbclass
> >>
> >> diff --git a/meta/classes/useradd.bbclass b/meta/classes/useradd.bbclass
> >> new file mode 100644
> >> index 0000000..3f07e5e
> >> --- /dev/null
> >> +++ b/meta/classes/useradd.bbclass
> >> @@ -0,0 +1,163 @@
> >> +USERADDPN ?= "${PN}"
> >> +
> >> +# base-passwd-cross provides the default passwd and group files in the
> >> +# target sysroot, and shadow-native provides the utilities needed to
> >> +# add and modify user and group accounts
> >> +DEPENDS_append = " base-passwd shadow-native"
> >> +RDEPENDS_${USERADDPN}_append = " base-passwd shadow"
> >> +
> >> +PSEUDO="${STAGING_DIR_NATIVE}/usr/bin/pseudo"
> >> +export PSEUDO
> > 
> > For reference this can be done with:
> > 
> > export PSEUDO = "${STAGING_DIR_NATIVE}/usr/bin/pseudo"
> > 
> >> +PSEUDO_LOCALSTATEDIR="${STAGING_DIR_TARGET}/var/pseudo"
> >> +export PSEUDO_LOCALSTATEDIR
> > 
> > I'm a little bit puzzled at this point. This is changing the default
> > PSEUDO state directory to be one shared by many other users rather than
> > the default of the one in workdir. Is that really what you intend here?
> > 
> > I guess the question is whether we need to preserve these users in the
> > sysroot or whether preserving them for the install/package/package_write
> > cycle is enough.
> 
> If we're populating the sysroot, we need to have a pseudo directory setup for it
> so that we can run the adduser/group items.  The new adduser/group require the
> ability to "chroot" into a (pseudo) root.  The above should only kick in while
> working with sysroots.

I understand this now. I still do have a concern about namespacing
though. I think alongside the existing code which does:

SYSROOT="${STAGING_DIR_TARGET}"
OPT="--root ${STAGING_DIR_TARGET}"

we should have these PSEUDO* exports, then they can't easily get
confused with the general pseudo environment we're using. Some comments
about what this is doing would also be useful as if I can't understand
this now, its likely in 3 months time its just going to be worse...

> The way this is implemented the new sysroot tasks call the regular tasks so the
> code only has to be implemented once.  Assuming context doesn't change, it
> should be possible to move the "PSEUDO" calls down into the _sysroot functions
> and remove them from the items that get embedded into the target packages.

I like this idea and I think it will be clearer whats going on,
particularly if we can do something like I mention above :)

> >> +			pkgs = packages[0]
> >> +
> >> +	for pkg in pkgs.split():
> >> +		param = bb.data.getVar(param_type % pkg, localdata, 1)
> >> +		params.append(param)
> >> +
> >> +	return string.join(params, "; ")
> 
> ... it's not clear to me that any of the 'd' elements are changing.  So
> localdata may not actually be needed in any way.  Either we should be consistent
> and use localdata everywhere or just 'd'.  (Normally I use localdata when I'm
> transforming the data "in-place" and using setVar... but I don't see that in here.

Good catch, I think there should be more use of localdata here too.

Cheers,

Richard






^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-06-29 14:27 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-02 23:50 [PATCH 0/7] User/group creation at preinstall v2 Scott Garman
2011-06-02 23:50 ` [PATCH 1/7] shadow: recipe and patch cleanup Scott Garman
2011-06-02 23:50 ` [PATCH 2/7] shadow: add a -native recipe with customized utilities Scott Garman
2011-06-02 23:50 ` [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs Scott Garman
2011-06-09 20:50   ` Koen Kooi
2011-06-09 21:23     ` Scott Garman
2011-06-09 21:25       ` Koen Kooi
2011-06-09 21:29         ` Scott Garman
2011-06-10 22:22         ` shadow errors related to login.defs Scott Garman
2011-06-10 22:38           ` Koen Kooi
2011-06-02 23:50 ` [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions Scott Garman
2011-06-28 13:04   ` Richard Purdie
2011-06-28 14:42     ` Mark Hatle
2011-06-29 14:22       ` Richard Purdie
2011-06-29  1:20     ` Scott Garman
2011-06-02 23:50 ` [PATCH 5/7] useradd-example: example recipe for using inherit useradd Scott Garman
2011-06-02 23:50 ` [PATCH 6/7] bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV Scott Garman
2011-06-02 23:50 ` [PATCH 7/7] package_rpm.bbclass: make RPM use on-disk permissions Scott Garman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.