From d611d54ed4c0e103ba6af8202d84fe8500bd7cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fran=C3=A7ois?= Date: Sun, 11 Aug 2013 14:54:22 +0200 Subject: [PATCH] Allow disabling of subordinate IDs. * configure.in: Add configure options --enable-subordinate-ids / --disable-subordinate-ids. Enabled by default. * lib/prototypes.h: Include before using its macros. * lib/commonio.h, lib/commonio.c: Define commonio_append only when ENABLE_SUBIDS is defined. * lib/prototypes.h, libmisc/find_new_sub_gids.c, libmisc/find_new_sub_uids.c: Likewise. * lib/subordinateio.h, lib/subordinateio.c: Likewise. * libmisc/user_busy.c: Only check if subordinate IDs are in use if ENABLE_SUBIDS is defined. * src/Makefile.am: Create newgidmap and newuidmap only if ENABLE_SUBIDS is defined. * src/newusers.c: Check for ENABLE_SUBIDS to enable support for subordinate IDs. * src/useradd.c: Likewise. * src/userdel.c: Likewise. * src/usermod.c: Likewise. * man/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1, man5/subgid.5, and man5/subuid.5 only if ENABLE_SUBIDS is defined. * man/fr/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1, man5/subgid.5, and man5/subuid.5 (not translated yet). * man/generate_mans.mak: Add xsltproc conditionals subids/no_subids. * man/login.defs.d/SUB_GID_COUNT.xml: Add dependency on subids condition. * man/login.defs.d/SUB_UID_COUNT.xml: Likewise. * man/usermod.8.xml: Document options for subordinate IDs and reference subgid(5) / subuid(5) depending on the subids condition. --- ChangeLog | 31 +++++++++++++++ configure.in | 17 ++++++++ lib/commonio.c | 2 + lib/commonio.h | 2 + lib/prototypes.h | 4 ++ lib/subordinateio.c | 7 ++++ lib/subordinateio.h | 5 +++ libmisc/find_new_sub_gids.c | 5 +++ libmisc/find_new_sub_uids.c | 5 +++ libmisc/user_busy.c | 11 +++++- man/Makefile.am | 18 +++++++-- man/fr/Makefile.am | 14 +++++++ man/generate_mans.mak | 8 +++- man/login.defs.d/SUB_GID_COUNT.xml | 2 +- man/login.defs.d/SUB_UID_COUNT.xml | 2 +- man/usermod.8.xml | 22 ++++++----- src/Makefile.am | 6 ++- src/newusers.c | 24 ++++++++++-- src/useradd.c | 33 +++++++++++++--- src/userdel.c | 20 +++++++++- src/usermod.c | 62 +++++++++++++++++++++++++----- 21 files changed, 259 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec19a818..b673a5a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2013-08-11 Nicolas François + + * configure.in: Add configure options --enable-subordinate-ids / + --disable-subordinate-ids. Enabled by default. + * lib/prototypes.h: Include before using its macros. + * lib/commonio.h, lib/commonio.c: Define commonio_append only when + ENABLE_SUBIDS is defined. + * lib/prototypes.h, libmisc/find_new_sub_gids.c, + libmisc/find_new_sub_uids.c: Likewise. + * lib/subordinateio.h, lib/subordinateio.c: Likewise. + * libmisc/user_busy.c: Only check if subordinate IDs are in use if + ENABLE_SUBIDS is defined. + * src/Makefile.am: Create newgidmap and newuidmap only if + ENABLE_SUBIDS is defined. + * src/newusers.c: Check for ENABLE_SUBIDS to enable support for + subordinate IDs. + * src/useradd.c: Likewise. + * src/userdel.c: Likewise. + * src/usermod.c: Likewise. + * man/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1, + man5/subgid.5, and man5/subuid.5 only if ENABLE_SUBIDS is defined. + * man/fr/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1, + man5/subgid.5, and man5/subuid.5 (not translated yet). + * man/generate_mans.mak: Add xsltproc conditionals + subids/no_subids. + * man/login.defs.d/SUB_GID_COUNT.xml: Add dependency on subids + condition. + * man/login.defs.d/SUB_UID_COUNT.xml: Likewise. + * man/usermod.8.xml: Document options for subordinate IDs and + reference subgid(5) / subuid(5) depending on the subids condition. + 2013-08-09 Nicolas François * libmisc/salt.c: Remove unused variable. diff --git a/configure.in b/configure.in index 30391436..d11a3649 100644 --- a/configure.in +++ b/configure.in @@ -240,6 +240,13 @@ AC_ARG_ENABLE(utmpx, [enable_utmpx="no"] ) +AC_ARG_ENABLE(subordinate-ids, + [AC_HELP_STRING([--enable-subordinate-ids], + [support subordinate ids @<:@default=yes@:>@])], + [enable_subids="${enableval}"], + [enable_subids="yes"] +) + AC_ARG_WITH(audit, [AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])], [with_audit=$withval], [with_audit=maybe]) @@ -324,6 +331,15 @@ if test "$enable_man" = "yes"; then fi AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test "x$enable_man" != "xno") +if test "$enable_subids" = "yes"; then + dnl + dnl FIXME: check if 32 bit UIDs/GIDs are supported by libc + dnl + AC_DEFINE(ENABLE_SUBIDS, 1, [Define to support the subordinate IDs.]) + enable_subids="yes" +fi +AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno") + AC_SUBST(LIBCRYPT) AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt], [AC_MSG_ERROR([crypt() not found])]) @@ -649,4 +665,5 @@ echo " shadow group support: $enable_shadowgrp" echo " S/Key support: $with_skey" echo " SHA passwords encryption: $with_sha_crypt" echo " nscd support: $with_nscd" +echo " subordinate IDs support: $enable_subids" echo diff --git a/lib/commonio.c b/lib/commonio.c index c7a9fca8..cc536bf1 100644 --- a/lib/commonio.c +++ b/lib/commonio.c @@ -1113,6 +1113,7 @@ int commonio_update (struct commonio_db *db, const void *eptr) return 1; } +#ifdef ENABLE_SUBIDS int commonio_append (struct commonio_db *db, const void *eptr) { struct commonio_entry *p; @@ -1143,6 +1144,7 @@ int commonio_append (struct commonio_db *db, const void *eptr) db->changed = true; return 1; } +#endif /* ENABLE_SUBIDS */ void commonio_del_entry (struct commonio_db *db, const struct commonio_entry *p) { diff --git a/lib/commonio.h b/lib/commonio.h index 5b49f25e..0a316f9c 100644 --- a/lib/commonio.h +++ b/lib/commonio.h @@ -146,7 +146,9 @@ extern int commonio_lock_nowait (struct commonio_db *, bool log); extern int commonio_open (struct commonio_db *, int); extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *); extern int commonio_update (struct commonio_db *, const void *); +#ifdef ENABLE_SUBIDS extern int commonio_append (struct commonio_db *, const void *); +#endif /* ENABLE_SUBIDS */ extern int commonio_remove (struct commonio_db *, const char *); extern int commonio_rewind (struct commonio_db *); extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); diff --git a/lib/prototypes.h b/lib/prototypes.h index 0503be46..7aaf1a63 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -42,6 +42,8 @@ #ifndef _PROTOTYPES_H #define _PROTOTYPES_H +#include + #include #ifdef USE_UTMPX #include @@ -149,6 +151,7 @@ extern int find_new_uid (bool sys_user, uid_t *uid, /*@null@*/uid_t const *preferred_uid); +#ifdef ENABLE_SUBIDS /* find_new_sub_gids.c */ extern int find_new_sub_gids (const char *owner, gid_t *range_start, unsigned long *range_count); @@ -156,6 +159,7 @@ extern int find_new_sub_gids (const char *owner, /* find_new_sub_uids.c */ extern int find_new_sub_uids (const char *owner, uid_t *range_start, unsigned long *range_count); +#endif /* ENABLE_SUBIDS */ /* get_gid.c */ diff --git a/lib/subordinateio.c b/lib/subordinateio.c index 27a8f4ab..4196434b 100644 --- a/lib/subordinateio.c +++ b/lib/subordinateio.c @@ -3,6 +3,9 @@ */ #include + +#ifdef ENABLE_SUBIDS + #include "prototypes.h" #include "defines.h" #include @@ -507,3 +510,7 @@ gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) start = find_free_range (&subordinate_gid_db, min, max, count); return start == ULONG_MAX ? (gid_t) -1 : start; } +#else /* !ENABLE_SUBIDS */ +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* !ENABLE_SUBIDS */ + diff --git a/lib/subordinateio.h b/lib/subordinateio.h index f27b3c0b..42aa5069 100644 --- a/lib/subordinateio.h +++ b/lib/subordinateio.h @@ -5,6 +5,10 @@ #ifndef _SUBORDINATEIO_H #define _SUBORDINATEIO_H +#include + +#ifdef ENABLE_SUBIDS + #include extern int sub_uid_close(void); @@ -34,5 +38,6 @@ extern int sub_gid_unlock (void); extern int sub_gid_add (const char *owner, gid_t start, unsigned long count); extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count); extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count); +#endif /* ENABLE_SUBIDS */ #endif diff --git a/libmisc/find_new_sub_gids.c b/libmisc/find_new_sub_gids.c index f52dda98..1b008fbe 100644 --- a/libmisc/find_new_sub_gids.c +++ b/libmisc/find_new_sub_gids.c @@ -28,6 +28,8 @@ #include +#ifdef ENABLE_SUBIDS + #include #include #include @@ -86,4 +88,7 @@ int find_new_sub_gids (const char *owner, *range_count = count; return 0; } +#else /* !ENABLE_SUBIDS */ +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* !ENABLE_SUBIDS */ diff --git a/libmisc/find_new_sub_uids.c b/libmisc/find_new_sub_uids.c index 5dfcaf25..35f5f90f 100644 --- a/libmisc/find_new_sub_uids.c +++ b/libmisc/find_new_sub_uids.c @@ -28,6 +28,8 @@ #include +#ifdef ENABLE_SUBIDS + #include #include #include @@ -86,4 +88,7 @@ int find_new_sub_uids (const char *owner, *range_count = count; return 0; } +#else /* !ENABLE_SUBIDS */ +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* !ENABLE_SUBIDS */ diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c index 04cfc319..db7174af 100644 --- a/libmisc/user_busy.c +++ b/libmisc/user_busy.c @@ -41,7 +41,9 @@ #include #include "defines.h" #include "prototypes.h" +#ifdef ENABLE_SUBIDS #include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ #ifdef __linux__ static int check_status (const char *name, const char *sname, uid_t uid); @@ -128,9 +130,12 @@ static int check_status (const char *name, const char *sname, uid_t uid) if ( (ruid == (unsigned long) uid) || (euid == (unsigned long) uid) || (suid == (unsigned long) uid) +#ifdef ENABLE_SUBIDS || have_sub_uids(name, ruid, 1) || have_sub_uids(name, euid, 1) - || have_sub_uids(name, suid, 1)) { + || have_sub_uids(name, suid, 1) +#endif /* ENABLE_SUBIDS */ + ) { (void) fclose (sfile); return 1; } @@ -158,7 +163,9 @@ static int user_busy_processes (const char *name, uid_t uid) struct stat sbroot; struct stat sbroot_process; +#ifdef ENABLE_SUBIDS sub_uid_open (O_RDONLY); +#endif /* ENABLE_SUBIDS */ proc = opendir ("/proc"); if (proc == NULL) { @@ -238,7 +245,9 @@ static int user_busy_processes (const char *name, uid_t uid) } (void) closedir (proc); +#ifdef ENABLE_SUBIDS sub_uid_close(); +#endif /* ENABLE_SUBIDS */ return 0; } #endif /* __linux__ */ diff --git a/man/Makefile.am b/man/Makefile.am index b50ca41c..307eab54 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -30,9 +30,7 @@ man_MANS = \ man1/login.1 \ man5/login.defs.5 \ man8/logoutd.8 \ - man1/newgidmap.1 \ man1/newgrp.1 \ - man1/newuidmap.1 \ man8/newusers.8 \ man8/nologin.8 \ man1/passwd.1 \ @@ -45,8 +43,6 @@ man_MANS = \ man5/shadow.5 \ man1/su.1 \ man5/suauth.5 \ - man5/subgid.5 \ - man5/subuid.5 \ man8/useradd.8 \ man8/userdel.8 \ man8/usermod.8 \ @@ -62,6 +58,16 @@ if !USE_PAM man_MANS += $(man_nopam) endif +man_subids = \ + man1/newgidmap.1 \ + man1/newuidmap.1 \ + man5/subgid.5 \ + man5/subuid.5 + +if ENABLE_SUBIDS +man_MANS += $(man_subids) +endif + man_XMANS = \ chage.1.xml \ chfn.1.xml \ @@ -187,6 +193,10 @@ if USE_PAM EXTRA_DIST += $(man_nopam) endif +if !ENABLE_SUBIDS +EXTRA_DIST += $(man_subids) +endif + generate_mans.deps: *.xml echo "# This file is generated" > $@ awk 'BEGIN{FS="\"";} /^$$/{ f=FILENAME; sub(/.xml/,"",f); print "man" substr(f, length (f)) "/" f ": " $$2 }' $(man_XMANS) >> $@ diff --git a/man/fr/Makefile.am b/man/fr/Makefile.am index c6800dc0..230d2126 100644 --- a/man/fr/Makefile.am +++ b/man/fr/Makefile.am @@ -53,6 +53,16 @@ if !USE_PAM man_MANS += $(man_nopam) endif +man_subids = \ + man1/newgidmap.1 \ + man1/newuidmap.1 \ + man5/subgid.5 \ + man5/subuid.5 + +if ENABLE_SUBIDS +man_MANS += $(man_subids) +endif + EXTRA_DIST = \ $(man_MANS) \ man1/id.1 \ @@ -62,5 +72,9 @@ if USE_PAM EXTRA_DIST += $(man_nopam) endif +if !ENABLE_SUBIDS +EXTRA_DIST += $(man_subids) +endif + include ../generate_translations.mak diff --git a/man/generate_mans.mak b/man/generate_mans.mak index 0c959c26..28694667 100644 --- a/man/generate_mans.mak +++ b/man/generate_mans.mak @@ -20,6 +20,12 @@ else SHA_CRYPT_COND=no_sha_crypt endif +if ENABLE_SUBIDS +SUBIDS_COND=subids +else +SUBIDS_COND=no_subids +endif + if ENABLE_REGENERATE_MAN %.xml-config: %.xml if grep -q SHADOW-CONFIG-HERE $<; then \ @@ -29,7 +35,7 @@ if ENABLE_REGENERATE_MAN fi man1/% man3/% man5/% man8/%: %.xml-config Makefile config.xml - $(XSLTPROC) --stringparam profile.condition "$(PAM_COND);$(SHADOWGRP_COND);$(TCB_COND);$(SHA_CRYPT_COND)" \ + $(XSLTPROC) --stringparam profile.condition "$(PAM_COND);$(SHADOWGRP_COND);$(TCB_COND);$(SHA_CRYPT_COND);$(SUBIDS_COND)" \ --param "man.authors.section.enabled" "0" \ --stringparam "man.output.base.dir" "" \ --param "man.output.in.separate.dir" "1" \ diff --git a/man/login.defs.d/SUB_GID_COUNT.xml b/man/login.defs.d/SUB_GID_COUNT.xml index 067d6196..e3ef8064 100644 --- a/man/login.defs.d/SUB_GID_COUNT.xml +++ b/man/login.defs.d/SUB_GID_COUNT.xml @@ -26,7 +26,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + (number) (number) (number) diff --git a/man/login.defs.d/SUB_UID_COUNT.xml b/man/login.defs.d/SUB_UID_COUNT.xml index 82595d35..5afd3473 100644 --- a/man/login.defs.d/SUB_UID_COUNT.xml +++ b/man/login.defs.d/SUB_UID_COUNT.xml @@ -26,7 +26,7 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - + (number) (number) (number) diff --git a/man/usermod.8.xml b/man/usermod.8.xml index 5debf568..2bfe4dda 100644 --- a/man/usermod.8.xml +++ b/man/usermod.8.xml @@ -389,7 +389,7 @@ - + , FIRST-LAST @@ -408,7 +408,7 @@ - + , FIRST-LAST @@ -429,7 +429,7 @@ - + , FIRST-LAST @@ -448,7 +448,7 @@ - + , FIRST-LAST @@ -588,12 +588,14 @@ login.defs5 , - - subgid5 - , - - subuid5 - , + + + subgid5 + , + + subuid5 + , + useradd8 , diff --git a/src/Makefile.am b/src/Makefile.am index e71ad55e..25e288d3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,8 +24,10 @@ INCLUDES = \ bin_PROGRAMS = groups login su sbin_PROGRAMS = nologin -ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd \ - newgidmap newuidmap +ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd +if ENABLE_SUBIDS +ubin_PROGRAMS += newgidmap newuidmap +endif usbin_PROGRAMS = \ chgpasswd \ chpasswd \ diff --git a/src/newusers.c b/src/newusers.c index 27300b5c..a90d04ee 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -65,7 +65,9 @@ #include "pwio.h" #include "sgroupio.h" #include "shadowio.h" +#ifdef ENABLE_SUBIDS #include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ #include "chkname.h" /* @@ -83,8 +85,6 @@ static long sha_rounds = 5000; #endif /* USE_SHA_CRYPT */ #endif /* !USE_PAM */ -static bool is_sub_uid = false; -static bool is_sub_gid = false; static bool is_shadow; #ifdef SHADOWGRP static bool is_shadow_grp; @@ -93,8 +93,12 @@ static bool sgr_locked = false; static bool pw_locked = false; static bool gr_locked = false; static bool spw_locked = false; +#ifdef ENABLE_SUBIDS +static bool is_sub_uid = false; +static bool is_sub_gid = false; static bool sub_uid_locked = false; static bool sub_gid_locked = false; +#endif /* ENABLE_SUBIDS */ /* local function prototypes */ static void usage (int status); @@ -183,6 +187,7 @@ static void fail_exit (int code) } } #endif +#ifdef ENABLE_SUBIDS if (sub_uid_locked) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -197,6 +202,7 @@ static void fail_exit (int code) /* continue */ } } +#endif /* ENABLE_SUBIDS */ exit (code); } @@ -778,6 +784,7 @@ static void open_files (void) sgr_locked = true; } #endif +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_lock () == 0) { fprintf (stderr, @@ -796,6 +803,7 @@ static void open_files (void) } sub_gid_locked = true; } +#endif /* ENABLE_SUBIDS */ if (pw_open (O_RDWR) == 0) { fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ()); @@ -815,6 +823,7 @@ static void open_files (void) fail_exit (EXIT_FAILURE); } #endif +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_open (O_RDWR) == 0) { fprintf (stderr, @@ -831,6 +840,7 @@ static void open_files (void) fail_exit (EXIT_FAILURE); } } +#endif /* ENABLE_SUBIDS */ } /* @@ -875,6 +885,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ())); fail_exit (EXIT_FAILURE); } +#ifdef ENABLE_SUBIDS if (is_sub_uid && (sub_uid_close () == 0)) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); @@ -887,6 +898,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); fail_exit (EXIT_FAILURE); } +#endif /* ENABLE_SUBIDS */ if (gr_unlock () == 0) { fprintf (stderr, @@ -916,6 +928,7 @@ static void close_files (void) sgr_locked = false; } #endif +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -932,6 +945,7 @@ static void close_files (void) } sub_gid_locked = false; } +#endif /* ENABLE_SUBIDS */ } int main (int argc, char **argv) @@ -973,8 +987,10 @@ int main (int argc, char **argv) #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif +#ifdef ENABLE_SUBIDS is_sub_uid = sub_uid_file_present (); is_sub_gid = sub_gid_file_present (); +#endif /* ENABLE_SUBIDS */ open_files (); @@ -1156,6 +1172,7 @@ int main (int argc, char **argv) continue; } +#ifdef ENABLE_SUBIDS /* * Add subordinate uids if the user does not have them. */ @@ -1175,7 +1192,7 @@ int main (int argc, char **argv) errors++; } } - + /* * Add subordinate gids if the user does not have them. */ @@ -1195,6 +1212,7 @@ int main (int argc, char **argv) errors++; } } +#endif /* ENABLE_SUBIDS */ } /* diff --git a/src/useradd.c b/src/useradd.c index 546a5c2a..0cbaa0aa 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -65,7 +65,9 @@ #include "sgroupio.h" #endif #include "shadowio.h" +#ifdef ENABLE_SUBIDS #include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ #ifdef WITH_TCB #include "tcbfuncs.h" #endif @@ -122,20 +124,22 @@ static bool is_shadow_pwd; static bool is_shadow_grp; static bool sgr_locked = false; #endif +#ifdef ENABLE_SUBIDS static bool is_sub_uid = false; static bool is_sub_gid = false; -static bool pw_locked = false; -static bool gr_locked = false; -static bool spw_locked = false; static bool sub_uid_locked = false; static bool sub_gid_locked = false; -static char **user_groups; /* NULL-terminated list */ -static long sys_ngroups; -static bool do_grp_update = false; /* group files need to be updated */ static uid_t sub_uid_start; /* New subordinate uid range */ static unsigned long sub_uid_count; static gid_t sub_gid_start; /* New subordinate gid range */ static unsigned long sub_gid_count; +#endif /* ENABLE_SUBIDS */ +static bool pw_locked = false; +static bool gr_locked = false; +static bool spw_locked = false; +static char **user_groups; /* NULL-terminated list */ +static long sys_ngroups; +static bool do_grp_update = false; /* group files need to be updated */ static bool bflg = false, /* new default root of home directory */ @@ -177,8 +181,10 @@ static bool home_added = false; #define E_GRP_UPDATE 10 /* can't update group file */ #define E_HOMEDIR 12 /* can't create home directory */ #define E_SE_UPDATE 14 /* can't update SELinux user mapping */ +#ifdef ENABLE_SUBIDS #define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */ #define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */ +#endif /* ENABLE_SUBIDS */ #define DGROUP "GROUP=" #define DHOME "HOME=" @@ -279,6 +285,7 @@ static void fail_exit (int code) } } #endif +#ifdef ENABLE_SUBIDS if (sub_uid_locked) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -305,6 +312,7 @@ static void fail_exit (int code) /* continue */ } } +#endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -1415,6 +1423,7 @@ static void close_files (void) } #endif } +#ifdef ENABLE_SUBIDS if (is_sub_uid && (sub_uid_close () == 0)) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); @@ -1427,6 +1436,7 @@ static void close_files (void) SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ())); fail_exit (E_SUB_GID_UPDATE); } +#endif /* ENABLE_SUBIDS */ if (is_shadow_pwd) { if (spw_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ()); @@ -1481,6 +1491,7 @@ static void close_files (void) sgr_locked = false; } #endif +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -1509,6 +1520,7 @@ static void close_files (void) } sub_gid_locked = false; } +#endif /* ENABLE_SUBIDS */ } /* @@ -1563,6 +1575,7 @@ static void open_files (void) } } #endif +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_lock () == 0) { fprintf (stderr, @@ -1593,6 +1606,7 @@ static void open_files (void) fail_exit (E_SUB_GID_UPDATE); } } +#endif /* ENABLE_SUBIDS */ } static void open_shadow (void) @@ -1839,6 +1853,7 @@ static void usr_update (void) #endif fail_exit (E_PW_UPDATE); } +#ifdef ENABLE_SUBIDS if (is_sub_uid && (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) { fprintf (stderr, @@ -1853,6 +1868,7 @@ static void usr_update (void) Prog, sub_uid_dbname ()); fail_exit (E_SUB_GID_UPDATE); } +#endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, Prog, @@ -2005,8 +2021,10 @@ int main (int argc, char **argv) #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif +#ifdef ENABLE_SUBIDS is_sub_uid = sub_uid_file_present (); is_sub_gid = sub_gid_file_present (); +#endif /* ENABLE_SUBIDS */ get_defaults (); @@ -2157,6 +2175,7 @@ int main (int argc, char **argv) grp_add (); } +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (find_new_sub_uids(user_name, &sub_uid_start, &sub_uid_count) < 0) { fprintf (stderr, @@ -2173,6 +2192,8 @@ int main (int argc, char **argv) fail_exit(E_SUB_GID_UPDATE); } } +#endif /* ENABLE_SUBIDS */ + usr_update (); if (mflg) { diff --git a/src/userdel.c b/src/userdel.c index 3e4ca466..19b12bc4 100644 --- a/src/userdel.c +++ b/src/userdel.c @@ -65,7 +65,9 @@ #endif /* WITH_TCB */ /*@-exitarg@*/ #include "exitcodes.h" +#ifdef ENABLE_SUBIDS #include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ /* * exit status values @@ -76,8 +78,10 @@ #define E_GRP_UPDATE 10 /* can't update group file */ #define E_HOMEDIR 12 /* can't remove home directory */ #define E_SE_UPDATE 14 /* can't update SELinux user mapping */ +#ifdef ENABLE_SUBIDS #define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */ #define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */ +#endif /* ENABLE_SUBIDS */ /* * Global variables @@ -99,13 +103,15 @@ static bool is_shadow_pwd; static bool is_shadow_grp; static bool sgr_locked = false; #endif /* SHADOWGRP */ -static bool is_sub_uid; -static bool is_sub_gid; static bool pw_locked = false; static bool gr_locked = false; static bool spw_locked = false; +#ifdef ENABLE_SUBIDS +static bool is_sub_uid; +static bool is_sub_gid; static bool sub_uid_locked = false; static bool sub_gid_locked = false; +#endif /* ENABLE_SUBIDS */ /* local function prototypes */ static void usage (int status); @@ -445,6 +451,7 @@ static void close_files (void) } #endif /* SHADOWGRP */ +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_close () == 0) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); @@ -472,6 +479,7 @@ static void close_files (void) } sub_gid_locked = false; } +#endif /* ENABLE_SUBIDS */ } /* @@ -509,6 +517,7 @@ static void fail_exit (int code) } } #endif /* SHADOWGRP */ +#ifdef ENABLE_SUBIDS if (sub_uid_locked) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -523,6 +532,7 @@ static void fail_exit (int code) /* continue */ } } +#endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, @@ -644,6 +654,7 @@ static void open_files (void) } } #endif /* SHADOWGRP */ +#ifdef ENABLE_SUBIDS if (is_sub_uid) { if (sub_uid_lock () == 0) { fprintf (stderr, @@ -696,6 +707,7 @@ static void open_files (void) fail_exit (E_SUB_GID_UPDATE); } } +#endif /* ENABLE_SUBIDS */ } /* @@ -720,6 +732,7 @@ static void update_user (void) Prog, user_name, spw_dbname ()); fail_exit (E_PW_UPDATE); } +#ifdef ENABLE_SUBIDS if (is_sub_uid && sub_uid_remove(user_name, 0, ULONG_MAX) == 0) { fprintf (stderr, _("%s: cannot remove entry %lu from %s\n"), @@ -732,6 +745,7 @@ static void update_user (void) Prog, (unsigned long)user_id, sub_gid_dbname ()); fail_exit (E_SUB_GID_UPDATE); } +#endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_DEL_USER, Prog, "deleting user entries", @@ -1079,8 +1093,10 @@ int main (int argc, char **argv) #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif /* SHADOWGRP */ +#ifdef ENABLE_SUBIDS is_sub_uid = sub_uid_file_present (); is_sub_gid = sub_gid_file_present (); +#endif /* ENABLE_SUBIDS */ /* * Start with a quick check to see if the user exists. diff --git a/src/usermod.c b/src/usermod.c index 5cf45fd5..250ac1a7 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -63,7 +63,9 @@ #include "sgroupio.h" #endif #include "shadowio.h" +#ifdef ENABLE_SUBIDS #include "subordinateio.h" +#endif /* ENABLE_SUBIDS */ #ifdef WITH_TCB #include "tcbfuncs.h" #endif @@ -87,9 +89,13 @@ /* #define E_NOSPACE 11 insufficient space to move home dir */ #define E_HOMEDIR 12 /* unable to complete home dir move */ #define E_SE_UPDATE 13 /* can't update SELinux user mapping */ +#ifdef ENABLE_SUBIDS #define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */ #define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */ +#endif /* ENABLE_SUBIDS */ + #define VALID(s) (strcspn (s, ":\n") == strlen (s)) + /* * Global variables */ @@ -135,12 +141,14 @@ static bool #ifdef WITH_SELINUX Zflg = false, /* new selinux user */ #endif - uflg = false, /* specify new user ID */ - Uflg = false, /* unlock the password */ +#ifdef ENABLE_SUBIDS vflg = false, /* add subordinate uids */ Vflg = false, /* delete subordinate uids */ wflg = false, /* add subordinate gids */ - Wflg = false; /* delete subordinate gids */ + Wflg = false, /* delete subordinate gids */ +#endif /* ENABLE_SUBIDS */ + uflg = false, /* specify new user ID */ + Uflg = false; /* unlock the password */ static bool is_shadow_pwd; @@ -148,8 +156,10 @@ static bool is_shadow_pwd; static bool is_shadow_grp; #endif +#ifdef ENABLE_SUBIDS static bool is_sub_uid = false; static bool is_sub_gid = false; +#endif /* ENABLE_SUBIDS */ static bool pw_locked = false; static bool spw_locked = false; @@ -157,8 +167,10 @@ static bool gr_locked = false; #ifdef SHADOWGRP static bool sgr_locked = false; #endif +#ifdef ENABLE_SUBIDS static bool sub_uid_locked = false; static bool sub_gid_locked = false; +#endif /* ENABLE_SUBIDS */ /* local function prototypes */ @@ -314,6 +326,7 @@ static int get_groups (char *list) return 0; } +#ifdef ENABLE_SUBIDS struct ulong_range { unsigned long first; @@ -376,6 +389,7 @@ static int prepend_range(const char *str, struct ulong_range_list_entry **head) *head = entry; return 1; } +#endif /* ENABLE_SUBIDS */ /* * usage - display usage message and exit @@ -409,10 +423,12 @@ static /*@noreturn@*/void usage (int status) (void) fputs (_(" -s, --shell SHELL new login shell for the user account\n"), usageout); (void) fputs (_(" -u, --uid UID new UID for the user account\n"), usageout); (void) fputs (_(" -U, --unlock unlock the user account\n"), usageout); +#ifdef ENABLE_SUBIDS (void) fputs (_(" -v, --add-subuids FIRST-LAST add range of subordinate uids\n"), usageout); (void) fputs (_(" -V, --del-subuids FIRST-LAST remove range of subordinate uids\n"), usageout); (void) fputs (_(" -w, --add-subgids FIRST-LAST add range of subordinate gids\n"), usageout); (void) fputs (_(" -W, --del-subgids FIRST-LAST remove range of subordinate gids\n"), usageout); +#endif /* ENABLE_SUBIDS */ #ifdef WITH_SELINUX (void) fputs (_(" -Z, --selinux-user SEUSER new SELinux user mapping for the user account\n"), usageout); #endif /* WITH_SELINUX */ @@ -669,6 +685,7 @@ static /*@noreturn@*/void fail_exit (int code) /* continue */ } } +#ifdef ENABLE_SUBIDS if (sub_uid_locked) { if (sub_uid_unlock () == 0) { fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ()); @@ -683,6 +700,7 @@ static /*@noreturn@*/void fail_exit (int code) /* continue */ } } +#endif /* ENABLE_SUBIDS */ #ifdef WITH_AUDIT audit_logger (AUDIT_USER_CHAUTHTOK, Prog, @@ -982,22 +1000,26 @@ static void process_flags (int argc, char **argv) {"shell", required_argument, NULL, 's'}, {"uid", required_argument, NULL, 'u'}, {"unlock", no_argument, NULL, 'U'}, +#ifdef ENABLE_SUBIDS {"add-subuids", required_argument, NULL, 'v'}, {"del-subuids", required_argument, NULL, 'V'}, {"add-subgids", required_argument, NULL, 'w'}, {"del-subgids", required_argument, NULL, 'W'}, +#endif /* ENABLE_SUBIDS */ #ifdef WITH_SELINUX {"selinux-user", required_argument, NULL, 'Z'}, #endif /* WITH_SELINUX */ {NULL, 0, NULL, '\0'} }; while ((c = getopt_long (argc, argv, + "ac:d:e:f:g:G:hl:Lmop:R:s:u:U" +#ifdef ENABLE_SUBIDS + "v:w:V:W:" +#endif /* ENABLE_SUBIDS */ #ifdef WITH_SELINUX - "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:v:w:V:W:", -#else /* !WITH_SELINUX */ - "ac:d:e:f:g:G:hl:Lmop:R:s:u:Uv:w:V:W:", -#endif /* !WITH_SELINUX */ - long_options, NULL)) != -1) { + "Z:" +#endif /* WITH_SELINUX */ + , long_options, NULL)) != -1) { switch (c) { case 'a': aflg = true; @@ -1115,6 +1137,7 @@ static void process_flags (int argc, char **argv) case 'U': Uflg = true; break; +#ifdef ENABLE_SUBIDS case 'v': if (prepend_range (optarg, &add_sub_uids) == 0) { fprintf (stderr, @@ -1151,6 +1174,7 @@ static void process_flags (int argc, char **argv) } Wflg = true; break; +#endif /* ENABLE_SUBIDS */ #ifdef WITH_SELINUX case 'Z': if (is_selinux_enabled () > 0) { @@ -1303,7 +1327,9 @@ static void process_flags (int argc, char **argv) if (!(Uflg || uflg || sflg || pflg || mflg || Lflg || lflg || Gflg || gflg || fflg || eflg || dflg || cflg +#ifdef ENABLE_SUBIDS || vflg || Vflg || wflg || Wflg +#endif /* ENABLE_SUBIDS */ #ifdef WITH_SELINUX || Zflg #endif /* WITH_SELINUX */ @@ -1435,6 +1461,7 @@ static void close_files (void) sgr_locked = false; #endif +#ifdef ENABLE_SUBIDS if (vflg || Vflg) { if (!is_sub_uid || (sub_uid_close () == 0)) { fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ()); @@ -1461,6 +1488,7 @@ static void close_files (void) } sub_gid_locked = false; } +#endif /* ENABLE_SUBIDS */ /* * Close the DBM and/or flat files @@ -1541,6 +1569,7 @@ static void open_files (void) } #endif } +#ifdef ENABLE_SUBIDS if (vflg || Vflg) { if (!is_sub_uid || (sub_uid_lock () == 0)) { fprintf (stderr, @@ -1571,6 +1600,7 @@ static void open_files (void) fail_exit (E_SUB_GID_UPDATE); } } +#endif /* ENABLE_SUBIDS */ } /* @@ -1672,6 +1702,7 @@ static void usr_update (void) fail_exit (E_PW_UPDATE); } } +#ifdef ENABLE_SUBIDS if (Vflg) { struct ulong_range_list_entry *ptr; for (ptr = del_sub_uids; ptr != NULL; ptr = ptr->next) { @@ -1724,6 +1755,7 @@ static void usr_update (void) } } } +#endif /* ENABLE_SUBIDS */ } /* @@ -2059,8 +2091,10 @@ int main (int argc, char **argv) #ifdef SHADOWGRP is_shadow_grp = sgr_file_present (); #endif +#ifdef ENABLE_SUBIDS is_sub_uid = sub_uid_file_present (); is_sub_gid = sub_gid_file_present (); +#endif /* ENABLE_SUBIDS */ process_flags (argc, argv); @@ -2068,7 +2102,11 @@ int main (int argc, char **argv) * The home directory, the username and the user's UID should not * be changed while the user is logged in. */ - if ( (uflg || lflg || dflg || Vflg || Wflg) + if ( (uflg || lflg || dflg +#ifdef ENABLE_SUBIDS + || Vflg || Wflg +#endif /* ENABLE_SUBIDS */ + ) && (user_busy (user_name, user_id) != 0)) { exit (E_USER_BUSY); } @@ -2121,7 +2159,11 @@ int main (int argc, char **argv) */ open_files (); if ( cflg || dflg || eflg || fflg || gflg || Lflg || lflg || pflg - || sflg || uflg || Uflg || vflg || Vflg || wflg || Wflg) { + || sflg || uflg || Uflg +#ifdef ENABLE_SUBIDS + || vflg || Vflg || wflg || Wflg +#endif /* ENABLE_SUBIDS */ + ) { usr_update (); } if (Gflg || lflg) {