Skip to contentSkip to conversation

User/group creation at preinstall v2

PATCH In review Scott Garman 4 participants 18 messages Jun 2, 2011 – Jun 29, 2011

lore
Share & tools
lore
#0 lore raw

cover User/group creation at preinstall v2

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
#1 lore raw

PATCH 1/7 shadow: recipe and patch cleanup

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.

---
 .../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
meta/recipes-extended/shadow/files/shadow-4.1.3-dots-in-usernames.patch +4 -0
index 7a2ff2e..a7bb0a9 100644
@@ -9,6 +9,10 @@
 #
 # comment added by Kevin Tian <[email protected]>, 2010-08-11
 
+Upstream-Status: Pending
+
+Signed-off-by: Scott Garman <[email protected]>
+
 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
meta/recipes-extended/shadow/files/shadow-4.1.4.2-env-reset-keep-locale.patch +4 -0
index 124065c..6514746 100644
@@ -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 <[email protected]>
+
 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
meta/recipes-extended/shadow/files/shadow-4.1.4.2-groupmod-pam-check.patch +4 -0
index 6682fe8..640200b 100644
@@ -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 <[email protected]>
+
 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
meta/recipes-extended/shadow/files/shadow-4.1.4.2-su_no_sanitize_env.patch +4 -0
index f67251c..0dc4d75 100644
@@ -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 <[email protected]>
+
 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
meta/recipes-extended/shadow/files/shadow.automake-1.11.patch +4 -0
index 36d7be6..a793f09 100644
@@ -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 <[email protected]>
+
 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
meta/recipes-extended/shadow/shadow.inc deleted +0 -121

121 lines not on this page · raw message

meta/recipes-extended/shadow/shadow_4.1.4.3.bb +132 -9

146 lines not on this page · raw message

Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/7 shadow: add a -native recipe with customized utilities

In reply to Scott Garman

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.

---
 .../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
meta/recipes-extended/shadow/files/add_root_cmd_options.patch new file +1296 -0
new file mode 100644
index 0000000..db969bb
@@ -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 <[email protected]>
+
+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 ();
meta/recipes-extended/shadow/shadow-native_4.1.4.3.bb new file +66 -0

66 lines not on this page · raw message

Signature · 1 line
1.7.1
#3 lore raw

PATCH 3/7 base-passwd: populate the target sysroot with passwd/group/login.defs

In reply to Scott Garman

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.

---
 .../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
meta/recipes-core/base-passwd/base-passwd-3.5.22/login.defs new file +386 -0
new file mode 100644
index 0000000..1d392ac
@@ -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
+
meta/recipes-core/base-passwd/base-passwd_3.5.22.bb +25 -2
index 6f768ca..3315c68 100644
@@ -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
+}
Signature · 1 line
1.7.1
#4 lore raw

Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs

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

Quoted 7 lines

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.

---
.../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

#5 lore raw

Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs

Quoted 31 lines · Koen Kooi

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

Quoted 7 lines

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.

---
.../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'
Quoted 1 line

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

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

Scott

Signature · 3 lines
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center
#6 lore raw

Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs

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

Quoted 32 lines · Koen Kooi
Quoted 31 lines

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

Quoted 7 lines

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.

---
.../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'
Quoted 3 lines
Quoted 1 line

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

#7 lore raw

Re: [PATCH 3/7] base-passwd: populate the target sysroot with passwd/group/login.defs

Quoted 35 lines · Koen Kooi

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

Quoted 32 lines · Koen Kooi
Quoted 31 lines

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

Quoted 7 lines

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.

---
.../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'
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

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

Signature · 3 lines
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center
#8 lore raw

shadow errors related to login.defs

In reply to Koen Kooi
Quoted 35 lines · Koen Kooi

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

Quoted 32 lines · Koen Kooi
Quoted 31 lines

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

Quoted 7 lines

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.

---
.../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'
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

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

Signature · 3 lines
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center
#9 lore raw

Re: shadow errors related to login.defs

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

Quoted 38 lines · Koen Kooi
Quoted 37 lines

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

Quoted 34 lines · Koen Kooi
Quoted 32 lines

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

Quoted 7 lines

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.

---
.../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.

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

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

#10 lore raw

PATCH 4/7 useradd.bbclass: new class for managing user/group permissions

In reply to Scott Garman

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

---
 meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 meta/classes/useradd.bbclass
meta/classes/useradd.bbclass new file +163 -0
new file mode 100644
index 0000000..3f07e5e
@@ -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)
+}
Signature · 1 line
1.7.1
#11 lore raw

Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions

Hi Scott,

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

Quoted 15 lines · Scott Garman

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

---
 meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 meta/classes/useradd.bbclass
meta/classes/useradd.bbclass new file +0 -0
new file mode 100644
index 0000000..3f07e5e

meta/classes/useradd.bbclass line 10

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
@@ -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"

meta/classes/useradd.bbclass line 12

Quoted 2 lines
meta/classes/useradd.bbclass new file +2 -0
+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?

meta/classes/useradd.bbclass line 14

Quoted 2 lines
meta/classes/useradd.bbclass new file +2 -0
+PSEUDO_PASSWD = "${STAGING_DIR_TARGET}"
+export PSEUDO_PASSWD

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

Quoted 21 lines
meta/classes/useradd.bbclass new file +21 -0
+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
+

meta/classes/useradd.bbclass line 46

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
+# 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?

Quoted 61 lines
meta/classes/useradd.bbclass new file +61 -0
+		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)
+}
+

meta/classes/useradd.bbclass line 118

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
+# 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)

meta/classes/useradd.bbclass line 117

Quoted 1 line
meta/classes/useradd.bbclass new file +1 -0
+	if pkgs == None:

if not pkgs:

meta/classes/useradd.bbclass line 122

Quoted 3 lines
meta/classes/useradd.bbclass new file +3 -0
+		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:

Quoted 31 lines
meta/classes/useradd.bbclass new file +31 -0
+			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

meta/classes/useradd.bbclass line 163

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
+	# 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

#12 lore raw

Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions

Quoted 3 lines · Richard Purdie

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.

Quoted 38 lines · Scott Garman
Quoted 15 lines

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

---
 meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 meta/classes/useradd.bbclass
meta/classes/useradd.bbclass new file +0 -0
new file mode 100644
index 0000000..3f07e5e

meta/classes/useradd.bbclass line 10

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
@@ -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"

meta/classes/useradd.bbclass line 12

Quoted 2 lines
meta/classes/useradd.bbclass new file +2 -0
+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?

Quoted 3 lines

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.

Quoted 2 lines

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.)

Quoted 5 lines

meta/classes/useradd.bbclass line 14

Quoted 2 lines
meta/classes/useradd.bbclass new file +2 -0
+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.

Quoted 27 lines
Quoted 27 lines
meta/classes/useradd.bbclass new file +27 -0
+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 ';'
Quoted 8 lines

meta/classes/useradd.bbclass line 46

Quoted 4 lines
meta/classes/useradd.bbclass new file +4 -0
+	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...

Quoted 39 lines
Quoted 39 lines
meta/classes/useradd.bbclass new file +39 -0
+		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
Quoted 8 lines

meta/classes/useradd.bbclass line 94

Quoted 8 lines
meta/classes/useradd.bbclass new file +8 -0
+}
+
+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.

Quoted 27 lines
Quoted 14 lines
meta/classes/useradd.bbclass new file +14 -0
+
+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)
+}
+

meta/classes/useradd.bbclass line 118

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
+# 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:

Quoted 1 line

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 ...

Quoted 10 lines

meta/classes/useradd.bbclass line 117

Quoted 1 line
meta/classes/useradd.bbclass new file +1 -0
+	if pkgs == None:

if not pkgs:

meta/classes/useradd.bbclass line 122

Quoted 3 lines
meta/classes/useradd.bbclass new file +3 -0
+		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:

Quoted 7 lines

meta/classes/useradd.bbclass line 129

Quoted 7 lines
meta/classes/useradd.bbclass new file +7 -0
+			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.

Quoted 8 lines

meta/classes/useradd.bbclass line 138

Quoted 8 lines
meta/classes/useradd.bbclass new file +8 -0
+# 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.

Quoted 35 lines
Quoted 15 lines
meta/classes/useradd.bbclass new file +15 -0
+
+		"""
+		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

meta/classes/useradd.bbclass line 163

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
+	# 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
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core

#13 lore raw

Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions

Quoted 46 lines · Mark Hatle
Quoted 3 lines · Richard Purdie

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.

Quoted 38 lines · Scott Garman
Quoted 15 lines

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

---
 meta/classes/useradd.bbclass |  163 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 meta/classes/useradd.bbclass
meta/classes/useradd.bbclass new file +0 -0
new file mode 100644
index 0000000..3f07e5e

meta/classes/useradd.bbclass line 10

Quoted 10 lines
meta/classes/useradd.bbclass new file +10 -0
@@ -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"

meta/classes/useradd.bbclass line 12

Quoted 2 lines
meta/classes/useradd.bbclass new file +2 -0
+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?

Quoted 8 lines
Quoted 3 lines

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...

Quoted 4 lines

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 :)

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
meta/classes/useradd.bbclass new file +4 -0
+			pkgs = packages[0]
+
+	for pkg in pkgs.split():
+		param = bb.data.getVar(param_type % pkg, localdata, 1)
Quoted 8 lines
Quoted 3 lines

meta/classes/useradd.bbclass line 129

Quoted 3 lines
meta/classes/useradd.bbclass new file +3 -0
+		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

#14 lore raw

Re: [PATCH 4/7] useradd.bbclass: new class for managing user/group permissions

In reply to Richard Purdie
Quoted 3 lines · Richard Purdie

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

Signature · 3 lines
Scott Garman
Embedded Linux Engineer - Yocto Project
Intel Open Source Technology Center
#15 lore raw

PATCH 5/7 useradd-example: example recipe for using inherit useradd

In reply to Scott Garman

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

---
 .../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
meta-skeleton/recipes-skeleton/useradd/useradd-example.bb new file +72 -0
new file mode 100644
index 0000000..6c6edf0
@@ -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/*"
meta-skeleton/recipes-skeleton/useradd/useradd-example/file1 new file +0 -0
new file mode 100644
index 0000000..e69de29
meta-skeleton/recipes-skeleton/useradd/useradd-example/file2 new file +0 -0
new file mode 100644
index 0000000..e69de29
meta-skeleton/recipes-skeleton/useradd/useradd-example/file3 new file +0 -0
new file mode 100644
index 0000000..e69de29
meta-skeleton/recipes-skeleton/useradd/useradd-example/file4 new file +0 -0
new file mode 100644
index 0000000..e69de29
Signature · 1 line
1.7.1
#16 lore raw

PATCH 6/7 bitbake.conf: set PSEUDO_PASSWD within FAKEROOTENV

In reply to Scott Garman

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.

---
 meta/conf/bitbake.conf |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
meta/conf/bitbake.conf +1 -1
index d307385..6f16a65 100644
@@ -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"
 
Signature · 1 line
1.7.1
#17 lore raw

PATCH 7/7 package_rpm.bbclass: make RPM use on-disk permissions

In reply to Scott Garman

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.

---
 meta/classes/package_rpm.bbclass |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
meta/classes/package_rpm.bbclass +2 -0
index 1d8c686..d124c01 100644
@@ -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('')
Signature · 1 line
1.7.1