From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1NhPwV-0004U4-7B for garchives@archives.gentoo.org; Tue, 16 Feb 2010 16:06:32 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id CE7D7E0AFB for ; Tue, 16 Feb 2010 16:06:30 +0000 (UTC) Received: from vms173017pub.verizon.net (vms173017pub.verizon.net [206.46.173.17]) by pigeon.gentoo.org (Postfix) with ESMTP id 2A5FFE07AB for ; Tue, 16 Feb 2010 15:42:28 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-embedded@lists.gentoo.org Reply-to: gentoo-embedded@lists.gentoo.org MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_ha5TfHHqr5wHwzKki9cf5w)" Received: from [192.168.0.7] ([unknown] [173.63.22.246]) by vms173017.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0KXX009IJYACRXP8@vms173017.mailsrvcs.net> for gentoo-embedded@lists.gentoo.org; Tue, 16 Feb 2010 09:42:14 -0600 (CST) Message-id: <4B7ABCD4.4070805@verizon.net> Date: Tue, 16 Feb 2010 10:42:12 -0500 From: "P. Levine" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100206 Lightning/1.0b2pre Thunderbird/3.0.1 To: gentoo-embedded@lists.gentoo.org Subject: Re: [gentoo-embedded] emerge --root : users not created X-Enigmail-Version: 1.0 X-Archives-Salt: b7de0b59-e7b2-470d-8b88-613c000c2478 X-Archives-Hash: 97b70b4f370c37d74899e7b8f325e1e6 This is a multi-part message in MIME format. --Boundary_(ID_ha5TfHHqr5wHwzKki9cf5w) Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT On 02/16/2010 10:04 AM, P. Levine wrote: > Peter Stuge wrote: >> I talked to upstream on freenode/#shadow and they welcome a patch for >> adding --chroot >> >> chroot() needs to happen really early since useradd and friends read >> some configuration files to know e.g. which password encryption >> method to use. > > Attached is a tentative patch to add a chroot flag to useradd and > groupadd (via --chroot or -R). It compiles and works on my end > (--chroot /usr/armv4tl-softfloat-linux-gnueabi) with various other flags > enabled. I'm hoping for others to test it and get some feedback before > I submit it to shadow upstream. > > There do exist a couple of issues: > > sysconf(_SC_NGROUPS_MAX) is called by useradd early on. This would > report the maximum allowable number of groups per user on the build > system, not the target. To my knowledge, this is set by the kernel and > would have to be used. However, this tends to be a very high number for > linux kernel >= 2.6.3 (65536) so it seems like a mute point (for linux > kernel >= 2.6.3). > > There are a number of calls to "getXXbyYY" functions (i.e., getgrgid, > getpwnam, etc...). These seem to be dynamically preloaded and access > preloaded databases. They are unaffected by chroot() (even after > setting __nss_configure_lookup(foo, files)). I've instead used shadow's > own method of macro expansion to generate functions doing the > equivalent, with recursive calls to fgetXXent functions. > > And PAM functionality doesn't work and has to be disabled while using > chroot(). I don't know very much about PAM. Would this be a problem? > > Also, the chroot functionality could probably be easily extended to > other modules but I'm not sure if this would be acceptable upstream. > > There are a couple of cosmetic changes I'm considering as well (such as > how --chroot flag is parsed). > > -- Peter Levine Sorry, wrong patch. I've attached the correct one. -- Peter Levine --Boundary_(ID_ha5TfHHqr5wHwzKki9cf5w) Content-type: text/x-patch; name=shadow-4.1.4.2-chroot.patch Content-disposition: attachment; filename=shadow-4.1.4.2-chroot.patch Content-Transfer-Encoding: quoted-printable diff -Naur shadow-4.1.4.2.old/config.h.in shadow-4.1.4.2/config.h.in --- shadow-4.1.4.2.old/config.h.in 2009-07-23 21:15:58.000000000 -0400 +++ shadow-4.1.4.2/config.h.in 2010-02-16 07:19:48.000000000 -0500 @@ -68,6 +68,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H =20 +/* Define to 1 if you have the `fgetgrent_r' function. */ +#undef HAVE_FGETGRENT_R + +/* Define to 1 if you have the `fgetpwent_r' function. */ +#undef HAVE_FGETPWENT_R + /* Define to 1 if you have the `fsync' function. */ #undef HAVE_FSYNC =20 diff -Naur shadow-4.1.4.2.old/configure shadow-4.1.4.2/configure --- shadow-4.1.4.2.old/configure 2009-07-23 21:15:56.000000000 -0400 +++ shadow-4.1.4.2/configure 2010-02-16 07:19:48.000000000 -0500 @@ -13536,7 +13536,8 @@ for ac_func in l64a fchmod fchown fsync futimes getgroups gethostname ge= tspnam \ gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innet= gr \ - getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo + fgetpwent_r fgetgrent_r getpwnam_r getpwuid_r getgrnam_r getgrgid_r \ + getspnam_r getaddrinfo do as_ac_var=3D`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 diff -Naur shadow-4.1.4.2.old/configure.in shadow-4.1.4.2/configure.in --- shadow-4.1.4.2.old/configure.in 2009-07-23 21:10:31.000000000 -0400 +++ shadow-4.1.4.2/configure.in 2010-02-16 07:19:48.000000000 -0500 @@ -41,7 +41,8 @@ AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname ge= tspnam \ gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \ lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innet= gr \ - getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo) + fgetpwent_r fgetgrent_r getpwnam_r getpwuid_r getgrnam_r getgrgid_r \ + getspnam_r getaddrinfo) AC_SYS_LARGEFILE =20 dnl Checks for typedefs, structures, and compiler characteristics. diff -Naur shadow-4.1.4.2.old/lib/prototypes.h shadow-4.1.4.2/lib/prototy= pes.h --- shadow-4.1.4.2.old/lib/prototypes.h 2009-05-18 14:32:21.000000000 -04= 00 +++ shadow-4.1.4.2/lib/prototypes.h 2010-02-16 07:19:48.000000000 -0500 @@ -154,6 +154,7 @@ =20 /* getgr_nam_gid.c */ extern /*@null@*/struct group *getgr_nam_gid (const char *grname); +extern /*@null@*/struct group *fgetgr_nam_gid (const char *grname); =20 /* getlong.c */ extern int getlong (const char *numstr, /*@out@*/long int *result); @@ -400,6 +401,15 @@ /* xgetspnam.c */ extern /*@null@*/ /*@only@*/struct spwd *xgetspnam(const char *); =20 +/* xfgetpwnam.c */ +extern /*@null@*/ /*@only@*/struct passwd *xfgetpwnam (const char *); +/* xfgetpwuid.c */ +extern /*@null@*/ /*@only@*/struct passwd *xfgetpwuid (uid_t); +/* xfgetgrnam.c */ +extern /*@null@*/ /*@only@*/struct group *xfgetgrnam (const char *); +/* xfgetgrgid.c */ +extern /*@null@*/ /*@only@*/struct group *xfgetgrgid (gid_t); + /* yesno.c */ extern bool yes_or_no (bool read_only); =20 diff -Naur shadow-4.1.4.2.old/libmisc/Makefile.am shadow-4.1.4.2/libmisc/= Makefile.am --- shadow-4.1.4.2.old/libmisc/Makefile.am 2009-05-17 14:39:06.000000000 = -0400 +++ shadow-4.1.4.2/libmisc/Makefile.am 2010-02-16 07:19:48.000000000 -050= 0 @@ -1,5 +1,5 @@ =20 -EXTRA_DIST =3D .indent.pro xgetXXbyYY.c +EXTRA_DIST =3D .indent.pro xgetXXbyYY.c xfgetXXbyYY.c =20 INCLUDES =3D -I$(top_srcdir)/lib =20 @@ -59,6 +59,10 @@ user_busy.c \ utmp.c \ valid.c \ + xfgetpwnam.c \ + xfgetpwuid.c \ + xfgetgrnam.c \ + xfgetgrgid.c \ xgetpwnam.c \ xgetpwuid.c \ xgetgrnam.c \ diff -Naur shadow-4.1.4.2.old/libmisc/Makefile.in shadow-4.1.4.2/libmisc/= Makefile.in --- shadow-4.1.4.2.old/libmisc/Makefile.in 2009-07-23 21:15:59.000000000 = -0400 +++ shadow-4.1.4.2/libmisc/Makefile.in 2010-02-16 07:19:48.000000000 -050= 0 @@ -64,9 +64,10 @@ shell.$(OBJEXT) system.$(OBJEXT) strtoday.$(OBJEXT) \ sub.$(OBJEXT) sulog.$(OBJEXT) ttytype.$(OBJEXT) tz.$(OBJEXT) \ ulimit.$(OBJEXT) user_busy.$(OBJEXT) utmp.$(OBJEXT) \ - valid.$(OBJEXT) xgetpwnam.$(OBJEXT) xgetpwuid.$(OBJEXT) \ - xgetgrnam.$(OBJEXT) xgetgrgid.$(OBJEXT) xgetspnam.$(OBJEXT) \ - xmalloc.$(OBJEXT) yesno.$(OBJEXT) + valid.$(OBJEXT) xfgetpwnam.$(OBJEXT) xfgetpwuid.$(OBJEXT) \ + xfgetgrnam.$(OBJEXT) xfgetgrgid.$(OBJEXT) xgetpwnam.$(OBJEXT) \ + xgetpwuid.$(OBJEXT) xgetgrnam.$(OBJEXT) xgetgrgid.$(OBJEXT) \ + xgetspnam.$(OBJEXT) xmalloc.$(OBJEXT) yesno.$(OBJEXT) libmisc_a_OBJECTS =3D $(am_libmisc_a_OBJECTS) DEFAULT_INCLUDES =3D -I.@am__isrc@ -I$(top_builddir) depcomp =3D $(SHELL) $(top_srcdir)/depcomp @@ -232,7 +233,7 @@ top_build_prefix =3D @top_build_prefix@ top_builddir =3D @top_builddir@ top_srcdir =3D @top_srcdir@ -EXTRA_DIST =3D .indent.pro xgetXXbyYY.c +EXTRA_DIST =3D .indent.pro xgetXXbyYY.c xfgetXXbyYY.c INCLUDES =3D -I$(top_srcdir)/lib noinst_LIBRARIES =3D libmisc.a libmisc_a_SOURCES =3D \ @@ -289,6 +290,10 @@ user_busy.c \ utmp.c \ valid.c \ + xfgetpwnam.c \ + xfgetpwuid.c \ + xfgetgrnam.c \ + xfgetgrgid.c \ xgetpwnam.c \ xgetpwuid.c \ xgetgrnam.c \ @@ -395,6 +400,10 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_busy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utmp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfgetgrgid.Po@am__quote= @ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfgetgrnam.Po@am__quote= @ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfgetpwnam.Po@am__quote= @ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfgetpwuid.Po@am__quote= @ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetgrgid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetgrnam.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetpwnam.Po@am__quote@ diff -Naur shadow-4.1.4.2.old/libmisc/getgr_nam_gid.c shadow-4.1.4.2/libm= isc/getgr_nam_gid.c --- shadow-4.1.4.2.old/libmisc/getgr_nam_gid.c 2009-04-29 09:50:14.000000= 000 -0400 +++ shadow-4.1.4.2/libmisc/getgr_nam_gid.c 2010-02-16 07:19:48.000000000 = -0500 @@ -64,3 +64,29 @@ return xgetgrnam (grname); } =20 +/* + * fgetgr_nam_gid - Return a pointer to the group specified by a string + * using recursive calls to fgetgrent. + * The string may be a valid GID or a valid groupname. + * If the group does not exist on the system, NULL is returned. + */ +extern /*@null@*/struct group *fgetgr_nam_gid (const char *grname) +{ + long long int gid; + char *endptr; + + if (NULL =3D=3D grname) { + return NULL; + } + + errno =3D 0; + gid =3D strtoll (grname, &endptr, 10); + if ( ('\0' !=3D *grname) + && ('\0' =3D=3D *endptr) + && (ERANGE !=3D errno) + && (/*@+longintegral@*/gid =3D=3D (gid_t)gid)/*@=3Dlongintegral@*/)= { + return xfgetgrgid ((gid_t) gid); + } + return xfgetgrnam (grname); +} + diff -Naur shadow-4.1.4.2.old/libmisc/xfgetXXbyYY.c shadow-4.1.4.2/libmis= c/xfgetXXbyYY.c --- shadow-4.1.4.2.old/libmisc/xfgetXXbyYY.c 1969-12-31 19:00:00.00000000= 0 -0500 +++ shadow-4.1.4.2/libmisc/xfgetXXbyYY.c 2010-02-16 07:19:48.000000000 -0= 500 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2007 - 2009, Nicolas Fran=C3=A7ois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the copyright holders or contributors may not be used = to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR= A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1.=C2=A0Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' function= s. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this functio= n + * is likely to corrupt a pointer previously obtained by the applicatio= n. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structur= e + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provide wrapper to the getpwnam or getpwnam_r functions. + */ + +#include +#include +#include +#include +#include "prototypes.h" + +#define F_FUNCTION_NAME F_FUNCTION_NAME1 (DB_TYPE) +#define F_FUNCTION_NAME1(name) F_FUNCTION_NAME2 (name) +#define F_FUNCTION_NAME2(name) fget##name##ent +#define F_COMPARE F_COMPARE1 (DB_TYPE,ARG_NAME) +#define F_COMPARE1(name1,name2) F_COMPARE2 (name1,name2) +#define F_COMPARE2(name1,name2) F_COMPARE3 (name1 ## _ ## name2,name2) +#define F_COMPARE3(name1,name2) F_COMPARE_## name2 (result->name1,name2) +#define F_COMPARE_gid F_COMPARE_num +#define F_COMPARE_uid F_COMPARE_num +#define F_COMPARE_namp F_COMPARE_str +#define F_COMPARE_name F_COMPARE_str +#define F_COMPARE_num(name1,name2) (name1 =3D=3D name2) +#define F_COMPARE_str(name1,name2) (!strcmp(name1,name2)) + +#define XFUNCTION_NAME XPREFIX (FUNCTION_NAME) +#define XPREFIX(name) XPREFIX1 (name) +#define XPREFIX1(name) x##name +#define REENTRANT_NAME APPEND_R (F_FUNCTION_NAME) +#define APPEND_R(name) APPEND_R1 (name) +#define APPEND_R1(name) name##_r +#define STRINGIZE(name) STRINGIZE1 (name) +#define STRINGIZE1(name) #name + +/*@null@*/ /*@only@*/LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME) +{ + FILE *stream =3D NULL; + if ((stream =3D fopen (DB_FILE, "r")) =3D=3D NULL) { + fprintf (stderr, _("%s: Error opening the database file.\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (1); + } +#if HAVE_FUNCTION_R + LOOKUP_TYPE *result=3DNULL; + char *buffer=3DNULL; + /* we have to start with something */ + size_t length =3D 0x100; + + result =3D malloc(sizeof(LOOKUP_TYPE)); + if (NULL =3D=3D result) { + fprintf (stderr, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } + + while (true) { + int status; + LOOKUP_TYPE *resbuf =3D NULL; + buffer =3D (char *)realloc (buffer, length); + if (NULL =3D=3D buffer) { + fprintf (stderr, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } + errno =3D 0; + status =3D REENTRANT_NAME(stream, result, buffer, + length, &resbuf); + while ((0 =3D=3Dstatus) && (resbuf =3D=3D result)) { + if (F_COMPARE) { + /* Build a result structure that can be freed by + * the shadow *_free functions. */ + LOOKUP_TYPE *ret_result =3D DUP_FUNCTION(result); + (void) fclose (stream); + free(buffer); + free(result); + return ret_result; + } else { + status =3D REENTRANT_NAME(stream, result, buffer, + length, &resbuf); + } + } + + if (ERANGE !=3D errno) { + (void) fclose (stream); + free (buffer); + free (result); + return NULL; + } + + if (length <=3D ((size_t)-1 / 4)) { + length *=3D 4; + } else if (length =3D=3D (size_t) -1) { + break; + } else { + length =3D (size_t) -1; + } + } + + (void) fclose (stream); + free(buffer); + free(result); + return NULL; + +#else /* !HAVE_FUNCTION_R */ + + /* No reentrant function. + * Duplicate the structure to avoid other call to overwrite it. + * + * We should also restore the initial structure. But that would be + * overkill. + */ + LOOKUP_TYPE *result =3D F_FUNCTION_NAME(stream); + + while (result) { + if (F_COMPARE) { + result =3D DUP_FUNCTION(result); + if (NULL =3D=3D result) { + fprintf (stderr, _("%s: out of memory\n"), + "x" STRINGIZE(FUNCTION_NAME)); + exit (13); + } + break; + } else { + result =3D F_FUNCTION_NAME(stream); + } + } + + (void) fclose (stream); + return result; +#endif +} + diff -Naur shadow-4.1.4.2.old/libmisc/xfgetgrgid.c shadow-4.1.4.2/libmisc= /xfgetgrgid.c --- shadow-4.1.4.2.old/libmisc/xfgetgrgid.c 1969-12-31 19:00:00.000000000= -0500 +++ shadow-4.1.4.2/libmisc/xfgetgrgid.c 2010-02-16 07:19:48.000000000 -05= 00 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2007 - 2009, Nicolas Fran=C3=A7ois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the copyright holders or contributors may not be used = to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR= A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1.=C2=A0Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' function= s. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this functio= n + * is likely to corrupt a pointer previously obtained by the applicatio= n. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structur= e + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provide wrapper to the getpwnam or getpwnam_r functions. + */ + +#include + +#include "groupio.h" + +#define LOOKUP_TYPE struct group +#define FUNCTION_NAME fgetgrgid +#define ARG_TYPE gid_t +#define ARG_NAME gid +#define DB_TYPE gr +#define DB_FILE GROUP_FILE +#define DUP_FUNCTION __gr_dup +#define HAVE_FUNCTION_R (defined HAVE_FGETGRENT_R) + +#include "xfgetXXbyYY.c" + diff -Naur shadow-4.1.4.2.old/libmisc/xfgetgrnam.c shadow-4.1.4.2/libmisc= /xfgetgrnam.c --- shadow-4.1.4.2.old/libmisc/xfgetgrnam.c 1969-12-31 19:00:00.000000000= -0500 +++ shadow-4.1.4.2/libmisc/xfgetgrnam.c 2010-02-16 07:19:48.000000000 -05= 00 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2007 - 2009, Nicolas Fran=C3=A7ois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the copyright holders or contributors may not be used = to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR= A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1.=C2=A0Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' function= s. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this functio= n + * is likely to corrupt a pointer previously obtained by the applicatio= n. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structur= e + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provide wrapper to the getpwnam or getpwnam_r functions. + */ + +#include + +#include "groupio.h" + +#define LOOKUP_TYPE struct group +#define FUNCTION_NAME fgetgrnam +#define ARG_TYPE const char * +#define ARG_NAME name +#define DB_TYPE gr +#define DB_FILE GROUP_FILE +#define DUP_FUNCTION __gr_dup +#define HAVE_FUNCTION_R (defined HAVE_FGETGRENT_R) + +#include "xfgetXXbyYY.c" + diff -Naur shadow-4.1.4.2.old/libmisc/xfgetpwnam.c shadow-4.1.4.2/libmisc= /xfgetpwnam.c --- shadow-4.1.4.2.old/libmisc/xfgetpwnam.c 1969-12-31 19:00:00.000000000= -0500 +++ shadow-4.1.4.2/libmisc/xfgetpwnam.c 2010-02-16 07:19:48.000000000 -05= 00 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2007 - 2009, Nicolas Fran=C3=A7ois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the copyright holders or contributors may not be used = to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR= A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1.=C2=A0Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' function= s. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this functio= n + * is likely to corrupt a pointer previously obtained by the applicatio= n. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structur= e + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provide wrapper to the getpwnam or getpwnam_r functions. + */ + +#include + +#include "pwio.h" + +#define LOOKUP_TYPE struct passwd +#define FUNCTION_NAME fgetpwnam +#define ARG_TYPE const char * +#define ARG_NAME name +#define DB_TYPE pw +#define DB_FILE PASSWD_FILE +#define DUP_FUNCTION __pw_dup +#define HAVE_FUNCTION_R (defined HAVE_FGETPWENT_R) + +#include "xfgetXXbyYY.c" + diff -Naur shadow-4.1.4.2.old/libmisc/xfgetpwuid.c shadow-4.1.4.2/libmisc= /xfgetpwuid.c --- shadow-4.1.4.2.old/libmisc/xfgetpwuid.c 1969-12-31 19:00:00.000000000= -0500 +++ shadow-4.1.4.2/libmisc/xfgetpwuid.c 2010-02-16 07:19:48.000000000 -05= 00 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2007 - 2009, Nicolas Fran=C3=A7ois + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The name of the copyright holders or contributors may not be used = to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR= A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTA= L, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * According to the Linux-PAM documentation: + * + * 4.1.=C2=A0Care about standard library calls + * + * In general, writers of authorization-granting applications should + * assume that each module is likely to call any or all 'libc' function= s. + * For 'libc' functions that return pointers to static/dynamically + * allocated structures (ie. the library allocates the memory and the + * user is not expected to 'free()' it) any module call to this functio= n + * is likely to corrupt a pointer previously obtained by the applicatio= n. + * The application programmer should either re-call such a 'libc' + * function after a call to the Linux-PAM library, or copy the structur= e + * contents to some safe area of memory before passing control to the + * Linux-PAM library. + * + * Two important function classes that fall into this category are + * getpwnam(3) and syslog(3). + * + * This file provide wrapper to the getpwnam or getpwnam_r functions. + */ + +#include + +#include "pwio.h" + +#define LOOKUP_TYPE struct passwd +#define FUNCTION_NAME fgetpwuid +#define ARG_TYPE uid_t +#define ARG_NAME uid +#define DB_TYPE pw +#define DB_FILE PASSWD_FILE +#define DUP_FUNCTION __pw_dup +#define HAVE_FUNCTION_R (defined HAVE_FGETPWENT_R) + +#include "xfgetXXbyYY.c" + diff -Naur shadow-4.1.4.2.old/man/groupadd.8 shadow-4.1.4.2/man/groupadd.= 8 --- shadow-4.1.4.2.old/man/groupadd.8 2009-07-23 21:16:24.000000000 -0400 +++ shadow-4.1.4.2/man/groupadd.8 2010-02-16 07:19:48.000000000 -0500 @@ -99,6 +99,18 @@ login\&.defs, instead of \fBGID_MIN\fR\-\fBGID_MAX\fR\&. .RE +.PP +\fB\-R\fR, \fB\-\-chroot\fR \fIROOT_DIR\fR +.RS 4 +Access files from a root directory other than /\&. +.sp +Instead of accessing or altering files from the usual directory, paths w= ill be prefixed with +\fBROOT_DIR\fR\&. +.sp +For instance, instead of adding a group to +/etc/group, the group would be added to +\fBROOT_DIR\fR/etc/group\&. +.RE .SH "CONFIGURATION" .PP The following configuration variables in diff -Naur shadow-4.1.4.2.old/man/groupadd.8.xml shadow-4.1.4.2/man/group= add.8.xml --- shadow-4.1.4.2.old/man/groupadd.8.xml 2009-05-21 08:02:13.000000000 -= 0400 +++ shadow-4.1.4.2/man/groupadd.8.xml 2010-02-16 07:19:48.000000000 -0500 @@ -179,6 +179,26 @@ + + + , + ROOT_DIR + + + + Access files from a root directory other than /. + + + Instead of accessing or altering files from the usual directory, + paths will be prefixed with . + + + For instance, instead of adding a group to + /etc/group, the group would be added to + /etc/group. + + + =20 diff -Naur shadow-4.1.4.2.old/man/useradd.8 shadow-4.1.4.2/man/useradd.8 --- shadow-4.1.4.2.old/man/useradd.8 2009-07-23 21:16:44.000000000 -0400 +++ shadow-4.1.4.2/man/useradd.8 2010-02-16 07:19:48.000000000 -0500 @@ -285,6 +285,18 @@ options if you want a home directory for a system account to be created\= &. .RE .PP +\fB\-R\fR, \fB\-\-chroot\fR \fIROOT_DIR\fR +.RS 4 +Access files from a root directory other than /\&. +.sp +Instead of accessing or altering files from the usual directory, paths w= ill be prefixed with +\fBROOT_DIR\fR\&. +.sp +For instance, instead of adding a user to +/etc/passwd, the user would be added to +\fBROOT_DIR\fR/etc/passwd\&. +.RE +.PP \fB\-s\fR, \fB\-\-shell\fR \fISHELL\fR .RS 4 The name of the user\'s login shell\&. The default is to leave this fiel= d blank, which causes the system to select the default login shell specif= ied by the diff -Naur shadow-4.1.4.2.old/man/useradd.8.xml shadow-4.1.4.2/man/userad= d.8.xml --- shadow-4.1.4.2.old/man/useradd.8.xml 2009-05-21 08:02:13.000000000 -0= 400 +++ shadow-4.1.4.2/man/useradd.8.xml 2010-02-16 07:19:48.000000000 -0500 @@ -425,6 +425,26 @@ + , + ROOT_DIR + + + + Access files from a root directory other than /. + + + Instead of accessing or altering files from the usual directory, + paths will be prefixed with . + + + For instance, instead of adding a user to + /etc/passwd, the user would be added to + /etc/passwd. + + + + + , SHELL diff -Naur shadow-4.1.4.2.old/src/groupadd.c shadow-4.1.4.2/src/groupadd.= c --- shadow-4.1.4.2.old/src/groupadd.c 2009-06-05 18:16:58.000000000 -0400 +++ shadow-4.1.4.2/src/groupadd.c 2010-02-16 08:18:58.000000000 -0500 @@ -72,6 +72,8 @@ */ char *Prog; =20 +#define VALID(s) (strcspn (s, ":\n") =3D=3D strlen (s)) + static /*@null@*/char *group_name; static gid_t group_id; static /*@null@*/char *group_passwd; @@ -81,6 +83,8 @@ static bool gflg =3D false; /* ID value for the new group */ static bool fflg =3D false; /* if group already exists, do nothing and e= xit(0) */ static bool rflg =3D false; /* create a system account */ +static bool Rflg =3D false; /* root directory offset to access files fro= m */ + static bool pflg =3D false; /* new encrypted password */ =20 #ifdef SHADOWGRP @@ -121,6 +125,7 @@ " (non-unique) GID\n"), = stderr); (void) fputs (_(" -p, --password PASSWORD use this encrypted pas= sword for the new group\n"), stderr); (void) fputs (_(" -r, --system create a system accoun= t\n"), stderr); + (void) fputs (_(" -R, --chroot ROOT_DIR access files from an a= lternate root directory\n"), stderr); (void) fputs ("\n", stderr); exit (E_USAGE); } @@ -373,6 +378,8 @@ /* * Parse the command line options. */ + int argc_saved =3D argc; + static bool parse_chroot =3D false; char *cp; int option_index =3D 0; int c; @@ -384,12 +391,35 @@ {"non-unique", no_argument, NULL, 'o'}, {"password", required_argument, NULL, 'p'}, {"system", no_argument, NULL, 'r'}, + {"chroot", required_argument, NULL, 'R'}, {NULL, 0, NULL, '\0'} }; =20 while ((c =3D - getopt_long (argc, argv, "fg:hK:op:r", long_options, + getopt_long (argc, argv, "fg:hK:op:rR:", long_options, &option_index)) !=3D -1) { + if (!parse_chroot) { + switch (c) { + case 'R': + if ((!VALID(optarg)) + || (optarg[0] !=3D '/')) { + fprintf (stderr, + _("%s: invalid root directory '%s'\n"), + Prog, optarg); + exit (E_BAD_ARG); + } + if ( chroot(optarg) !=3D 0 ) { + fprintf (stderr, + _("%s: unable to change root directory to '%s': %s\n"), + Prog, optarg, strerror (errno)); + exit (1); + } + Rflg =3D true; + break; + default: + break; + } + } else { switch (c) { case 'f': /* @@ -443,9 +473,20 @@ case 'r': rflg =3D true; break; + case 'R': + break; default: usage (); } + } + } + + /* Finished parsing for chroot flag */ + if (!parse_chroot) { + parse_chroot =3D true; + argc =3D argc_saved; + optind =3D 0; + return; } =20 /* @@ -476,8 +517,10 @@ /* * Check if the group already exist. */ - /* local, no need for xgetgrnam */ - if (getgrnam (group_name) !=3D NULL) { + /* no chroot flag, local, no need for xgetgrnam */ + if (((!Rflg) && (getgrnam (group_name) !=3D NULL)) || + /* chroot flag set, use compatible xfgetgrnam */ + ((Rflg) && (xfgetgrnam (group_name) !=3D NULL))) { /* The group already exist */ if (fflg) { /* OK, no need to do anything */ @@ -489,7 +532,8 @@ exit (E_NAME_IN_USE); } =20 - if (gflg && (getgrgid (group_id) !=3D NULL)) { + if (((gflg) && (!Rflg) && (getgrgid (group_id) !=3D NULL)) || + ((gflg) && (Rflg) && (xfgetgrgid (group_id) !=3D NULL))) { /* A GID was specified, and a group already exist with that GID * - either we will use this GID anyway (-o) * - either we ignore the specified GID and @@ -524,6 +568,8 @@ { #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM + /* chroot doesn't work with PAM libs */ + if (!Rflg) { pam_handle_t *pamh =3D NULL; int retval; struct passwd *pampw; @@ -553,6 +599,7 @@ fprintf (stderr, _("%s: PAM authentication failed\n"), Prog); exit (1); } + } #endif /* USE_PAM */ #endif /* ACCT_TOOLS_SETUID */ } @@ -579,6 +626,12 @@ OPENLOG ("groupadd"); =20 /* + * Parse the chroot option before other options + * but after opening the log. + */ + process_flags (argc, argv); + + /* * Parse the command line options. */ process_flags (argc, argv); diff -Naur shadow-4.1.4.2.old/src/useradd.c shadow-4.1.4.2/src/useradd.c --- shadow-4.1.4.2.old/src/useradd.c 2009-06-05 18:16:58.000000000 -0400 +++ shadow-4.1.4.2/src/useradd.c 2010-02-16 08:17:32.000000000 -0500 @@ -143,6 +143,7 @@ Nflg =3D false, /* do not create a group having the same name as th= e user, but add the user to def_group (or the group specified with -g) */ oflg =3D false, /* permit non-unique user ID to be specified with -= u */ rflg =3D false, /* create a system account */ + Rflg =3D false, /* root directory offset to access files from */ sflg =3D false, /* shell program for new account */ uflg =3D false, /* specify user ID for new account */ Uflg =3D false, /* create a group having the same name as the user = */ @@ -286,6 +287,7 @@ FILE *fp; char buf[1024]; char *cp; + const struct group *grp; =20 /* * Open the defaults file for reading. @@ -317,7 +319,11 @@ * Primary GROUP identifier */ if (MATCH (buf, DGROUP)) { - const struct group *grp =3D getgr_nam_gid (cp); + if (!Rflg) { + grp =3D getgr_nam_gid (cp); + } else { + grp =3D fgetgr_nam_gid (cp); + } if (NULL =3D=3D grp) { fprintf (stderr, _("%s: group '%s' does not exist\n"), @@ -618,7 +624,11 @@ * Names starting with digits are treated as numerical * GID values, otherwise the string is looked up as is. */ - grp =3D getgr_nam_gid (list); + if (!Rflg) { + grp =3D getgr_nam_gid (list); + } else { + grp =3D fgetgr_nam_gid (list); + } =20 /* * There must be a match, either by GID value or by @@ -712,6 +722,7 @@ " (non-unique) UID\n"), = stderr); (void) fputs (_(" -p, --password PASSWORD encrypted password of = the new account\n"), stderr); (void) fputs (_(" -r, --system create a system accoun= t\n"), stderr); + (void) fputs (_(" -R, --chroot ROOT_DIR access files from an a= lternate root directory\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 acc= ount\n"), stderr); (void) fputs (_(" -U, --user-group create a group with th= e same name as the user\n"), stderr); @@ -960,6 +971,8 @@ * Parse the command line options. */ int c; + int argc_saved =3D argc; + static bool parse_chroot =3D false; static struct option long_options[] =3D { {"base-dir", required_argument, NULL, 'b'}, {"comment", required_argument, NULL, 'c'}, @@ -979,6 +992,7 @@ {"non-unique", no_argument, NULL, 'o'}, {"password", required_argument, NULL, 'p'}, {"system", no_argument, NULL, 'r'}, + {"chroot", required_argument, NULL, 'R'}, {"shell", required_argument, NULL, 's'}, #ifdef WITH_SELINUX {"selinux-user", required_argument, NULL, 'Z'}, @@ -989,11 +1003,33 @@ }; while ((c =3D 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:rR:s: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:rR:s:u:U", #endif long_options, NULL)) !=3D -1) { + if (!parse_chroot) { + switch (c) { + case 'R': + if ((!VALID(optarg)) + || (optarg[0] !=3D '/')) { + fprintf (stderr, + _("%s: invalid root directory '%s'\n"), + Prog, optarg); + exit (E_BAD_ARG); + } + if ( chroot(optarg) !=3D 0 ) { + fprintf (stderr, + _("%s: unable to change root directory to '%s': %s\n"), + Prog, optarg, strerror (errno)); + fail_exit (1); + } + Rflg =3D true; + break; + default: + break; + } + } else { switch (c) { case 'b': if ( ( !VALID (optarg) ) @@ -1081,7 +1117,11 @@ fflg =3D true; break; case 'g': - grp =3D getgr_nam_gid (optarg); + if (!Rflg) { + grp =3D getgr_nam_gid (optarg); + } else { + grp =3D fgetgr_nam_gid (optarg); + } if (NULL =3D=3D grp) { fprintf (stderr, _("%s: group '%s' does not exist\n"), @@ -1159,6 +1199,8 @@ case 'r': rflg =3D true; break; + case 'R': + break; case 's': if ( ( !VALID (optarg) ) || ( ('\0' !=3D optarg[0]) @@ -1204,6 +1246,14 @@ usage (); } anyflag =3D true; + } + } + /* Finished parsing for chroot flag */ + if (!parse_chroot) { + parse_chroot =3D true; + argc =3D argc_saved; + optind =3D 0; + return; } } =20 @@ -1663,8 +1713,10 @@ * no user with this UID exists yet (entries for shared UIDs * are left unchanged). --marekm */ - /* local, no need for xgetpwuid */ - if ((!lflg) && (getpwuid (user_id) =3D=3D NULL)) { + /* no chroot flag, local, no need for xgetpwuid */ + if ((((!Rflg) && (!lflg)) && (getpwuid (user_id) =3D=3D NULL)) || + /* chroot flag set, use compatible xfgetpwuid */ + ((!lflg) && (xfgetpwuid (user_id) =3D=3D NULL))) { faillog_reset (user_id); lastlog_reset (user_id); } @@ -1806,7 +1858,11 @@ return; } =20 - gr =3D getgrnam ("mail"); /* local, no need for xgetgrnam */ + if (!Rflg) { + gr =3D getgrnam ("mail"); /* no chroot flag, local, no need for xgetg= rnam */ + } else { + gr =3D xfgetgrnam ("mail"); /* chroot flag set, use compatible xfgetg= rnam */ + } if (NULL =3D=3D gr) { fputs (_("Group 'mail' not found. Creating the user mailbox file with= 0600 mode.\n"), stderr); @@ -1861,6 +1917,12 @@ */ user_groups[0] =3D (char *) 0; =20 + /* + * Parse the chroot option before other options + * and before accessing any database files, + * but after opening the log. + */ + process_flags (argc, argv); =20 is_shadow_pwd =3D spw_file_present (); #ifdef SHADOWGRP @@ -1873,6 +1935,8 @@ =20 #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM + /* chroot doesn't work with PAM libs */ + if (!Rflg) { { struct passwd *pampw; pampw =3D getpwuid (getuid ()); /* local, no need for xgetpwuid */ @@ -1901,6 +1965,7 @@ fprintf (stderr, _("%s: PAM authentication failed\n"), Prog); fail_exit (1); } + } #endif /* USE_PAM */ #endif /* ACCT_TOOLS_SETUID */ =20 @@ -1920,7 +1985,8 @@ /* * Start with a quick check to see if the user exists. */ - if (getpwnam (user_name) !=3D NULL) { /* local, no need for xgetpwnam *= / + if (((!Rflg) && (getpwnam (user_name) !=3D NULL)) || /* no chroot flag,= local, no need for xgetpwnam */ + ((Rflg) && (xfgetpwnam (user_name) !=3D NULL))) { /* chroot flag set, = use compatible xfgetpwnam */ fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name)= ; #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1938,8 +2004,10 @@ * --bero */ if (Uflg) { - /* local, no need for xgetgrnam */ - if (getgrnam (user_name) !=3D NULL) { + /* no chroot flag, local, no need for xgetgrnam */ + if (((!Rflg) && (getgrnam (user_name) !=3D NULL)) || + /* chroot flag set, use compatible xfgetgrnam */ + ((Rflg) && (xfgetgrnam (user_name) !=3D NULL))) { fprintf (stderr, _("%s: group %s exists - if you want to add this user to tha= t group, use -g.\n"), Prog, user_name); @@ -1974,7 +2042,8 @@ fail_exit (E_UID_IN_USE); } } else { - if (getpwuid (user_id) !=3D NULL) { + if (((!Rflg) && (getpwuid (user_id) !=3D NULL)) ||=20 + ((Rflg) && (xfgetpwuid (user_id) !=3D NULL))) { fprintf (stderr, _("%s: UID %lu is not unique\n"), Prog, (unsigned long) user_id); --Boundary_(ID_ha5TfHHqr5wHwzKki9cf5w)--