New upstream version 4.15.1

This commit is contained in:
Chris Hofstaedtler
2024-06-13 03:08:44 +02:00
parent 3987cc7880
commit f7f4fd7c05
759 changed files with 53132 additions and 39788 deletions
+18 -24
View File
@@ -9,9 +9,11 @@ sgidperms = 2755
AM_CPPFLAGS = \
-I${top_srcdir}/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-DLOCALEDIR=\"$(datadir)/locale\"
-DLOCALEDIR=\"$(datadir)/locale\" \
$(ECONF_CPPFLAGS)
AM_CFLAGS = $(LIBBSD_CFLAGS)
# XXX why are login and su in /bin anyway (other than for
# historical reasons)?
@@ -26,10 +28,13 @@ AM_CPPFLAGS = \
bin_PROGRAMS = groups login
sbin_PROGRAMS = nologin
ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
ubin_PROGRAMS = faillog chage chfn chsh expiry gpasswd newgrp passwd
if ENABLE_SUBIDS
ubin_PROGRAMS += newgidmap newuidmap
endif
if ENABLE_LASTLOG
ubin_PROGRAMS += lastlog
endif
if WITH_SU
bin_PROGRAMS += su
endif
@@ -79,7 +84,6 @@ shadowsgidubins = passwd
endif
LDADD = $(INTLLIBS) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la \
$(LIBTCB)
@@ -95,13 +99,13 @@ else
LIBCRYPT_NOPAM = $(LIBCRYPT)
endif
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
expiry_LDADD = $(LDADD) $(LIBECONF)
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
@@ -115,18 +119,18 @@ lastlog_LDADD = $(LDADD) $(LIBAUDIT) $(LIBECONF)
login_SOURCES = \
login.c \
login_nopam.c
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF)
newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
nologin_LDADD =
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF)
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl
pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
pwconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
su_SOURCES = \
su.c \
suauth.c
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF)
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
@@ -177,59 +181,49 @@ MISCLIBS = \
getsubids_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS) -ldl
getsubids_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-I$(top_srcdir)/libsubid
-I$(top_builddir)/libsubid
get_subid_owners_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS) -ldl
get_subid_owners_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-I$(top_srcdir)/libsubid
-I$(top_builddir)/libsubid
new_subid_range_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-I$(top_srcdir)/libsubid
-I$(top_builddir)/libsubid
new_subid_range_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS) -ldl
free_subid_range_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-I$(top_srcdir)/libsubid
-I$(top_builddir)/libsubid
free_subid_range_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS) -ldl
check_subid_range_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir) \
-I$(top_srcdir)/libmisc
-I$(top_srcdir)
check_subid_range_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.la \
$(MISCLIBS) -ldl
endif
+56 -58
View File
@@ -91,11 +91,12 @@ host_triplet = @host@
bin_PROGRAMS = groups$(EXEEXT) login$(EXEEXT) $(am__EXEEXT_1) \
$(am__EXEEXT_2)
sbin_PROGRAMS = nologin$(EXEEXT)
ubin_PROGRAMS = faillog$(EXEEXT) lastlog$(EXEEXT) chage$(EXEEXT) \
chfn$(EXEEXT) chsh$(EXEEXT) expiry$(EXEEXT) gpasswd$(EXEEXT) \
newgrp$(EXEEXT) passwd$(EXEEXT) $(am__EXEEXT_4)
ubin_PROGRAMS = faillog$(EXEEXT) chage$(EXEEXT) chfn$(EXEEXT) \
chsh$(EXEEXT) expiry$(EXEEXT) gpasswd$(EXEEXT) newgrp$(EXEEXT) \
passwd$(EXEEXT) $(am__EXEEXT_4) $(am__EXEEXT_5)
@ENABLE_SUBIDS_TRUE@am__append_1 = newgidmap newuidmap
@WITH_SU_TRUE@am__append_2 = su
@ENABLE_LASTLOG_TRUE@am__append_2 = lastlog
@WITH_SU_TRUE@am__append_3 = su
usbin_PROGRAMS = chgpasswd$(EXEEXT) chpasswd$(EXEEXT) \
groupadd$(EXEEXT) groupdel$(EXEEXT) groupmems$(EXEEXT) \
groupmod$(EXEEXT) grpck$(EXEEXT) grpconv$(EXEEXT) \
@@ -104,12 +105,12 @@ usbin_PROGRAMS = chgpasswd$(EXEEXT) chpasswd$(EXEEXT) \
useradd$(EXEEXT) userdel$(EXEEXT) usermod$(EXEEXT) \
vipw$(EXEEXT)
noinst_PROGRAMS = id$(EXEEXT) sulogin$(EXEEXT) $(am__EXEEXT_3)
@WITH_SU_TRUE@am__append_3 = su
@WITH_TCB_FALSE@am__append_4 = passwd
@ACCT_TOOLS_SETUID_TRUE@am__append_5 = chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
@ENABLE_SUBIDS_TRUE@@FCAPS_FALSE@am__append_6 = newgidmap newuidmap
@ENABLE_SUBIDS_TRUE@am__append_7 = getsubids
@ENABLE_SUBIDS_TRUE@am__append_8 = get_subid_owners \
@WITH_SU_TRUE@am__append_4 = su
@WITH_TCB_FALSE@am__append_5 = passwd
@ACCT_TOOLS_SETUID_TRUE@am__append_6 = chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
@ENABLE_SUBIDS_TRUE@@FCAPS_FALSE@am__append_7 = newgidmap newuidmap
@ENABLE_SUBIDS_TRUE@am__append_8 = getsubids
@ENABLE_SUBIDS_TRUE@am__append_9 = get_subid_owners \
@ENABLE_SUBIDS_TRUE@ new_subid_range \
@ENABLE_SUBIDS_TRUE@ free_subid_range \
@ENABLE_SUBIDS_TRUE@ check_subid_range
@@ -142,13 +143,13 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
@ENABLE_SUBIDS_TRUE@ check_subid_range$(EXEEXT)
@ENABLE_SUBIDS_TRUE@am__EXEEXT_4 = newgidmap$(EXEEXT) \
@ENABLE_SUBIDS_TRUE@ newuidmap$(EXEEXT)
@ENABLE_LASTLOG_TRUE@am__EXEEXT_5 = lastlog$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) \
$(ubin_PROGRAMS) $(usbin_PROGRAMS)
chage_SOURCES = chage.c
chage_OBJECTS = chage.$(OBJEXT)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la $(am__DEPENDENCIES_1)
@ACCT_TOOLS_SETUID_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1)
chage_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \
@@ -173,7 +174,6 @@ check_subid_range_OBJECTS = \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_1)
@ENABLE_SUBIDS_TRUE@check_subid_range_DEPENDENCIES = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_5)
chfn_SOURCES = chfn.c
chfn_OBJECTS = chfn.$(OBJEXT)
@@ -204,14 +204,12 @@ faillog_SOURCES = faillog.c
faillog_OBJECTS = faillog.$(OBJEXT)
faillog_LDADD = $(LDADD)
faillog_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la $(am__DEPENDENCIES_1)
free_subid_range_SOURCES = free_subid_range.c
free_subid_range_OBJECTS = \
free_subid_range-free_subid_range.$(OBJEXT)
@ENABLE_SUBIDS_TRUE@free_subid_range_DEPENDENCIES = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_5)
get_subid_owners_SOURCES = get_subid_owners.c
@@ -219,14 +217,12 @@ get_subid_owners_OBJECTS = \
get_subid_owners-get_subid_owners.$(OBJEXT)
@ENABLE_SUBIDS_TRUE@get_subid_owners_DEPENDENCIES = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_5)
getsubids_SOURCES = getsubids.c
getsubids_OBJECTS = getsubids-getsubids.$(OBJEXT)
@ENABLE_SUBIDS_TRUE@getsubids_DEPENDENCIES = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_5)
gpasswd_SOURCES = gpasswd.c
@@ -258,7 +254,6 @@ groups_SOURCES = groups.c
groups_OBJECTS = groups.$(OBJEXT)
groups_LDADD = $(LDADD)
groups_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la $(am__DEPENDENCIES_1)
grpck_SOURCES = grpck.c
grpck_OBJECTS = grpck.$(OBJEXT)
@@ -276,7 +271,6 @@ id_SOURCES = id.c
id_OBJECTS = id.$(OBJEXT)
id_LDADD = $(LDADD)
id_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la $(am__DEPENDENCIES_1)
lastlog_SOURCES = lastlog.c
lastlog_OBJECTS = lastlog.$(OBJEXT)
@@ -287,18 +281,16 @@ login_OBJECTS = $(am_login_OBJECTS)
login_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
logoutd_SOURCES = logoutd.c
logoutd_OBJECTS = logoutd.$(OBJEXT)
logoutd_LDADD = $(LDADD)
logoutd_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la $(am__DEPENDENCIES_1)
new_subid_range_SOURCES = new_subid_range.c
new_subid_range_OBJECTS = new_subid_range-new_subid_range.$(OBJEXT)
@ENABLE_SUBIDS_TRUE@new_subid_range_DEPENDENCIES = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(am__DEPENDENCIES_5)
newgidmap_SOURCES = newgidmap.c
@@ -325,8 +317,7 @@ passwd_SOURCES = passwd.c
passwd_OBJECTS = passwd.$(OBJEXT)
passwd_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) \
$(am__DEPENDENCIES_1)
$(am__DEPENDENCIES_4) $(am__DEPENDENCIES_1)
pwck_SOURCES = pwck.c
pwck_OBJECTS = pwck.$(OBJEXT)
pwck_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
@@ -344,7 +335,7 @@ su_OBJECTS = $(am_su_OBJECTS)
su_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
sulogin_SOURCES = sulogin.c
sulogin_OBJECTS = sulogin.$(OBJEXT)
sulogin_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
@@ -478,6 +469,8 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
@@ -511,9 +504,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -529,6 +528,7 @@ LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
@@ -537,6 +537,8 @@ LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -559,6 +561,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -639,17 +644,17 @@ suidperms = 4755
sgidperms = 2755
AM_CPPFLAGS = \
-I${top_srcdir}/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir) \
-DLOCALEDIR=\"$(datadir)/locale\"
-DLOCALEDIR=\"$(datadir)/locale\" \
$(ECONF_CPPFLAGS)
suidusbins = $(am__append_5)
suidbins = $(am__append_3)
suidubins = chage chfn chsh expiry gpasswd newgrp $(am__append_4) \
$(am__append_6)
AM_CFLAGS = $(LIBBSD_CFLAGS)
suidusbins = $(am__append_6)
suidbins = $(am__append_4)
suidubins = chage chfn chsh expiry gpasswd newgrp $(am__append_5) \
$(am__append_7)
@WITH_TCB_TRUE@shadowsgidubins = passwd
LDADD = $(INTLLIBS) \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la \
$(LIBTCB)
@@ -657,13 +662,13 @@ LDADD = $(INTLLIBS) \
@ACCT_TOOLS_SETUID_TRUE@LIBPAM_SUID = $(LIBPAM)
@USE_PAM_FALSE@LIBCRYPT_NOPAM = $(LIBCRYPT)
@USE_PAM_TRUE@LIBCRYPT_NOPAM =
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
expiry_LDADD = $(LDADD) $(LIBECONF)
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
@@ -678,11 +683,11 @@ login_SOURCES = \
login.c \
login_nopam.c
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
newgrp_LDADD = $(LDADD) $(LIBAUDIT) $(LIBCRYPT) $(LIBECONF)
newusers_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
nologin_LDADD =
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF)
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBECONF) -ldl
pwck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
pwconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
pwunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
@@ -690,7 +695,7 @@ su_SOURCES = \
su.c \
suauth.c
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF)
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
@@ -709,60 +714,50 @@ vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
@ENABLE_SUBIDS_TRUE@getsubids_LDADD = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(MISCLIBS) -ldl
@ENABLE_SUBIDS_TRUE@getsubids_CPPFLAGS = \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/lib \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libmisc \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir) \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libsubid
@ENABLE_SUBIDS_TRUE@ -I$(top_builddir)/libsubid
@ENABLE_SUBIDS_TRUE@get_subid_owners_LDADD = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(MISCLIBS) -ldl
@ENABLE_SUBIDS_TRUE@get_subid_owners_CPPFLAGS = \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/lib \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libmisc \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir) \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libsubid
@ENABLE_SUBIDS_TRUE@ -I$(top_builddir)/libsubid
@ENABLE_SUBIDS_TRUE@new_subid_range_CPPFLAGS = \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/lib \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libmisc \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir) \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libsubid
@ENABLE_SUBIDS_TRUE@ -I$(top_builddir)/libsubid
@ENABLE_SUBIDS_TRUE@new_subid_range_LDADD = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(MISCLIBS) -ldl
@ENABLE_SUBIDS_TRUE@free_subid_range_CPPFLAGS = \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/lib \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libmisc \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir) \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libsubid
@ENABLE_SUBIDS_TRUE@ -I$(top_builddir)/libsubid
@ENABLE_SUBIDS_TRUE@free_subid_range_LDADD = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libsubid/libsubid.la \
@ENABLE_SUBIDS_TRUE@ $(MISCLIBS) -ldl
@ENABLE_SUBIDS_TRUE@check_subid_range_CPPFLAGS = \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/lib \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir) \
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)/libmisc
@ENABLE_SUBIDS_TRUE@ -I$(top_srcdir)
@ENABLE_SUBIDS_TRUE@check_subid_range_LDADD = \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/lib/libshadow.la \
@ENABLE_SUBIDS_TRUE@ $(top_builddir)/libmisc/libmisc.la \
@ENABLE_SUBIDS_TRUE@ $(MISCLIBS) -ldl
all: all-am
@@ -1220,22 +1215,25 @@ $(am__depfiles_remade):
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+101 -87
View File
@@ -25,21 +25,30 @@
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include <pwd.h>
#include "prototypes.h"
#include "alloc.h"
#include "defines.h"
#include "memzero.h"
#include "prototypes.h"
#include "pwio.h"
#include "shadowio.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/strftime.h"
#include "string/strtcpy.h"
#include "time/day_to_str.h"
/*@-exitarg@*/
#include "exitcodes.h"
#ifdef WITH_TCB
#include "tcbfuncs.h"
#endif
/*@-exitarg@*/
#include "exitcodes.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "chage";
static bool
dflg = false, /* set last password change date */
@@ -52,6 +61,8 @@ static bool
Wflg = false; /* set expiration warning days */
static bool amroot = false;
static const char *prefix = "";
static bool pw_locked = false; /* Indicate if the password file is locked */
static bool spw_locked = false; /* Indicate if the shadow file is locked */
/* The name and UID of the user being worked on */
@@ -66,21 +77,23 @@ static long inactdays;
static long expdate;
/* local function prototypes */
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static int new_fields (void);
static void print_date (time_t date);
static void print_day_as_date (long day);
static void list_fields (void);
static void process_flags (int argc, char **argv);
static void check_flags (int argc, int opt_index);
static void check_perms (void);
static void open_files (bool readonly);
static void close_files (void);
static /*@noreturn@*/void fail_exit (int code);
NORETURN static void fail_exit (int code);
/*
* fail_exit - do some cleanup and exit with the given error code
*/
static /*@noreturn@*/void fail_exit (int code)
NORETURN
static void
fail_exit (int code)
{
if (spw_locked) {
if (spw_unlock () == 0) {
@@ -101,8 +114,7 @@ static /*@noreturn@*/void fail_exit (int code)
#ifdef WITH_AUDIT
if (E_SUCCESS != code) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change age",
user_name, (unsigned int) user_uid, 0);
"change age", user_name, user_uid, 0);
}
#endif
@@ -112,7 +124,9 @@ static /*@noreturn@*/void fail_exit (int code)
/*
* usage - print command line syntax and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -132,6 +146,7 @@ static /*@noreturn@*/void usage (int status)
(void) fputs (_(" -M, --maxdays MAX_DAYS set maximum number of days before password\n"
" change to MAX_DAYS\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
(void) fputs (_(" -W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout);
(void) fputs ("\n", usageout);
exit (status);
@@ -148,30 +163,29 @@ static /*@noreturn@*/void usage (int status)
*/
static int new_fields (void)
{
char buf[200];
char buf[200];
(void) puts (_("Enter the new value, or press ENTER for the default"));
(void) puts ("");
(void) snprintf (buf, sizeof buf, "%ld", mindays);
SNPRINTF(buf, "%ld", mindays);
change_field (buf, sizeof buf, _("Minimum Password Age"));
if ( (getlong (buf, &mindays) == 0)
if ( (getlong(buf, &mindays) == -1)
|| (mindays < -1)) {
return 0;
}
(void) snprintf (buf, sizeof buf, "%ld", maxdays);
SNPRINTF(buf, "%ld", maxdays);
change_field (buf, sizeof buf, _("Maximum Password Age"));
if ( (getlong (buf, &maxdays) == 0)
if ( (getlong(buf, &maxdays) == -1)
|| (maxdays < -1)) {
return 0;
}
if (-1 == lstchgdate || lstchgdate > LONG_MAX / SCALE) {
strcpy (buf, "-1");
} else {
date_to_str (sizeof(buf), buf, lstchgdate * SCALE);
}
if (-1 == lstchgdate || lstchgdate > LONG_MAX / DAY)
strcpy(buf, "-1");
else
DAY_TO_STR(buf, lstchgdate);
change_field (buf, sizeof buf, _("Last Password Change (YYYY-MM-DD)"));
@@ -184,25 +198,24 @@ static int new_fields (void)
}
}
(void) snprintf (buf, sizeof buf, "%ld", warndays);
SNPRINTF(buf, "%ld", warndays);
change_field (buf, sizeof buf, _("Password Expiration Warning"));
if ( (getlong (buf, &warndays) == 0)
if ( (getlong(buf, &warndays) == -1)
|| (warndays < -1)) {
return 0;
}
(void) snprintf (buf, sizeof buf, "%ld", inactdays);
SNPRINTF(buf, "%ld", inactdays);
change_field (buf, sizeof buf, _("Password Inactive"));
if ( (getlong (buf, &inactdays) == 0)
if ( (getlong(buf, &inactdays) == -1)
|| (inactdays < -1)) {
return 0;
}
if (-1 == expdate || LONG_MAX / SCALE < expdate) {
strcpy (buf, "-1");
} else {
date_to_str (sizeof(buf), buf, expdate * SCALE);
}
if (-1 == expdate || LONG_MAX / DAY < expdate)
strcpy(buf, "-1");
else
DAY_TO_STR(buf, expdate);
change_field (buf, sizeof buf,
_("Account Expiration Date (YYYY-MM-DD)"));
@@ -219,20 +232,33 @@ static int new_fields (void)
return 1;
}
static void print_date (time_t date)
{
struct tm *tp;
char buf[80];
tp = gmtime (&date);
if (NULL == tp) {
(void) printf ("time_t: %lu\n", (unsigned long)date);
} else {
(void) strftime (buf, sizeof buf, iflg ? "%Y-%m-%d" : "%b %d, %Y", tp);
(void) puts (buf);
static void
print_day_as_date(long day)
{
char buf[80];
time_t date;
struct tm tm;
if (day < 0) {
puts(_("never"));
return;
}
if (__builtin_mul_overflow(day, DAY, &date)) {
puts(_("future"));
return;
}
if (gmtime_r(&date, &tm) == NULL) {
(void) printf ("time_t: %lu\n", (unsigned long)date);
return;
}
STRFTIME(buf, iflg ? "%Y-%m-%d" : "%b %d, %Y", &tm);
(void) puts (buf);
}
/*
* list_fields - display the current values of the expiration fields
*
@@ -242,21 +268,15 @@ static void print_date (time_t date)
*/
static void list_fields (void)
{
long changed = 0;
long expires;
/*
* The "last change" date is either "never" or the date the password
* was last modified. The date is the number of days since 1/1/1970.
*/
(void) fputs (_("Last password change\t\t\t\t\t: "), stdout);
if (lstchgdate < 0 || lstchgdate > LONG_MAX / SCALE) {
(void) puts (_("never"));
} else if (lstchgdate == 0) {
if (lstchgdate == 0) {
(void) puts (_("password must be changed"));
} else {
changed = lstchgdate * SCALE;
print_date ((time_t) changed);
print_day_as_date(lstchgdate);
}
/*
@@ -267,13 +287,13 @@ static void list_fields (void)
if (lstchgdate == 0) {
(void) puts (_("password must be changed"));
} else if ( (lstchgdate < 0)
|| (maxdays >= (10000 * (DAY / SCALE)))
|| (maxdays >= 10000)
|| (maxdays < 0)
|| ((LONG_MAX - changed) / SCALE < maxdays)) {
|| (LONG_MAX - lstchgdate < maxdays))
{
(void) puts (_("never"));
} else {
expires = changed + maxdays * SCALE;
print_date ((time_t) expires);
print_day_as_date(lstchgdate + maxdays);
}
/*
@@ -287,14 +307,14 @@ static void list_fields (void)
(void) puts (_("password must be changed"));
} else if ( (lstchgdate < 0)
|| (inactdays < 0)
|| (maxdays >= (10000 * (DAY / SCALE)))
|| (maxdays >= 10000)
|| (maxdays < 0)
|| (maxdays > LONG_MAX - inactdays)
|| ((LONG_MAX - changed) / SCALE < maxdays + inactdays)) {
|| (LONG_MAX - inactdays < maxdays)
|| (LONG_MAX - lstchgdate < maxdays + inactdays))
{
(void) puts (_("never"));
} else {
expires = changed + (maxdays + inactdays) * SCALE;
print_date ((time_t) expires);
print_day_as_date(lstchgdate + maxdays + inactdays);
}
/*
@@ -302,12 +322,7 @@ static void list_fields (void)
* password expiring or not.
*/
(void) fputs (_("Account expires\t\t\t\t\t\t: "), stdout);
if (expdate < 0 || LONG_MAX / SCALE < expdate) {
(void) puts (_("never"));
} else {
expires = expdate * SCALE;
print_date ((time_t) expires);
}
print_day_as_date(expdate);
/*
* Start with the easy numbers - the number of days before the
@@ -344,12 +359,13 @@ static void process_flags (int argc, char **argv)
{"mindays", required_argument, NULL, 'm'},
{"maxdays", required_argument, NULL, 'M'},
{"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{"warndays", required_argument, NULL, 'W'},
{"iso8601", no_argument, NULL, 'i'},
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv, "d:E:hiI:lm:M:R:W:",
while ((c = getopt_long (argc, argv, "d:E:hiI:lm:M:R:P:W:",
long_options, NULL)) != -1) {
switch (c) {
case 'd':
@@ -380,7 +396,7 @@ static void process_flags (int argc, char **argv)
break;
case 'I':
Iflg = true;
if ( (getlong (optarg, &inactdays) == 0)
if ( (getlong(optarg, &inactdays) == -1)
|| (inactdays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -393,7 +409,7 @@ static void process_flags (int argc, char **argv)
break;
case 'm':
mflg = true;
if ( (getlong (optarg, &mindays) == 0)
if ( (getlong(optarg, &mindays) == -1)
|| (mindays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -403,7 +419,7 @@ static void process_flags (int argc, char **argv)
break;
case 'M':
Mflg = true;
if ( (getlong (optarg, &maxdays) == 0)
if ( (getlong(optarg, &maxdays) == -1)
|| (maxdays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -413,9 +429,11 @@ static void process_flags (int argc, char **argv)
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
case 'W':
Wflg = true;
if ( (getlong (optarg, &warndays) == 0)
if ( (getlong(optarg, &warndays) == -1)
|| (warndays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -500,7 +518,7 @@ static void check_perms (void)
exit (E_NOPERM);
}
retval = pam_start ("chage", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -751,24 +769,23 @@ int main (int argc, char **argv)
gid_t rgid;
const struct passwd *pw;
/*
* Get the program name so that error messages can use it.
*/
Prog = Basename (argv[0]);
sanitize_env ();
check_fds ();
log_set_progname(Prog);
log_set_logfd(stderr);
sanitize_env ();
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
#ifdef WITH_AUDIT
audit_help_open ();
#endif
OPENLOG ("chage");
OPENLOG (Prog);
ruid = getuid ();
rgid = getgid ();
@@ -809,7 +826,7 @@ int main (int argc, char **argv)
fail_exit (E_NOPERM);
}
STRFCPY (user_name, pw->pw_name);
STRTCPY(user_name, pw->pw_name);
#ifdef WITH_TCB
if (shadowtcb_set_user (pw->pw_name) == SHADOWTCB_FAILURE) {
fail_exit (E_NOPERM);
@@ -831,8 +848,7 @@ int main (int argc, char **argv)
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"display aging info",
user_name, (unsigned int) user_uid, 1);
"display aging info", user_name, user_uid, 1);
#endif
list_fields ();
fail_exit (E_SUCCESS);
@@ -854,40 +870,38 @@ int main (int argc, char **argv)
else {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change all aging information",
user_name, (unsigned int) user_uid, 1);
user_name, user_uid, 1);
}
#endif
} else {
#ifdef WITH_AUDIT
if (Mflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change max age",
user_name, (unsigned int) user_uid, 1);
"change max age", user_name, user_uid, 1);
}
if (mflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change min age",
user_name, (unsigned int) user_uid, 1);
"change min age", user_name, user_uid, 1);
}
if (dflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change last change date",
user_name, (unsigned int) user_uid, 1);
user_name, user_uid, 1);
}
if (Wflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change passwd warning",
user_name, (unsigned int) user_uid, 1);
user_name, user_uid, 1);
}
if (Iflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change inactive days",
user_name, (unsigned int) user_uid, 1);
user_name, user_uid, 1);
}
if (Eflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"change passwd expiration",
user_name, (unsigned int) user_uid, 1);
user_name, user_uid, 1);
}
#endif
}
+8 -6
View File
@@ -12,20 +12,21 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "atoi/strtou_noneg.h"
#include "defines.h"
#include "prototypes.h"
#include "subordinateio.h"
#include "idmapping.h"
#include "shadowlog.h"
const char *Prog;
static const char Prog[] = "check_subid_range";
int main(int argc, char **argv)
{
char *owner;
unsigned long start, count;
bool check_uids;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -34,11 +35,12 @@ int main(int argc, char **argv)
owner = argv[1];
check_uids = argv[2][0] == 'u';
start = strtoul(argv[3], NULL, 10);
if (start == ULONG_MAX && errno == ERANGE)
errno = 0;
start = strtoul_noneg(argv[3], NULL, 10);
if (errno != 0)
exit(1);
count = strtoul(argv[4], NULL, 10);
if (count == ULONG_MAX && errno == ERANGE)
count = strtoul_noneg(argv[4], NULL, 10);
if (errno != 0)
exit(1);
if (check_uids) {
if (have_sub_uids(owner, start, count))
+38 -56
View File
@@ -17,6 +17,8 @@
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "nscd.h"
@@ -30,11 +32,14 @@
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/strtcpy.h"
/*
* Global variables.
*/
const char *Prog;
static const char Prog[] = "chfn";
static char fullnm[BUFSIZ];
static char roomno[BUFSIZ];
static char workph[BUFSIZ];
@@ -54,8 +59,8 @@ static bool pw_locked = false;
*/
/* local function prototypes */
static void fail_exit (int code);
static /*@noreturn@*/void usage (int status);
NORETURN static void fail_exit (int code);
NORETURN static void usage (int status);
static bool may_change_field (int);
static void new_fields (void);
static char *copy_field (char *, char *, char *);
@@ -86,7 +91,9 @@ static void fail_exit (int code)
/*
* usage - print command line syntax and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -175,19 +182,19 @@ static void new_fields (void)
if (may_change_field ('r')) {
change_field (roomno, sizeof roomno, _("Room Number"));
} else {
printf (_("\t%s: %s\n"), _("Room Number"), fullnm);
printf (_("\t%s: %s\n"), _("Room Number"), roomno);
}
if (may_change_field ('w')) {
change_field (workph, sizeof workph, _("Work Phone"));
} else {
printf (_("\t%s: %s\n"), _("Work Phone"), fullnm);
printf (_("\t%s: %s\n"), _("Work Phone"), workph);
}
if (may_change_field ('h')) {
change_field (homeph, sizeof homeph, _("Home Phone"));
} else {
printf (_("\t%s: %s\n"), _("Home Phone"), fullnm);
printf (_("\t%s: %s\n"), _("Home Phone"), homeph);
}
if (amroot) {
@@ -271,7 +278,7 @@ static void process_flags (int argc, char **argv)
exit (E_NOPERM);
}
fflg = true;
STRFCPY (fullnm, optarg);
STRTCPY(fullnm, optarg);
break;
case 'h':
if (!may_change_field ('h')) {
@@ -280,7 +287,7 @@ static void process_flags (int argc, char **argv)
exit (E_NOPERM);
}
hflg = true;
STRFCPY (homeph, optarg);
STRTCPY(homeph, optarg);
break;
case 'o':
if (!amroot) {
@@ -294,7 +301,7 @@ static void process_flags (int argc, char **argv)
_("%s: fields too long\n"), Prog);
exit (E_NOPERM);
}
STRFCPY (slop, optarg);
STRTCPY(slop, optarg);
break;
case 'r':
if (!may_change_field ('r')) {
@@ -303,7 +310,7 @@ static void process_flags (int argc, char **argv)
exit (E_NOPERM);
}
rflg = true;
STRFCPY (roomno, optarg);
STRTCPY(roomno, optarg);
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
@@ -317,7 +324,7 @@ static void process_flags (int argc, char **argv)
exit (E_NOPERM);
}
wflg = true;
STRFCPY (workph, optarg);
STRTCPY(workph, optarg);
break;
default:
usage (E_USAGE);
@@ -358,7 +365,7 @@ static void check_perms (const struct passwd *pw)
* check if the change is allowed by SELinux policy.
*/
if ((pw->pw_uid != getuid ())
&& (check_selinux_permit ("chfn") != 0)) {
&& (check_selinux_permit (Prog) != 0)) {
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
closelog ();
exit (E_NOPERM);
@@ -373,7 +380,7 @@ static void check_perms (const struct passwd *pw)
* --marekm
*/
if (!amroot && getdef_bool ("CHFN_AUTH")) {
passwd_check (pw->pw_name, pw->pw_passwd, "chfn");
passwd_check (pw->pw_name, pw->pw_passwd, Prog);
}
#else /* !USE_PAM */
@@ -385,7 +392,7 @@ static void check_perms (const struct passwd *pw)
exit (E_NOPERM);
}
retval = pam_start ("chfn", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -504,34 +511,35 @@ static void get_old_fields (const char *gecos)
{
char *cp; /* temporary character pointer */
char old_gecos[BUFSIZ]; /* buffer for old GECOS fields */
STRFCPY (old_gecos, gecos);
STRTCPY(old_gecos, gecos);
/*
* Now get the full name. It is the first comma separated field in
* the GECOS field.
*/
cp = copy_field (old_gecos, fflg ? (char *) 0 : fullnm, slop);
cp = copy_field (old_gecos, fflg ? NULL : fullnm, slop);
/*
* Now get the room number. It is the next comma separated field,
* if there is indeed one.
*/
if (NULL != cp) {
cp = copy_field (cp, rflg ? (char *) 0 : roomno, slop);
cp = copy_field (cp, rflg ? NULL : roomno, slop);
}
/*
* Now get the work phone number. It is the third field.
*/
if (NULL != cp) {
cp = copy_field (cp, wflg ? (char *) 0 : workph, slop);
cp = copy_field (cp, wflg ? NULL : workph, slop);
}
/*
* Now get the home phone number. It is the fourth field.
*/
if (NULL != cp) {
cp = copy_field (cp, hflg ? (char *) 0 : homeph, slop);
cp = copy_field (cp, hflg ? NULL : homeph, slop);
}
/*
@@ -608,19 +616,16 @@ static void check_fields (void)
*/
int main (int argc, char **argv)
{
const struct passwd *pw; /* password file entry */
char new_gecos[BUFSIZ]; /* buffer for new GECOS fields */
char *user;
char new_gecos[BUFSIZ];
char *user;
const struct passwd *pw;
sanitize_env ();
check_fds ();
/*
* Get the program name. The program name is used as a
* prefix to most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
sanitize_env ();
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
@@ -633,7 +638,7 @@ int main (int argc, char **argv)
*/
amroot = (getuid () == 0);
OPENLOG ("chfn");
OPENLOG (Prog);
/* parse the command line options */
process_flags (argc, argv);
@@ -663,29 +668,6 @@ int main (int argc, char **argv)
user = xstrdup (pw->pw_name);
}
#ifdef USE_NIS
/*
* Now we make sure this is a LOCAL password entry for this user ...
*/
if (__ispwNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: cannot change user '%s' on NIS client.\n"),
Prog, user);
if (!yp_get_default_domain (&nis_domain) &&
!yp_master (nis_domain, "passwd.byname", &nis_master)) {
fprintf (stderr,
_
("%s: '%s' is the NIS master for this client.\n"),
Prog, nis_master);
}
fail_exit (E_NOPERM);
}
#endif
/* Check that the caller is allowed to change the gecos of the
* specified user */
check_perms (pw);
@@ -717,9 +699,9 @@ int main (int argc, char **argv)
fprintf (stderr, _("%s: fields too long\n"), Prog);
fail_exit (E_NOPERM);
}
snprintf (new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s",
fullnm, roomno, workph, homeph,
('\0' != slop[0]) ? "," : "", slop);
SNPRINTF(new_gecos, "%s,%s,%s,%s%s%s",
fullnm, roomno, workph, homeph,
('\0' != slop[0]) ? "," : "", slop);
/* Rewrite the user's gecos in the passwd file */
update_gecos (user, new_gecos);
+25 -11
View File
@@ -36,7 +36,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "chgpasswd";
static bool eflg = false;
static bool md5flg = false;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
@@ -62,8 +62,8 @@ static bool sgr_locked = false;
static bool gr_locked = false;
/* local function prototypes */
static void fail_exit (int code);
static /*@noreturn@*/void usage (int status);
NORETURN static void fail_exit (int code);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv);
static void check_flags (void);
static void check_perms (void);
@@ -99,7 +99,9 @@ static void fail_exit (int code)
/*
* usage - display usage message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -184,21 +186,28 @@ static void process_flags (int argc, char **argv)
case 's':
sflg = true;
bad_s = 0;
if (!crypt_method) {
fprintf (stderr,
_("%s: no crypt method defined\n"),
Prog);
usage (E_USAGE);
}
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (0 == getlong(optarg, &sha_rounds)))) {
&& (-1 == getlong(optarg, &sha_rounds)))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
&& (-1 == getlong(optarg, &bcrypt_rounds)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (0 == getlong(optarg, &yescrypt_cost)))) {
&& (-1 == getlong(optarg, &yescrypt_cost)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
@@ -294,7 +303,7 @@ static void check_perms (void)
exit (1);
}
retval = pam_start ("chgpasswd", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -414,7 +423,6 @@ int main (int argc, char **argv)
int errors = 0;
int line = 0;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -422,11 +430,17 @@ int main (int argc, char **argv)
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
#ifdef WITH_SELINUX
if (check_selinux_permit ("passwd") != 0) {
return (E_NOPERM);
}
#endif /* WITH_SELINUX */
process_root_flag ("-R", argc, argv);
process_flags (argc, argv);
OPENLOG ("chgpasswd");
OPENLOG (Prog);
check_perms ();
@@ -441,7 +455,7 @@ int main (int argc, char **argv)
* group entry for each group will be looked up in the appropriate
* file (gshadow or group) and the password changed.
*/
while (fgets (buf, (int) sizeof buf, stdin) != (char *) 0) {
while (fgets (buf, (int) sizeof buf, stdin) != NULL) {
line++;
cp = strrchr (buf, '\n');
if (NULL != cp) {
+31 -17
View File
@@ -35,7 +35,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "chpasswd";
static bool eflg = false;
static bool md5flg = false;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
@@ -54,13 +54,15 @@ static long bcrypt_rounds = 13;
static long yescrypt_cost = 5;
#endif
static const char *prefix = "";
static bool is_shadow_pwd;
static bool pw_locked = false;
static bool spw_locked = false;
/* local function prototypes */
static void fail_exit (int code);
static /*@noreturn@*/void usage (int status);
NORETURN static void fail_exit (int code);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv);
static void check_flags (void);
static void check_perms (void);
@@ -94,7 +96,9 @@ static void fail_exit (int code)
/*
* usage - display usage message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -121,6 +125,7 @@ static /*@noreturn@*/void usage (int status)
" the MD5 algorithm\n"),
usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
(void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n"
" or YESCRYPT crypt algorithms\n"),
@@ -148,6 +153,7 @@ static void process_flags (int argc, char **argv)
{"help", no_argument, NULL, 'h'},
{"md5", no_argument, NULL, 'm'},
{"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
{"sha-rounds", required_argument, NULL, 's'},
#endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */
@@ -156,9 +162,9 @@ static void process_flags (int argc, char **argv)
while ((c = getopt_long (argc, argv,
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
"c:ehmR:s:",
"c:ehmR:P:s:",
#else
"c:ehmR:",
"c:ehmR:P:",
#endif
long_options, NULL)) != -1) {
switch (c) {
@@ -176,25 +182,27 @@ static void process_flags (int argc, char **argv)
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
case 's':
sflg = true;
bad_s = 0;
#if defined(USE_SHA_CRYPT)
if ((IS_CRYPT_METHOD("SHA256") || IS_CRYPT_METHOD("SHA512"))
&& (0 == getlong(optarg, &sha_rounds))) {
&& (-1 == getlong(optarg, &sha_rounds))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (IS_CRYPT_METHOD("BCRYPT")
&& (0 == getlong(optarg, &bcrypt_rounds))) {
&& (-1 == getlong(optarg, &bcrypt_rounds))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (IS_CRYPT_METHOD("YESCRYPT")
&& (0 == getlong(optarg, &yescrypt_cost))) {
&& (-1 == getlong(optarg, &yescrypt_cost))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
@@ -294,7 +302,7 @@ static void check_perms (void)
exit (1);
}
retval = pam_start ("chpasswd", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -442,7 +450,6 @@ int main (int argc, char **argv)
int errors = 0;
int line = 0;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -450,18 +457,25 @@ int main (int argc, char **argv)
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
#ifdef WITH_SELINUX
if (check_selinux_permit ("passwd") != 0) {
return (E_NOPERM);
}
#endif /* WITH_SELINUX */
process_flags (argc, argv);
salt = get_salt();
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
#ifdef USE_PAM
if (md5flg || eflg || cflg) {
if (md5flg || eflg || cflg || prefix[0]) {
use_pam = false;
}
#endif /* USE_PAM */
OPENLOG ("chpasswd");
OPENLOG (Prog);
check_perms ();
@@ -482,7 +496,7 @@ int main (int argc, char **argv)
* last change date is set in the age only if aging information is
* present.
*/
while (fgets (buf, (int) sizeof buf, stdin) != (char *) 0) {
while (fgets (buf, sizeof buf, stdin) != NULL) {
line++;
cp = strrchr (buf, '\n');
if (NULL != cp) {
@@ -491,7 +505,7 @@ int main (int argc, char **argv)
if (feof (stdin) == 0) {
// Drop all remaining characters on this line.
while (fgets (buf, (int) sizeof buf, stdin) != (char *) 0) {
while (fgets (buf, sizeof buf, stdin) != NULL) {
cp = strchr (buf, '\n');
if (cp != NULL) {
break;
@@ -531,7 +545,7 @@ int main (int argc, char **argv)
#ifdef USE_PAM
if (use_pam) {
if (do_pam_passwd_non_interactive ("chpasswd", name, newpwd) != 0) {
if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) {
fprintf (stderr,
_("%s: (line %d, user %s) password not changed\n"),
Prog, line, name);
@@ -606,7 +620,7 @@ int main (int argc, char **argv)
if (NULL != sp) {
newsp = *sp;
newsp.sp_pwdp = cp;
newsp.sp_lstchg = (long) gettime () / SCALE;
newsp.sp_lstchg = gettime () / DAY;
if (0 == newsp.sp_lstchg) {
/* Better disable aging than requiring a
* password change */
+92 -55
View File
@@ -16,6 +16,8 @@
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "nscd.h"
@@ -29,14 +31,22 @@
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/strtcpy.h"
#ifndef SHELLS_FILE
#define SHELLS_FILE "/etc/shells"
#endif
#ifdef HAVE_VENDORDIR
#include <libeconf.h>
#define SHELLS "shells"
#define ETCDIR "/etc"
#endif
/*
* Global variables
*/
const char *Prog; /* Program name */
static const char Prog[] = "chsh"; /* Program name */
static bool amroot; /* Real UID is root */
static char loginsh[BUFSIZ]; /* Name of new login shell */
/* command line options */
@@ -46,8 +56,8 @@ static bool pw_locked = false;
/* external identifiers */
/* local function prototypes */
static /*@noreturn@*/void fail_exit (int code);
static /*@noreturn@*/void usage (int status);
NORETURN static void fail_exit (int code);
NORETURN static void usage (int status);
static void new_fields (void);
static bool shell_is_listed (const char *);
static bool is_restricted_shell (const char *);
@@ -58,7 +68,9 @@ static void update_shell (const char *user, char *loginsh);
/*
* fail_exit - do some cleanup and exit with the given error code
*/
static /*@noreturn@*/void fail_exit (int code)
NORETURN
static void
fail_exit (int code)
{
if (pw_locked) {
if (pw_unlock () == 0) {
@@ -76,7 +88,9 @@ static /*@noreturn@*/void fail_exit (int code)
/*
* usage - print command line syntax and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -127,17 +141,60 @@ static bool is_restricted_shell (const char *sh)
* If getusershell() is available (Linux, *BSD, possibly others), use it
* instead of re-implementing it.
*/
#ifdef HAVE_VENDORDIR
static bool shell_is_listed (const char *sh)
{
char *cp;
bool found = false;
#ifndef HAVE_GETUSERSHELL
char buf[BUFSIZ];
FILE *fp;
#endif
size_t size = 0;
econf_err error;
char **keys;
econf_file *key_file;
error = econf_readDirs(&key_file,
VENDORDIR,
ETCDIR,
SHELLS,
NULL,
"", /* key only */
"#" /* comment */);
if (error) {
fprintf (stderr,
_("Cannot parse shell files: %s"),
econf_errString(error));
fail_exit (1);
}
error = econf_getKeys(key_file, NULL, &size, &keys);
if (error) {
fprintf (stderr,
_("Cannot evaluate entries in shell files: %s"),
econf_errString(error));
econf_free (key_file);
fail_exit (1);
}
for (size_t i = 0; i < size; i++) {
if (strcmp (keys[i], sh) == 0) {
found = true;
break;
}
}
econf_free (keys);
econf_free (key_file);
return found;
}
#else /* without HAVE_VENDORDIR */
static bool shell_is_listed (const char *sh)
{
bool found = false;
#ifdef HAVE_GETUSERSHELL
char *cp;
setusershell ();
while ((cp = getusershell ())) {
if (strcmp (cp, sh) == 0) {
@@ -147,18 +204,17 @@ static bool shell_is_listed (const char *sh)
}
endusershell ();
#else
char *buf = NULL;
FILE *fp;
size_t n = 0;
fp = fopen (SHELLS_FILE, "r");
if (NULL == fp) {
return false;
}
while (fgets (buf, sizeof (buf), fp) == buf) {
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
if (buf[0] == '#') {
while (getline (&buf, &n, fp) != -1) {
if (buf[0] != '/') {
continue;
}
@@ -167,10 +223,13 @@ static bool shell_is_listed (const char *sh)
break;
}
}
free(buf);
fclose (fp);
#endif
return found;
}
#endif /* with HAVE_VENDORDIR */
/*
* process_flags - parse the command line options
@@ -197,7 +256,7 @@ static void process_flags (int argc, char **argv)
break;
case 's':
sflg = true;
STRFCPY (loginsh, optarg);
STRTCPY(loginsh, optarg);
break;
default:
usage (E_USAGE);
@@ -260,7 +319,7 @@ static void check_perms (const struct passwd *pw)
* check if the change is allowed by SELinux policy.
*/
if ((pw->pw_uid != getuid ())
&& (check_selinux_permit("chsh") != 0)) {
&& (check_selinux_permit(Prog) != 0)) {
SYSLOG ((LOG_WARN, "can't change shell for '%s'", pw->pw_name));
fprintf (stderr,
_("You may not change the shell for '%s'.\n"),
@@ -277,7 +336,7 @@ static void check_perms (const struct passwd *pw)
* chfn/chsh. --marekm
*/
if (!amroot && getdef_bool ("CHSH_AUTH")) {
passwd_check (pw->pw_name, pw->pw_passwd, "chsh");
passwd_check (pw->pw_name, pw->pw_passwd, Prog);
}
#else /* !USE_PAM */
@@ -289,7 +348,7 @@ static void check_perms (const struct passwd *pw)
exit (E_NOPERM);
}
retval = pam_start ("chsh", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -413,12 +472,8 @@ int main (int argc, char **argv)
const struct passwd *pw; /* Password entry from /etc/passwd */
sanitize_env ();
check_fds ();
/*
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -433,7 +488,7 @@ int main (int argc, char **argv)
*/
amroot = (getuid () == 0);
OPENLOG ("chsh");
OPENLOG (Prog);
/* parse the command line options */
process_flags (argc, argv);
@@ -463,28 +518,6 @@ int main (int argc, char **argv)
user = xstrdup (pw->pw_name);
}
#ifdef USE_NIS
/*
* Now we make sure this is a LOCAL password entry for this user ...
*/
if (__ispwNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: cannot change user '%s' on NIS client.\n"),
Prog, user);
if (!yp_get_default_domain (&nis_domain) &&
!yp_master (nis_domain, "passwd.byname", &nis_master)) {
fprintf (stderr,
_("%s: '%s' is the NIS master for this client.\n"),
Prog, nis_master);
}
fail_exit (1);
}
#endif
check_perms (pw);
/*
@@ -492,7 +525,7 @@ int main (int argc, char **argv)
* file, or use the value from the command line.
*/
if (!sflg) {
STRFCPY (loginsh, pw->pw_shell);
STRTCPY(loginsh, pw->pw_shell);
}
/*
@@ -514,11 +547,15 @@ int main (int argc, char **argv)
fprintf (stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh);
fail_exit (1);
}
if ( !amroot
&& ( is_restricted_shell (loginsh)
|| (access (loginsh, X_OK) != 0))) {
fprintf (stderr, _("%s: %s is an invalid shell\n"), Prog, loginsh);
fail_exit (1);
if (loginsh[0] != '/'
|| is_restricted_shell (loginsh)
|| (access (loginsh, X_OK) != 0)) {
if (amroot) {
fprintf (stderr, _("%s: Warning: %s is an invalid shell\n"), Prog, loginsh);
} else {
fprintf (stderr, _("%s: %s is an invalid shell\n"), Prog, loginsh);
fail_exit (1);
}
}
/* Even for root, warn if an invalid shell is specified. */
+13 -11
View File
@@ -16,6 +16,8 @@
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "attr.h"
#include "defines.h"
#include "prototypes.h"
/*@-exitarg@*/
@@ -23,18 +25,18 @@
#include "shadowlog.h"
/* Global variables */
const char *Prog;
static const char Prog[] = "expiry";
static bool cflg = false;
/* local function prototypes */
static void catch_signals (unused int sig);
static /*@noreturn@*/void usage (int status);
static void catch_signals (MAYBE_UNUSED int sig);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv);
/*
* catch_signals - signal catcher
*/
static void catch_signals (unused int sig)
static void catch_signals (MAYBE_UNUSED int sig)
{
_exit (10);
}
@@ -42,7 +44,9 @@ static void catch_signals (unused int sig)
/*
* usage - print syntax message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -121,21 +125,19 @@ int main (int argc, char **argv)
struct passwd *pwd;
struct spwd *spwd;
Prog = Basename (argv[0]);
sanitize_env ();
check_fds ();
log_set_progname(Prog);
log_set_logfd(stderr);
sanitize_env ();
/*
* Start by disabling all of the keyboard signals.
*/
(void) signal (SIGHUP, catch_signals);
(void) signal (SIGINT, catch_signals);
(void) signal (SIGQUIT, catch_signals);
#ifdef SIGTSTP
(void) signal (SIGTSTP, catch_signals);
#endif
/*
* expiry takes one of two arguments. The default action is to give
@@ -145,7 +147,7 @@ int main (int argc, char **argv)
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
OPENLOG ("expiry");
OPENLOG (Prog);
process_flags (argc, argv);
+94 -126
View File
@@ -18,15 +18,19 @@
#include <sys/types.h>
#include <time.h>
#include <assert.h>
#include "defines.h"
#include "faillog.h"
#include "memzero.h"
#include "prototypes.h"
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/strftime.h"
/* local function prototypes */
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void print_one (/*@null@*/const struct passwd *pw, bool force);
static void set_locktime (long locktime);
static bool set_locktime_one (uid_t uid, long locktime);
@@ -39,7 +43,7 @@ static void reset (void);
/*
* Global variables
*/
const char *Prog; /* Program name */
static const char Prog[] = "faillog"; /* Program name */
static FILE *fail; /* failure file stream */
static time_t seconds; /* that number of days in seconds */
static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */
@@ -57,9 +61,11 @@ static bool rflg = false; /* reset the counters of login failures */
static struct stat statbuf; /* fstat buffer for file size */
#define NOW (time((time_t *) 0))
#define NOW time(NULL)
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -81,11 +87,53 @@ static /*@noreturn@*/void usage (int status)
exit (status);
}
/*
* Looks up the offset in the faillog file for the given uid.
* Returns -1 on error.
*/
static off_t lookup_faillog(struct faillog *fl, uid_t uid)
{
off_t offset, size;
/* Ensure multiplication does not overflow and retrieving a wrong entry */
if (__builtin_mul_overflow(uid, sizeof(*fl), &offset)) {
fprintf(stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long)uid);
return -1;
}
if (!__builtin_add_overflow(offset, sizeof(*fl), &size)
&& size <= statbuf.st_size) {
/* fseeko errors are not really relevant for us. */
int err = fseeko(fail, offset, SEEK_SET);
assert(0 == err);
/* faillog is a sparse file. Even if no entries were
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread(fl, sizeof(*fl), 1, fail) != 1) {
fprintf(stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long)uid);
return -1;
}
} else {
/* Outsize of the faillog file.
* Behave as if there were a missing entry (same behavior
* as if we were reading an non existing entry in the
* sparse faillog file).
*/
memzero(fl, sizeof(*fl));
}
return offset;
}
static void print_one (/*@null@*/const struct passwd *pw, bool force)
{
static bool once = false;
struct tm *tm;
off_t offset;
struct faillog fl;
time_t now;
char *cp;
@@ -95,28 +143,8 @@ static void print_one (/*@null@*/const struct passwd *pw, bool force)
return;
}
offset = (off_t) pw->pw_uid * sizeof (fl);
if (offset + sizeof (fl) <= statbuf.st_size) {
/* fseeko errors are not really relevant for us. */
int err = fseeko (fail, offset, SEEK_SET);
assert (0 == err);
/* faillog is a sparse file. Even if no entries were
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
fprintf (stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long int)pw->pw_uid);
return;
}
} else {
/* Outsize of the faillog file.
* Behave as if there were a missing entry (same behavior
* as if we were reading an non existing entry in the
* sparse faillog file).
*/
memzero (&fl, sizeof (fl));
if (lookup_faillog(&fl, pw->pw_uid) < 0) {
return;
}
/* Nothing to report */
@@ -142,7 +170,7 @@ static void print_one (/*@null@*/const struct passwd *pw, bool force)
fprintf (stderr, "Cannot read time from faillog.\n");
return;
}
strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm);
STRFTIME(ptime, "%D %H:%M:%S %z", tm);
cp = ptime;
printf ("%-9s %5d %5d ",
@@ -164,7 +192,7 @@ static void print_one (/*@null@*/const struct passwd *pw, bool force)
static void print (void)
{
if (uflg && has_umin && has_umax && (umin==umax)) {
print_one (getpwuid ((uid_t)umin), true);
print_one (getpwuid (umin), true);
} else {
/* We only print records for existing users.
* Loop based on the user database instead of reading the
@@ -197,28 +225,10 @@ static bool reset_one (uid_t uid)
off_t offset;
struct faillog fl;
offset = (off_t) uid * sizeof (fl);
if (offset + sizeof (fl) <= statbuf.st_size) {
/* fseeko errors are not really relevant for us. */
int err = fseeko (fail, offset, SEEK_SET);
assert (0 == err);
/* faillog is a sparse file. Even if no entries were
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
fprintf (stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long int)uid);
return true;
}
} else {
/* Outsize of the faillog file.
* Behave as if there were a missing entry (same behavior
* as if we were reading an non existing entry in the
* sparse faillog file).
*/
memzero (&fl, sizeof (fl));
offset = lookup_faillog(&fl, uid);
if (offset < 0) {
/* failure */
return true;
}
if (0 == fl.fail_cnt) {
@@ -232,21 +242,21 @@ static bool reset_one (uid_t uid)
fl.fail_cnt = 0;
if ( (fseeko (fail, offset, SEEK_SET) == 0)
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
&& (fwrite (&fl, sizeof (fl), 1, fail) == 1)) {
(void) fflush (fail);
return false;
}
fprintf (stderr,
_("%s: Failed to reset fail count for UID %lu\n"),
Prog, (unsigned long int)uid);
Prog, (unsigned long)uid);
return true;
}
static void reset (void)
{
if (uflg && has_umin && has_umax && (umin==umax)) {
if (reset_one ((uid_t)umin)) {
if (reset_one (umin)) {
errors = true;
}
} else {
@@ -258,7 +268,7 @@ static void reset (void)
uidmax--;
}
if (has_umax && (uid_t)umax < uidmax) {
uidmax = (uid_t)umax;
uidmax = umax;
}
/* Reset all entries in the specified range.
@@ -271,7 +281,7 @@ static void reset (void)
/* Make sure we stay in the umin-umax range if specified */
if (has_umin) {
uid = (uid_t)umin;
uid = umin;
}
while (uid <= uidmax) {
@@ -289,7 +299,7 @@ static void reset (void)
while ( (pwent = getpwent ()) != NULL ) {
if ( uflg
&& ( (has_umin && (pwent->pw_uid < (uid_t)umin))
|| (pwent->pw_uid > (uid_t)uidmax))) {
|| (pwent->pw_uid > uidmax))) {
continue;
}
if (reset_one (pwent->pw_uid)) {
@@ -311,28 +321,9 @@ static bool setmax_one (uid_t uid, short max)
off_t offset;
struct faillog fl;
offset = (off_t) uid * sizeof (fl);
if (offset + sizeof (fl) <= statbuf.st_size) {
/* fseeko errors are not really relevant for us. */
int err = fseeko (fail, offset, SEEK_SET);
assert (0 == err);
/* faillog is a sparse file. Even if no entries were
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
fprintf (stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long int)uid);
return true;
}
} else {
/* Outsize of the faillog file.
* Behave as if there were a missing entry (same behavior
* as if we were reading an non existing entry in the
* sparse faillog file).
*/
memzero (&fl, sizeof (fl));
offset = lookup_faillog(&fl, uid);
if (offset < 0) {
return true;
}
if (max == fl.fail_max) {
@@ -347,21 +338,21 @@ static bool setmax_one (uid_t uid, short max)
fl.fail_max = max;
if ( (fseeko (fail, offset, SEEK_SET) == 0)
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
&& (fwrite (&fl, sizeof (fl), 1, fail) == 1)) {
(void) fflush (fail);
return false;
}
fprintf (stderr,
_("%s: Failed to set max for UID %lu\n"),
Prog, (unsigned long int)uid);
Prog, (unsigned long)uid);
return true;
}
static void setmax (short max)
{
if (uflg && has_umin && has_umax && (umin==umax)) {
if (setmax_one ((uid_t)umin, max)) {
if (setmax_one (umin, max)) {
errors = true;
}
} else {
@@ -385,10 +376,10 @@ static void setmax (short max)
/* Make sure we stay in the umin-umax range if specified */
if (has_umin) {
uid = (uid_t)umin;
uid = umin;
}
if (has_umax) {
uidmax = (uid_t)umax;
uidmax = umax;
}
while (uid <= uidmax) {
@@ -428,28 +419,9 @@ static bool set_locktime_one (uid_t uid, long locktime)
off_t offset;
struct faillog fl;
offset = (off_t) uid * sizeof (fl);
if (offset + sizeof (fl) <= statbuf.st_size) {
/* fseeko errors are not really relevant for us. */
int err = fseeko (fail, offset, SEEK_SET);
assert (0 == err);
/* faillog is a sparse file. Even if no entries were
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread ((char *) &fl, sizeof (fl), 1, fail) != 1) {
fprintf (stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long int)uid);
return true;
}
} else {
/* Outsize of the faillog file.
* Behave as if there were a missing entry (same behavior
* as if we were reading an non existing entry in the
* sparse faillog file).
*/
memzero (&fl, sizeof (fl));
offset = lookup_faillog(&fl, uid);
if (offset < 0) {
return true;
}
if (locktime == fl.fail_locktime) {
@@ -464,21 +436,21 @@ static bool set_locktime_one (uid_t uid, long locktime)
fl.fail_locktime = locktime;
if ( (fseeko (fail, offset, SEEK_SET) == 0)
&& (fwrite ((char *) &fl, sizeof (fl), 1, fail) == 1)) {
&& (fwrite (&fl, sizeof (fl), 1, fail) == 1)) {
(void) fflush (fail);
return false;
}
fprintf (stderr,
_("%s: Failed to set locktime for UID %lu\n"),
Prog, (unsigned long int)uid);
Prog, (unsigned long)uid);
return true;
}
static void set_locktime (long locktime)
{
if (uflg && has_umin && has_umax && (umin==umax)) {
if (set_locktime_one ((uid_t)umin, locktime)) {
if (set_locktime_one (umin, locktime)) {
errors = true;
}
} else {
@@ -502,10 +474,10 @@ static void set_locktime (long locktime)
/* Make sure we stay in the umin-umax range if specified */
if (has_umin) {
uid = (uid_t)umin;
uid = umin;
}
if (has_umax) {
uidmax = (uid_t)umax;
uidmax = umax;
}
while (uid <= uidmax) {
@@ -541,11 +513,6 @@ int main (int argc, char **argv)
short fail_max = 0; // initialize to silence compiler warning
long days = 0;
/*
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -578,7 +545,7 @@ int main (int argc, char **argv)
usage (E_SUCCESS);
/*@notreached@*/break;
case 'l':
if (getlong (optarg, &fail_locktime) == 0) {
if (getlong(optarg, &fail_locktime) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -588,15 +555,16 @@ int main (int argc, char **argv)
break;
case 'm':
{
long int lmax;
if ( (getlong (optarg, &lmax) == 0)
|| ((long int)(short) lmax != lmax)) {
long lmax;
if ( (getlong(optarg, &lmax) == -1)
|| ((long)(short) lmax != lmax)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
fail_max = (short) lmax;
fail_max = lmax;
mflg = true;
break;
}
@@ -606,7 +574,7 @@ int main (int argc, char **argv)
case 'R': /* no-op, handled in process_root_flag () */
break;
case 't':
if (getlong (optarg, &days) == 0) {
if (getlong(optarg, &days) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -630,14 +598,14 @@ int main (int argc, char **argv)
/* local, no need for xgetpwnam */
pwent = getpwnam (optarg);
if (NULL != pwent) {
umin = (unsigned long) pwent->pw_uid;
umin = pwent->pw_uid;
has_umin = true;
umax = umin;
has_umax = true;
} else {
if (getrange (optarg,
&umin, &has_umin,
&umax, &has_umax) == 0) {
if (getrange(optarg,
&umin, &has_umin,
&umax, &has_umax) == -1) {
fprintf (stderr,
_("%s: Unknown user or range: %s\n"),
Prog, optarg);
+1 -2
View File
@@ -9,7 +9,7 @@
/* Test program for the subid freeing routine */
const char *Prog;
static const char Prog[] = "free_subid_range";
static void usage(void)
{
@@ -25,7 +25,6 @@ int main(int argc, char *argv[])
struct subordinate_range range;
bool group = false; // get subuids by default
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
while ((c = getopt(argc, argv, "g")) != EOF) {
+1 -2
View File
@@ -6,7 +6,7 @@
#include "prototypes.h"
#include "shadowlog.h"
const char *Prog;
static const char Prog[] = "get_subid_owners";
static void usage(void)
{
@@ -21,7 +21,6 @@ int main(int argc, char *argv[])
int i, n;
uid_t *uids;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
if (argc < 2) {
+1 -2
View File
@@ -7,7 +7,7 @@
#include "prototypes.h"
#include "shadowlog.h"
const char *Prog;
static const char Prog[] = "getsubids";
static void usage(void)
{
@@ -23,7 +23,6 @@ int main(int argc, char *argv[])
struct subid_range *ranges;
const char *owner;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
if (argc < 2)
+87 -111
View File
@@ -19,8 +19,13 @@
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include "agetpass.h"
#include "alloc.h"
#include "attr.h"
#include "defines.h"
#include "groupio.h"
#include "memzero.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -29,13 +34,16 @@
#endif
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/strtcpy.h"
/*
* Global variables
*/
/* The name of this command, as it is invoked */
const char *Prog;
static const char Prog[] = "gpasswd";
#ifdef SHADOWGRP
/* Indicate if shadow groups are enabled on the system
@@ -73,6 +81,7 @@ static uid_t bywho;
#endif
/* local function prototypes */
NORETURN static void failure(void);
static void usage (int status);
static void catch_signals (int killed);
static bool is_valid_user_list (const char *users);
@@ -92,14 +101,14 @@ static void update_group (struct group *gr);
static void change_passwd (struct group *gr);
#endif
static void log_gpasswd_failure (const char *suffix);
static void log_gpasswd_failure_system (/*@null@*/unused void *arg);
static void log_gpasswd_failure_group (/*@null@*/unused void *arg);
static void log_gpasswd_failure_system (/*@null@*/MAYBE_UNUSED void *arg);
static void log_gpasswd_failure_group (/*@null@*/MAYBE_UNUSED void *arg);
#ifdef SHADOWGRP
static void log_gpasswd_failure_gshadow (/*@null@*/unused void *arg);
static void log_gpasswd_failure_gshadow (/*@null@*/MAYBE_UNUSED void *arg);
#endif
static void log_gpasswd_success (const char *suffix);
static void log_gpasswd_success_system (/*@null@*/unused void *arg);
static void log_gpasswd_success_group (/*@null@*/unused void *arg);
static void log_gpasswd_success_system (/*@null@*/MAYBE_UNUSED void *arg);
static void log_gpasswd_success_group (/*@null@*/MAYBE_UNUSED void *arg);
/*
* usage - display usage message
@@ -194,11 +203,11 @@ static bool is_valid_user_list (const char *users)
return is_valid;
}
static void failure (void)
static void failure(void)
{
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
log_gpasswd_failure (": Permission denied");
exit (E_NOPERM);
fprintf(stderr, _("%s: Permission denied.\n"), Prog);
log_gpasswd_failure(": Permission denied");
exit(E_NOPERM);
}
/*
@@ -376,17 +385,16 @@ static void open_files (void)
static void log_gpasswd_failure (const char *suffix)
{
#ifdef WITH_AUDIT
char buf[1024];
char buf[1024];
#endif
if (aflg) {
SYSLOG ((LOG_ERR,
"%s failed to add user %s to group %s%s",
myname, user, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to add user %s to group %s%s",
myname, user, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to add user %s to group %s%s",
myname, user, group, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -397,10 +405,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to remove user %s from group %s%s",
myname, user, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to remove user %s from group %s%s",
myname, user, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to remove user %s from group %s%s",
myname, user, group, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -411,10 +417,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to remove password of group %s%s",
myname, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to remove password of group %s%s",
myname, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to remove password of group %s%s",
myname, group, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -425,10 +429,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to restrict access to group %s%s",
myname, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to restrict access to group %s%s",
myname, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to restrict access to group %s%s",
myname, group, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -441,10 +443,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to set the administrators of group %s to %s%s",
myname, group, admins, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to set the administrators of group %s to %s%s",
myname, group, admins, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to set the administrators of group %s to %s%s",
myname, group, admins, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -457,10 +457,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to set the members of group %s to %s%s",
myname, group, members, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to set the members of group %s to %s%s",
myname, group, members, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to set the members of group %s to %s%s",
myname, group, members, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -472,10 +470,8 @@ static void log_gpasswd_failure (const char *suffix)
"%s failed to change password of group %s%s",
myname, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"%s failed to change password of group %s%s",
myname, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "%s failed to change password of group %s%s",
myname, group, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -484,25 +480,25 @@ static void log_gpasswd_failure (const char *suffix)
}
}
static void log_gpasswd_failure_system (unused void *arg)
static void log_gpasswd_failure_system (MAYBE_UNUSED void *arg)
{
log_gpasswd_failure ("");
}
static void log_gpasswd_failure_group (unused void *arg)
static void log_gpasswd_failure_group (MAYBE_UNUSED void *arg)
{
char buf[1024];
snprintf (buf, 1023, " in %s", gr_dbname ());
buf[1023] = '\0';
char buf[1024];
SNPRINTF(buf, " in %s", gr_dbname());
log_gpasswd_failure (buf);
}
#ifdef SHADOWGRP
static void log_gpasswd_failure_gshadow (unused void *arg)
static void log_gpasswd_failure_gshadow (MAYBE_UNUSED void *arg)
{
char buf[1024];
snprintf (buf, 1023, " in %s", sgr_dbname ());
buf[1023] = '\0';
char buf[1024];
SNPRINTF(buf, " in %s", sgr_dbname());
log_gpasswd_failure (buf);
}
#endif /* SHADOWGRP */
@@ -510,17 +506,16 @@ static void log_gpasswd_failure_gshadow (unused void *arg)
static void log_gpasswd_success (const char *suffix)
{
#ifdef WITH_AUDIT
char buf[1024];
char buf[1024];
#endif
if (aflg) {
SYSLOG ((LOG_INFO,
"user %s added by %s to group %s%s",
user, myname, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"user %s added by %s to group %s%s",
user, myname, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "user %s added by %s to group %s%s",
user, myname, group, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -531,10 +526,8 @@ static void log_gpasswd_success (const char *suffix)
"user %s removed by %s from group %s%s",
user, myname, group, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"user %s removed by %s from group %s%s",
user, myname, group, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "user %s removed by %s from group %s%s",
user, myname, group, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -545,10 +538,8 @@ static void log_gpasswd_success (const char *suffix)
"password of group %s removed by %s%s",
group, myname, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"password of group %s removed by %s%s",
group, myname, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "password of group %s removed by %s%s",
group, myname, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -559,10 +550,8 @@ static void log_gpasswd_success (const char *suffix)
"access to group %s restricted by %s%s",
group, myname, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"access to group %s restricted by %s%s",
group, myname, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "access to group %s restricted by %s%s",
group, myname, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -575,10 +564,8 @@ static void log_gpasswd_success (const char *suffix)
"administrators of group %s set by %s to %s%s",
group, myname, admins, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"administrators of group %s set by %s to %s%s",
group, myname, admins, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "administrators of group %s set by %s to %s%s",
group, myname, admins, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -591,10 +578,8 @@ static void log_gpasswd_success (const char *suffix)
"members of group %s set by %s to %s%s",
group, myname, members, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"members of group %s set by %s to %s%s",
group, myname, members, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "members of group %s set by %s to %s%s",
group, myname, members, suffix);
audit_logger (AUDIT_USER_ACCT, Prog,
buf,
group, AUDIT_NO_ID,
@@ -606,10 +591,8 @@ static void log_gpasswd_success (const char *suffix)
"password of group %s changed by %s%s",
group, myname, suffix));
#ifdef WITH_AUDIT
snprintf (buf, 1023,
"password of group %s changed by %s%s",
group, myname, suffix);
buf[1023] = '\0';
SNPRINTF(buf, "password of group %s changed by %s%s",
group, myname, suffix);
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
buf,
group, AUDIT_NO_ID,
@@ -618,16 +601,16 @@ static void log_gpasswd_success (const char *suffix)
}
}
static void log_gpasswd_success_system (unused void *arg)
static void log_gpasswd_success_system (MAYBE_UNUSED void *arg)
{
log_gpasswd_success ("");
}
static void log_gpasswd_success_group (unused void *arg)
static void log_gpasswd_success_group (MAYBE_UNUSED void *arg)
{
char buf[1024];
snprintf (buf, 1023, " in %s", gr_dbname ());
buf[1023] = '\0';
char buf[1024];
SNPRINTF(buf, " in %s", gr_dbname());
log_gpasswd_success (buf);
}
@@ -704,8 +687,7 @@ static void check_perms (const struct group *gr)
}
} else
#endif /* SHADOWGRP */
{
#ifdef FIRST_MEMBER_IS_ADMIN
if (!amroot) {
/*
* The policy here for changing a group is that
* 1) you must be root or
@@ -720,20 +702,14 @@ static void check_perms (const struct group *gr)
* first group member might be just a normal user.
* --marekm
*/
if (!amroot) {
if (gr->gr_mem[0] == (char *) 0) {
failure ();
}
if (strcmp (gr->gr_mem[0], myname) != 0) {
failure ();
}
}
#else /* ! FIRST_MEMBER_IS_ADMIN */
if (!amroot) {
failure ();
}
#if !defined(FIRST_MEMBER_IS_ADMIN)
failure();
#endif
if (gr->gr_mem[0] == NULL)
failure();
if (strcmp(gr->gr_mem[0], myname) != 0)
failure();
}
}
@@ -834,7 +810,7 @@ static void get_group (struct group *gr)
sg->sg_mem = dup_list (gr->gr_mem);
sg->sg_adm = (char **) xmalloc (sizeof (char *) * 2);
sg->sg_adm = XMALLOC(2, char *);
#ifdef FIRST_MEMBER_IS_ADMIN
if (sg->sg_mem[0]) {
sg->sg_adm[0] = xstrdup (sg->sg_mem[0]);
@@ -887,25 +863,26 @@ static void change_passwd (struct group *gr)
printf (_("Changing the password for group %s\n"), group);
for (retries = 0; retries < RETRIES; retries++) {
cp = getpass (_("New Password: "));
cp = agetpass (_("New Password: "));
if (NULL == cp) {
exit (1);
}
STRFCPY (pass, cp);
strzero (cp);
cp = getpass (_("Re-enter new password: "));
STRTCPY(pass, cp);
erase_pass (cp);
cp = agetpass (_("Re-enter new password: "));
if (NULL == cp) {
MEMZERO(pass);
exit (1);
}
if (strcmp (pass, cp) == 0) {
strzero (cp);
erase_pass (cp);
break;
}
strzero (cp);
memzero (pass, sizeof pass);
erase_pass (cp);
MEMZERO(pass);
if (retries + 1 < RETRIES) {
puts (_("They don't match; try again"));
@@ -925,7 +902,7 @@ static void change_passwd (struct group *gr)
Prog, salt, strerror (errno));
exit (1);
}
memzero (pass, sizeof pass);
MEMZERO(pass);
#ifdef SHADOWGRP
if (is_shadowgrp) {
gr->gr_passwd = SHADOW_PASSWD_STRING;
@@ -953,6 +930,8 @@ int main (int argc, char **argv)
#endif
sanitize_env ();
check_fds ();
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
@@ -965,11 +944,10 @@ int main (int argc, char **argv)
* with this command.
*/
bywho = getuid ();
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
OPENLOG ("gpasswd");
OPENLOG (Prog);
setbuf (stdout, NULL);
setbuf (stderr, NULL);
@@ -1145,9 +1123,7 @@ int main (int argc, char **argv)
(void) signal (SIGINT, catch_signals);
(void) signal (SIGQUIT, catch_signals);
(void) signal (SIGTERM, catch_signals);
#ifdef SIGTSTP
(void) signal (SIGTSTP, catch_signals);
#endif
/* Prompt for the new password */
#ifdef SHADOWGRP
+31 -25
View File
@@ -27,6 +27,7 @@
#include "defines.h"
#include "getdef.h"
#include "groupio.h"
#include "memzero.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -34,6 +35,7 @@
#include "sgroupio.h"
#endif
#include "shadowlog.h"
#include "run_part.h"
/*
* exit status values
@@ -49,7 +51,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "groupadd";
static /*@null@*/char *group_name;
static gid_t group_id;
@@ -70,7 +72,7 @@ static bool is_shadow_grp;
#endif
/* local function prototypes */
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void new_grent (struct group *grent);
#ifdef SHADOWGRP
@@ -87,7 +89,9 @@ static void check_perms (void);
/*
* usage - display usage message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -105,7 +109,7 @@ static /*@noreturn@*/void usage (int status)
(void) fputs (_(" -p, --password PASSWORD use this encrypted password for the new group\n"), usageout);
(void) fputs (_(" -r, --system create a system account\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DI directory prefix\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
(void) fputs (_(" -U, --users USERS list of user members of this group\n"), usageout);
(void) fputs ("\n", usageout);
exit (status);
@@ -262,8 +266,7 @@ static void close_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"adding group to /etc/group",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO, "group added to %s: name=%s, GID=%u",
gr_dbname (), group_name, (unsigned int) group_id));
@@ -284,8 +287,7 @@ static void close_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"adding group to /etc/gshadow",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO, "group added to %s: name=%s",
sgr_dbname (), group_name));
@@ -299,9 +301,7 @@ static void close_files (void)
/* Report success at the system level */
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
"", group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u",
group_name, (unsigned int) group_id));
@@ -344,8 +344,8 @@ static void open_files (void)
/* And now open the databases */
if (gr_open (O_CREAT | O_RDWR) == 0) {
fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ());
SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ()));
fprintf (stderr, _("%s: cannot open %s: %s\n"), Prog, gr_dbname (), strerror(errno));
SYSLOG ((LOG_WARN, "cannot open %s: %s", gr_dbname (), strerror(errno)));
exit (E_GRP_UPDATE);
}
@@ -353,9 +353,9 @@ static void open_files (void)
if (is_shadow_grp) {
if (sgr_open (O_CREAT | O_RDWR) == 0) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ()));
_("%s: cannot open %s: %s\n"),
Prog, sgr_dbname (), strerror(errno));
SYSLOG ((LOG_WARN, "cannot open %s: %s", sgr_dbname (), strerror(errno)));
exit (E_GRP_UPDATE);
}
}
@@ -403,7 +403,7 @@ static void process_flags (int argc, char **argv)
break;
case 'g':
gflg = true;
if ( (get_gid (optarg, &group_id) == 0)
if ( (get_gid(optarg, &group_id) == -1)
|| (group_id == (gid_t)-1)) {
fprintf (stderr,
_("%s: invalid group ID '%s'\n"),
@@ -429,7 +429,7 @@ static void process_flags (int argc, char **argv)
}
/* terminate name, point to value */
*cp++ = '\0';
if (putdef_str (optarg, cp) < 0) {
if (putdef_str (optarg, cp, NULL) < 0) {
exit (E_BAD_ARG);
}
break;
@@ -511,7 +511,7 @@ static void check_flags (void)
} else {
fprintf (stderr,
_("%s: GID '%lu' already exists\n"),
Prog, (unsigned long int) group_id);
Prog, (unsigned long) group_id);
exit (E_GID_IN_USE);
}
}
@@ -543,7 +543,7 @@ static void check_perms (void)
exit (1);
}
retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -572,10 +572,6 @@ static void check_perms (void)
*/
int main (int argc, char **argv)
{
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -586,7 +582,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupadd");
OPENLOG (Prog);
#ifdef WITH_AUDIT
audit_help_open ();
#endif
@@ -605,6 +601,11 @@ int main (int argc, char **argv)
check_perms ();
if (run_parts ("/etc/shadow-maint/groupadd-pre.d", group_name,
Prog)) {
exit(1);
}
#ifdef SHADOWGRP
is_shadow_grp = sgr_file_present ();
#endif
@@ -623,6 +624,11 @@ int main (int argc, char **argv)
grp_update ();
close_files ();
if (run_parts ("/etc/shadow-maint/groupadd-post.d", group_name,
Prog)) {
exit(1);
}
nscd_flush_cache ("group");
sssd_flush_cache (SSSD_DB_GROUP);
+22 -39
View File
@@ -32,10 +32,11 @@
#include "sgroupio.h"
#endif
#include "shadowlog.h"
#include "run_part.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "groupdel";
static char *group_name;
static gid_t group_id = -1;
@@ -58,7 +59,7 @@ static bool is_shadow_grp;
#define E_GRP_UPDATE 10 /* can't update group file */
/* local function prototypes */
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void grp_update (void);
static void close_files (void);
static void open_files (void);
@@ -68,7 +69,9 @@ static void process_flags (int argc, char **argv);
/*
* usage - display usage message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -147,8 +150,7 @@ static void close_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, Prog,
"removing group from /etc/group",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO,
"group '%s' removed from %s",
@@ -172,8 +174,7 @@ static void close_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, Prog,
"removing group from /etc/gshadow",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO,
"group '%s' removed from %s",
@@ -188,9 +189,7 @@ static void close_files (void)
/* Report success at the system level */
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, Prog,
"",
group_name, (unsigned int) group_id,
SHADOW_AUDIT_SUCCESS);
"", group_name, group_id, SHADOW_AUDIT_SUCCESS);
#endif
SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name));
del_cleanup (cleanup_report_del_group);
@@ -275,7 +274,7 @@ static void group_busy (gid_t gid)
* If pwd isn't NULL, it stopped because the gid's matched.
*/
if (pwd == (struct passwd *) 0) {
if (pwd == NULL) {
return;
}
@@ -350,10 +349,6 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -364,7 +359,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupdel");
OPENLOG (Prog);
#ifdef WITH_AUDIT
audit_help_open ();
#endif
@@ -390,7 +385,7 @@ int main (int argc, char **argv)
exit (1);
}
retval = pam_start ("groupdel", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
@@ -434,28 +429,6 @@ int main (int argc, char **argv)
group_id = grp->gr_gid;
}
#ifdef USE_NIS
/*
* Make sure this isn't a NIS group
*/
if (__isgrNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: group '%s' is a NIS group\n"),
Prog, group_name);
if (!yp_get_default_domain (&nis_domain) &&
!yp_master (nis_domain, "group.byname", &nis_master)) {
fprintf (stderr,
_("%s: %s is the NIS master\n"),
Prog, nis_master);
}
exit (E_NOTFOUND);
}
#endif
/*
* Make sure this isn't the primary group of anyone.
*/
@@ -463,6 +436,11 @@ int main (int argc, char **argv)
group_busy (group_id);
}
if (run_parts ("/etc/shadow-maint/groupdel-pre.d", group_name,
Prog)) {
exit(1);
}
/*
* Do the hard stuff - open the files, delete the group entries,
* then close and update the files.
@@ -473,6 +451,11 @@ int main (int argc, char **argv)
close_files ();
if (run_parts ("/etc/shadow-maint/groupdel-post.d", group_name,
Prog)) {
exit(1);
}
nscd_flush_cache ("group");
sssd_flush_cache (SSSD_DB_GROUP);
+16 -16
View File
@@ -18,6 +18,8 @@
#include "pam_defs.h"
#endif /* USE_PAM */
#include <pwd.h>
#include "alloc.h"
#include "defines.h"
#include "prototypes.h"
#include "groupio.h"
@@ -42,7 +44,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "groupmems";
static char *adduser = NULL;
static char *deluser = NULL;
@@ -66,10 +68,10 @@ static void remove_user (const char *user,
const struct group *grp);
static void purge_members (const struct group *grp);
static void display_members (const char *const *members);
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv);
static void check_perms (void);
static void fail_exit (int code);
NORETURN static void fail_exit (int code);
#define isroot() (getuid () == 0)
static char *whoami (void)
@@ -89,7 +91,7 @@ static char *whoami (void)
}
/*
* add_user - Add an user to the specified group
* add_user - Add a user to the specified group
*/
static void add_user (const char *user,
const struct group *grp)
@@ -125,7 +127,7 @@ static void add_user (const char *user,
static struct sgrp sgrent;
sgrent.sg_name = xstrdup (newgrp->gr_name);
sgrent.sg_mem = dup_list (newgrp->gr_mem);
sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
sgrent.sg_adm = XMALLOC(1, char *);
#ifdef FIRST_MEMBER_IS_ADMIN
if (sgrent.sg_mem[0]) {
sgrent.sg_adm[0] = xstrdup (sgrent.sg_mem[0]);
@@ -172,7 +174,7 @@ static void add_user (const char *user,
}
/*
* remove_user - Remove an user from a given group
* remove_user - Remove a user from a given group
*/
static void remove_user (const char *user,
const struct group *grp)
@@ -208,7 +210,7 @@ static void remove_user (const char *user,
static struct sgrp sgrent;
sgrent.sg_name = xstrdup (newgrp->gr_name);
sgrent.sg_mem = dup_list (newgrp->gr_mem);
sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
sgrent.sg_adm = XMALLOC(1, char *);
#ifdef FIRST_MEMBER_IS_ADMIN
if (sgrent.sg_mem[0]) {
sgrent.sg_adm[0] = xstrdup (sgrent.sg_mem[0]);
@@ -281,9 +283,9 @@ static void purge_members (const struct group *grp)
/* Create a shadow group based on this group */
static struct sgrp sgrent;
sgrent.sg_name = xstrdup (newgrp->gr_name);
sgrent.sg_mem = (char **) xmalloc (sizeof (char *));
sgrent.sg_mem = XMALLOC(1, char *);
sgrent.sg_mem[0] = NULL;
sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
sgrent.sg_adm = XMALLOC(1, char *);
sgrent.sg_adm[0] = NULL;
/* Move any password to gshadow */
@@ -339,7 +341,9 @@ static void display_members (const char *const *members)
}
}
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (EXIT_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -439,7 +443,7 @@ static void check_perms (void)
fail_exit (1);
}
retval = pam_start ("groupmems", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
@@ -569,10 +573,6 @@ int main (int argc, char **argv)
char *name;
const struct group *grp;
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -582,7 +582,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("groupmems");
OPENLOG (Prog);
#ifdef SHADOWGRP
is_shadowgrp = sgr_file_present ();
+52 -93
View File
@@ -15,7 +15,9 @@
#include <fcntl.h>
#include <getopt.h>
#include <grp.h>
#include <stdint.h>
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
@@ -23,6 +25,8 @@
#include <pwd.h>
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "alloc.h"
#include "chkname.h"
#include "defines.h"
#include "groupio.h"
@@ -34,6 +38,8 @@
#include "sgroupio.h"
#endif
#include "shadowlog.h"
#include "string/stpecpy.h"
#include "string/stpeprintf.h"
/*
* exit status values
*/
@@ -53,7 +59,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "groupmod";
#ifdef SHADOWGRP
static bool is_shadow_grp;
@@ -224,7 +230,7 @@ static void grp_update (void)
* shadowed password, we force the creation of a
* gshadow entry when a new password is requested.
*/
memset (&sgrp, 0, sizeof sgrp);
bzero(&sgrp, sizeof sgrp);
sgrp.sg_name = xstrdup (grp.gr_name);
sgrp.sg_passwd = xstrdup (grp.gr_passwd);
sgrp.sg_adm = &empty;
@@ -246,8 +252,8 @@ static void grp_update (void)
// requested to replace the existing groups
if (NULL != grp.gr_mem[0])
gr_free_members(&grp);
grp.gr_mem = (char **)xmalloc(sizeof(char *));
grp.gr_mem[0] = (char *)0;
grp.gr_mem = XMALLOC(1, char *);
grp.gr_mem[0] = NULL;
} else {
// append to existing groups
if (NULL != grp.gr_mem[0])
@@ -333,7 +339,7 @@ static void check_new_gid (void)
*/
fprintf (stderr,
_("%s: GID '%lu' already exists\n"),
Prog, (unsigned long int) group_newid);
Prog, (unsigned long) group_newid);
exit (E_GID_IN_USE);
}
@@ -408,7 +414,7 @@ static void process_flags (int argc, char **argv)
break;
case 'g':
gflg = true;
if ( (get_gid (optarg, &group_newid) == 0)
if ( (get_gid(optarg, &group_newid) == -1)
|| (group_newid == (gid_t)-1)) {
fprintf (stderr,
_("%s: invalid group ID '%s'\n"),
@@ -542,95 +548,74 @@ static void close_files (void)
*/
static void prepare_failure_reports (void)
{
char *gr, *gr_end;
#ifdef SHADOWGRP
char *sgr, *sgr_end;
#endif
char *pw, *pw_end;
info_group.name = group_name;
#ifdef SHADOWGRP
info_gshadow.name = group_name;
#endif
info_passwd.name = group_name;
info_group.audit_msg = xmalloc (512);
gr = XMALLOC(512, char);
info_group.audit_msg = gr;
gr_end = gr + 512;
#ifdef SHADOWGRP
info_gshadow.audit_msg = xmalloc (512);
sgr = XMALLOC(512, char);
info_gshadow.audit_msg = sgr;
sgr_end = sgr + 512;
#endif
info_passwd.audit_msg = xmalloc (512);
pw = XMALLOC(512, char);
info_passwd.audit_msg = pw;
pw_end = pw + 512;
(void) snprintf (info_group.audit_msg, 511,
"changing %s; ", gr_dbname ());
gr = stpeprintf(gr, gr_end, "changing %s; ", gr_dbname ());
#ifdef SHADOWGRP
(void) snprintf (info_gshadow.audit_msg, 511,
"changing %s; ", sgr_dbname ());
sgr = stpeprintf(sgr, sgr_end, "changing %s; ", sgr_dbname ());
#endif
(void) snprintf (info_passwd.audit_msg, 511,
"changing %s; ", pw_dbname ());
pw = stpeprintf(pw, pw_end, "changing %s; ", pw_dbname ());
info_group.action = info_group.audit_msg
+ strlen (info_group.audit_msg);
info_group.action = gr;
#ifdef SHADOWGRP
info_gshadow.action = info_gshadow.audit_msg
+ strlen (info_gshadow.audit_msg);
info_gshadow.action = sgr;
#endif
info_passwd.action = info_passwd.audit_msg
+ strlen (info_passwd.audit_msg);
info_passwd.action = pw;
(void) snprintf (info_group.action,
511 - strlen (info_group.audit_msg),
"group %s/%lu",
group_name, (unsigned long int) group_id);
gr = stpeprintf(gr, gr_end,
"group %s/%ju", group_name, (uintmax_t) group_id);
#ifdef SHADOWGRP
(void) snprintf (info_gshadow.action,
511 - strlen (info_group.audit_msg),
sgr = stpeprintf(sgr, sgr_end,
"group %s", group_name);
#endif
(void) snprintf (info_passwd.action,
511 - strlen (info_group.audit_msg),
"group %s/%lu",
group_name, (unsigned long int) group_id);
pw = stpeprintf(pw, pw_end,
"group %s/%ju", group_name, (uintmax_t) group_id);
if (nflg) {
strncat (info_group.action, ", new name: ",
511 - strlen (info_group.audit_msg));
strncat (info_group.action, group_newname,
511 - strlen (info_group.audit_msg));
gr = stpecpy(gr, gr_end, ", new name: ");
gr = stpecpy(gr, gr_end, group_newname);
#ifdef SHADOWGRP
strncat (info_gshadow.action, ", new name: ",
511 - strlen (info_gshadow.audit_msg));
strncat (info_gshadow.action, group_newname,
511 - strlen (info_gshadow.audit_msg));
sgr = stpecpy(sgr, sgr_end, ", new name: ");
sgr = stpecpy(sgr, sgr_end, group_newname);
#endif
strncat (info_passwd.action, ", new name: ",
511 - strlen (info_passwd.audit_msg));
strncat (info_passwd.action, group_newname,
511 - strlen (info_passwd.audit_msg));
pw = stpecpy(pw, pw_end, ", new name: ");
pw = stpecpy(pw, pw_end, group_newname);
}
if (pflg) {
strncat (info_group.action, ", new password",
511 - strlen (info_group.audit_msg));
gr = stpecpy(gr, gr_end, ", new password");
#ifdef SHADOWGRP
strncat (info_gshadow.action, ", new password",
511 - strlen (info_gshadow.audit_msg));
sgr = stpecpy(sgr, sgr_end, ", new password");
#endif
}
if (gflg) {
strncat (info_group.action, ", new gid: ",
511 - strlen (info_group.audit_msg));
(void) snprintf (info_group.action+strlen (info_group.action),
511 - strlen (info_group.audit_msg),
"%lu", (unsigned long int) group_newid);
gr = stpecpy(gr, gr_end, ", new gid: ");
stpeprintf(gr, gr_end, "%ju", (uintmax_t) group_newid);
strncat (info_passwd.action, ", new gid: ",
511 - strlen (info_passwd.audit_msg));
(void) snprintf (info_passwd.action+strlen (info_passwd.action),
511 - strlen (info_passwd.audit_msg),
"%lu", (unsigned long int) group_newid);
pw = stpecpy(pw, pw_end, ", new gid: ");
stpeprintf(pw, pw_end, "%ju", (uintmax_t) group_newid);
}
info_group.audit_msg[511] = '\0';
#ifdef SHADOWGRP
info_gshadow.audit_msg[511] = '\0';
#endif
info_passwd.audit_msg[511] = '\0';
// FIXME: add a system cleanup
add_cleanup (cleanup_report_mod_group, &info_group);
@@ -766,10 +751,6 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -780,7 +761,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("groupmod");
OPENLOG (Prog);
#ifdef WITH_AUDIT
audit_help_open ();
#endif
@@ -806,7 +787,7 @@ int main (int argc, char **argv)
exit (E_PAM_USERNAME);
}
retval = pam_start ("groupmod", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
@@ -849,28 +830,6 @@ int main (int argc, char **argv)
}
}
#ifdef USE_NIS
/*
* Now make sure it isn't an NIS group.
*/
if (__isgrNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: group %s is a NIS group\n"),
Prog, group_name);
if (!yp_get_default_domain (&nis_domain) &&
!yp_master (nis_domain, "group.byname", &nis_master)) {
fprintf (stderr,
_("%s: %s is the NIS master\n"),
Prog, nis_master);
}
exit (E_NOTFOUND);
}
#endif
if (gflg) {
check_new_gid ();
}
+5 -6
View File
@@ -14,13 +14,16 @@
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include "alloc.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "groups";
/* local function prototypes */
static void print_groups (const char *member);
@@ -88,16 +91,12 @@ int main (int argc, char **argv)
GETGROUPS_T *groups;
sys_ngroups = sysconf (_SC_NGROUPS_MAX);
groups = (GETGROUPS_T *) malloc (sizeof (GETGROUPS_T) * sys_ngroups);
groups = XMALLOC(sys_ngroups, GETGROUPS_T);
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
/*
* Get the program name so that error messages can use it.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
+6 -8
View File
@@ -43,7 +43,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "grpck";
static const char *grp_file = GROUP_FILE;
static bool use_system_grp_file = true;
@@ -62,7 +62,7 @@ static bool silence_warnings = false;
/* local function prototypes */
static void fail_exit (int status);
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void delete_member (char **, const char *);
static void process_flags (int argc, char **argv);
static void open_files (void);
@@ -114,7 +114,9 @@ static void fail_exit (int status)
/*
* usage - print syntax message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
#ifdef SHADOWGRP
@@ -814,10 +816,6 @@ int main (int argc, char **argv)
int errors = 0;
bool changed = false;
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -827,7 +825,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("grpck");
OPENLOG (Prog);
/* Parse the command line arguments */
process_flags (argc, argv);
+7 -5
View File
@@ -21,9 +21,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include "attr.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -36,7 +39,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "grpconv";
static bool gr_locked = false;
static bool sgr_locked = false;
@@ -123,7 +126,6 @@ int main (int argc, char **argv)
const struct sgrp *sg;
struct sgrp sgent;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -133,7 +135,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("grpconv");
OPENLOG (Prog);
process_flags (argc, argv);
@@ -198,7 +200,7 @@ int main (int argc, char **argv)
static char *empty = 0;
/* add new shadow group entry */
memset (&sgent, 0, sizeof sgent);
bzero(&sgent, sizeof sgent);
sgent.sg_name = gr->gr_name;
sgent.sg_passwd = gr->gr_passwd;
sgent.sg_adm = &empty;
@@ -259,7 +261,7 @@ int main (int argc, char **argv)
return 0;
}
#else /* !SHADOWGRP */
int main (int unused(argc), char **argv)
int main (MAYBE_UNUSED int argc, char **argv)
{
fprintf (stderr,
"%s: not configured for shadow group support.\n", argv[0]);
+5 -4
View File
@@ -24,6 +24,8 @@
#include <unistd.h>
#include <grp.h>
#include <getopt.h>
#include "attr.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -36,7 +38,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "grpunconv";
static bool gr_locked = false;
static bool sgr_locked = false;
@@ -122,7 +124,6 @@ int main (int argc, char **argv)
struct group grent;
const struct sgrp *sg;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -132,7 +133,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("grpunconv");
OPENLOG (Prog);
process_flags (argc, argv);
@@ -222,7 +223,7 @@ int main (int argc, char **argv)
return 0;
}
#else /* !SHADOWGRP */
int main (int unused(argc), char **argv)
int main (MAYBE_UNUSED int argc, char **argv)
{
fprintf (stderr,
"%s: not configured for shadow group support.\n", argv[0]);
+9 -6
View File
@@ -23,7 +23,10 @@
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include "alloc.h"
#include "defines.h"
/* local function prototypes */
static void usage (void);
@@ -33,7 +36,8 @@ static void usage (void)
exit (EXIT_FAILURE);
}
/*ARGSUSED*/ int main (int argc, char **argv)
int
main(int argc, char *argv[])
{
uid_t ruid, euid;
gid_t rgid, egid;
@@ -63,7 +67,7 @@ static void usage (void)
* work if the system library is recompiled.
*/
sys_ngroups = sysconf (_SC_NGROUPS_MAX);
groups = (GETGROUPS_T *) malloc (sizeof (GETGROUPS_T) * sys_ngroups);
groups = MALLOC(sys_ngroups, GETGROUPS_T);
/*
* See if the -a flag has been given to print out the concurrent
@@ -71,11 +75,10 @@ static void usage (void)
*/
if (argc > 1) {
if ((argc > 2) || (strcmp (argv[1], "-a") != 0)) {
usage ();
} else {
if (argc > 2 || strcmp(argv[1], "-a") != 0)
usage();
else
aflg = true;
}
}
ruid = getuid ();
+26 -21
View File
@@ -22,12 +22,16 @@
#ifdef HAVE_LL_HOST
#include <net/if.h>
#endif
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
#include "memzero.h"
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/strftime.h"
/*
* Needed for MkLinux DR1/2/2.1 - J.
@@ -39,7 +43,7 @@
/*
* Global variables
*/
const char *Prog; /* Program name */
static const char Prog[] = "lastlog"; /* Program name */
static FILE *lastlogfile; /* lastlog file stream */
static unsigned long umin; /* if uflg and has_umin, only display users with uid >= umin */
static bool has_umin = false;
@@ -50,15 +54,17 @@ static time_t inverse_seconds; /* that number of days in seconds */
static struct stat statbuf; /* fstat buffer for file size */
static bool uflg = false; /* print only an user of range of users */
static bool uflg = false; /* print only a user of range of users */
static bool tflg = false; /* print is restricted to most recent days */
static bool bflg = false; /* print excludes most recent days */
static bool Cflg = false; /* clear record for user */
static bool Sflg = false; /* set record for user */
#define NOW (time ((time_t *) 0))
#define NOW time(NULL)
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -67,7 +73,7 @@ static /*@noreturn@*/void usage (int status)
"Options:\n"),
Prog);
(void) fputs (_(" -b, --before DAYS print only lastlog records older than DAYS\n"), usageout);
(void) fputs (_(" -C, --clear clear lastlog record of an user (usable only with -u)\n"), usageout);
(void) fputs (_(" -C, --clear clear lastlog record of a user (usable only with -u)\n"), usageout);
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -S, --set set lastlog record to current time (usable only with -u)\n"), usageout);
@@ -114,10 +120,10 @@ static void print_one (/*@null@*/const struct passwd *pw)
* entered for this user, which should be able to get the
* empty entry in this case.
*/
if (fread ((char *) &ll, sizeof (ll), 1, lastlogfile) != 1) {
if (fread (&ll, sizeof (ll), 1, lastlogfile) != 1) {
fprintf (stderr,
_("%s: Failed to get the entry for UID %lu\n"),
Prog, (unsigned long int)pw->pw_uid);
Prog, (unsigned long)pw->pw_uid);
exit (EXIT_FAILURE);
}
} else {
@@ -141,7 +147,7 @@ static void print_one (/*@null@*/const struct passwd *pw)
/* Print the header only once */
if (!once) {
#ifdef HAVE_LL_HOST
printf (_("Username Port From%*sLatest\n"), maxIPv6Addrlen-3, " ");
printf (_("Username Port From%*sLatest\n"), maxIPv6Addrlen-4, " ");
#else
puts (_("Username Port Latest"));
#endif
@@ -153,7 +159,7 @@ static void print_one (/*@null@*/const struct passwd *pw)
if (tm == NULL) {
cp = "(unknown)";
} else {
strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm);
STRFTIME(ptime, "%a %b %e %H:%M:%S %z %Y", tm);
cp = ptime;
}
if (ll.ll_time == (time_t) 0) {
@@ -182,7 +188,7 @@ static void print (void)
}
if (uflg && has_umin && has_umax && (umin == umax)) {
print_one (getpwuid ((uid_t)umin));
print_one (getpwuid (umin));
} else {
setpwent ();
while ( (pwent = getpwent ()) != NULL ) {
@@ -225,21 +231,21 @@ static void update_one (/*@null@*/const struct passwd *pw)
#ifdef WITH_AUDIT
audit_logger (AUDIT_ACCT_UNLOCK, Prog,
"clearing-lastlog",
pw->pw_name, (unsigned int) pw->pw_uid, SHADOW_AUDIT_SUCCESS);
pw->pw_name, pw->pw_uid, SHADOW_AUDIT_SUCCESS);
#endif
}
#ifdef WITH_AUDIT
else {
audit_logger (AUDIT_ACCT_UNLOCK, Prog,
"refreshing-lastlog",
pw->pw_name, (unsigned int) pw->pw_uid, SHADOW_AUDIT_SUCCESS);
pw->pw_name, pw->pw_uid, SHADOW_AUDIT_SUCCESS);
}
#endif
if (fwrite (&ll, sizeof(ll), 1, lastlogfile) != 1) {
fprintf (stderr,
_("%s: Failed to update the entry for UID %lu\n"),
Prog, (unsigned long int)pw->pw_uid);
Prog, (unsigned long)pw->pw_uid);
exit (EXIT_FAILURE);
}
}
@@ -261,7 +267,7 @@ static void update (void)
}
if (has_umin && has_umax && (umin == umax)) {
update_one (getpwuid ((uid_t)umin));
update_one (getpwuid (umin));
} else {
setpwent ();
while ( (pwent = getpwent ()) != NULL ) {
@@ -288,7 +294,6 @@ int main (int argc, char **argv)
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -321,7 +326,7 @@ int main (int argc, char **argv)
case 'b':
{
unsigned long inverse_days;
if (getulong (optarg, &inverse_days) == 0) {
if (getulong(optarg, &inverse_days) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -349,7 +354,7 @@ int main (int argc, char **argv)
case 't':
{
unsigned long days;
if (getulong (optarg, &days) == 0) {
if (getulong(optarg, &days) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -373,14 +378,14 @@ int main (int argc, char **argv)
/* local, no need for xgetpwnam */
pwent = getpwnam (optarg);
if (NULL != pwent) {
umin = (unsigned long) pwent->pw_uid;
umin = pwent->pw_uid;
has_umin = true;
umax = umin;
has_umax = true;
} else {
if (getrange (optarg,
&umin, &has_umin,
&umax, &has_umax) == 0) {
if (getrange(optarg,
&umin, &has_umin,
&umax, &has_umax) == -1) {
fprintf (stderr,
_("%s: Unknown user or range: %s\n"),
Prog, optarg);
+112 -150
View File
@@ -14,7 +14,9 @@
#include <errno.h>
#include <grp.h>
#ifndef USE_PAM
#ifdef ENABLE_LASTLOG
#include <lastlog.h>
#endif /* ENABLE_LASTLOG */
#endif /* !USE_PAM */
#include <pwd.h>
#include <signal.h>
@@ -22,15 +24,23 @@
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <assert.h>
#include "alloc.h"
#include "attr.h"
#include "defines.h"
#include "faillog.h"
#include "failure.h"
#include "getdef.h"
#include "memzero.h"
#include "prototypes.h"
#include "pwauth.h"
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/strftime.h"
#include "string/strtcpy.h"
#ifdef USE_PAM
#include "pam_defs.h"
@@ -60,14 +70,16 @@ static pam_handle_t *pamh = NULL;
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "login";
static const char *hostname = "";
static /*@null@*/ /*@only@*/char *username = NULL;
static int reason = PW_LOGIN;
#ifndef USE_PAM
#ifdef ENABLE_LASTLOG
static struct lastlog ll;
#endif /* ENABLE_LASTLOG */
#endif /* !USE_PAM */
static bool pflg = false;
static bool fflg = false;
@@ -89,7 +101,6 @@ static char tmsg[256];
extern char **newenvp;
extern size_t newenvc;
extern char **environ;
#ifndef ALARM
#define ALARM 60
@@ -104,15 +115,6 @@ static void usage (void);
static void setup_tty (void);
static void process_flags (int argc, char *const *argv);
static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *user);
static void update_utmp (const char *user,
const char *tty,
const char *host,
#ifdef USE_UTMPX
/*@null@*/const struct utmpx *utent
#else
/*@null@*/const struct utmp *utent
#endif
);
#ifndef USE_PAM
static struct faillog faillog;
@@ -125,6 +127,7 @@ static void get_pam_user (char **ptr_pam_user);
static void init_env (void);
static void alarm_handler (int);
static void exit_handler (int);
/*
* usage - print login command usage and exit
@@ -172,10 +175,10 @@ static void setup_tty (void)
#endif
/* leave these values unchanged if not specified in login.defs */
erasechar = getdef_num ("ERASECHAR", (int) termio.c_cc[VERASE]);
killchar = getdef_num ("KILLCHAR", (int) termio.c_cc[VKILL]);
termio.c_cc[VERASE] = (cc_t) erasechar;
termio.c_cc[VKILL] = (cc_t) killchar;
erasechar = getdef_num ("ERASECHAR", termio.c_cc[VERASE]);
killchar = getdef_num ("KILLCHAR", termio.c_cc[VKILL]);
termio.c_cc[VERASE] = erasechar;
termio.c_cc[VKILL] = killchar;
/* Make sure the values were valid.
* getdef_num cannot validate this.
*/
@@ -396,13 +399,18 @@ static void init_env (void)
#endif /* !USE_PAM */
}
static void alarm_handler (unused int sig)
static void exit_handler (MAYBE_UNUSED int sig)
{
write (STDERR_FILENO, tmsg, strlen (tmsg));
_exit (0);
}
static void alarm_handler (MAYBE_UNUSED int sig)
{
write_full(STDERR_FILENO, tmsg, strlen(tmsg));
signal(SIGALRM, exit_handler);
alarm(2);
}
#ifdef USE_PAM
/*
* get_pam_user - Get the username according to PAM
@@ -411,17 +419,17 @@ static void alarm_handler (unused int sig)
*/
static void get_pam_user (char **ptr_pam_user)
{
int retcode;
void *ptr_user;
int retcode;
const void *ptr_user;
assert (NULL != ptr_pam_user);
retcode = pam_get_item (pamh, PAM_USER, (const void **)&ptr_user);
retcode = pam_get_item (pamh, PAM_USER, &ptr_user);
PAM_FAIL_CHECK;
free (*ptr_pam_user);
if (NULL != ptr_user) {
*ptr_pam_user = xstrdup ((const char *)ptr_user);
*ptr_pam_user = xstrdup (ptr_user);
} else {
*ptr_pam_user = NULL;
}
@@ -430,7 +438,7 @@ static void get_pam_user (char **ptr_pam_user)
/*
* get_failent_user - Return a string that can be used to log failure
* from an user.
* from a user.
*
* This will be either the user argument, or "UNKNOWN".
*
@@ -452,38 +460,6 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
return failent_user;
}
/*
* update_utmp - Update or create an utmp entry in utmp, wtmp, utmpw, and
* wtmpx
*
* utent should be the utmp entry returned by get_current_utmp (or
* NULL).
*/
static void update_utmp (const char *user,
const char *tty,
const char *host,
#ifdef USE_UTMPX
/*@null@*/const struct utmpx *utent
#else
/*@null@*/const struct utmp *utent
#endif
)
{
#ifdef USE_UTMPX
struct utmpx *utx = prepare_utmpx (user, tty, host, utent);
#else
struct utmp *ut = prepare_utmp (user, tty, host, utent);
#endif /* USE_UTMPX */
#ifndef USE_UTMPX
(void) setutmp (ut); /* make entry in the utmp & wtmp files */
free (ut);
#else
(void) setutmpx (utx); /* make entry in the utmpx & wtmpx files */
free (utx);
#endif /* USE_UTMPX */
}
/*
* login - create a new login session for a user
*
@@ -503,42 +479,36 @@ static void update_utmp (const char *user,
*/
int main (int argc, char **argv)
{
const char *tmptty;
char tty[BUFSIZ];
int err;
bool subroot = false;
char **envp = environ;
char *host = NULL;
char tty[BUFSIZ];
char fromhost[512];
const char *failent_user;
const char *tmptty;
const char *cp;
const char *tmp;
unsigned int delay;
unsigned int retries;
unsigned int timeout;
struct passwd *pwd = NULL;
#ifdef RLOGIN
char term[128] = "";
#endif /* RLOGIN */
#if !defined(USE_PAM)
char ptime[80];
#endif
unsigned int delay;
unsigned int retries;
bool subroot = false;
#ifndef USE_PAM
#if defined(USE_PAM)
int retcode;
char *pam_user = NULL;
pid_t child;
#else
bool is_console;
struct spwd *spwd = NULL;
# if defined(ENABLE_LASTLOG)
char ptime[80];
# endif
#endif
int err;
unsigned int timeout;
const char *cp;
const char *tmp;
char fromhost[512];
struct passwd *pwd = NULL;
char **envp = environ;
const char *failent_user;
#ifdef USE_UTMPX
/*@null@*/struct utmpx *utent;
#else
/*@null@*/struct utmp *utent;
#if defined(RLOGIN)
char term[128] = "";
#endif
#ifdef USE_PAM
int retcode;
pid_t child;
char *pam_user = NULL;
#else
struct spwd *spwd = NULL;
#endif
/*
* Some quick initialization.
*/
@@ -552,7 +522,6 @@ int main (int argc, char **argv)
initenv ();
amroot = (getuid () == 0);
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -567,25 +536,23 @@ int main (int argc, char **argv)
exit (1); /* must be a terminal */
}
utent = get_current_utmp ();
err = get_session_host(&host);
/*
* Be picky if run by normal users (possible if installed setuid
* root), but not if run by root. This way it still allows logins
* even if your getty is broken, or if something corrupts utmp,
* but users must "exec login" which will use the existing utmp
* entry (will not overwrite remote hostname). --marekm
* root), but not if run by root.
*/
if (!amroot && (NULL == utent)) {
(void) puts (_("No utmp entry. You must exec \"login\" from the lowest level \"sh\""));
if (!amroot && (err != 0)) {
SYSLOG ((LOG_ERR,
"No session entry, error %d. You must exec \"login\" from the lowest level \"sh\"",
err));
exit (1);
}
/* NOTE: utent might be NULL afterwards */
tmptty = ttyname (0);
if (NULL == tmptty) {
tmptty = "UNKNOWN";
}
STRFCPY (tty, tmptty);
STRTCPY(tty, tmptty);
#ifndef USE_PAM
is_console = console (tty);
@@ -606,10 +573,13 @@ int main (int argc, char **argv)
}
#ifdef RLOGIN
if (rflg) {
size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
assert (NULL == username);
username = xmalloc (USER_NAME_MAX_LENGTH + 1);
username[USER_NAME_MAX_LENGTH] = '\0';
if (do_rlogin (hostname, username, USER_NAME_MAX_LENGTH, term, sizeof term)) {
username = XMALLOC(max_size, char);
username[max_size - 1] = '\0';
if (do_rlogin(hostname, username, max_size, term, sizeof(term)))
{
preauth_flag = true;
} else {
free (username);
@@ -618,7 +588,7 @@ int main (int argc, char **argv)
}
#endif /* RLOGIN */
OPENLOG ("login");
OPENLOG (Prog);
setup_tty ();
@@ -674,27 +644,23 @@ int main (int argc, char **argv)
if (rflg || hflg) {
cp = hostname;
#if defined(HAVE_STRUCT_UTMP_UT_HOST) || defined(USE_UTMPX)
} else if ((NULL != utent) && ('\0' != utent->ut_host[0])) {
cp = utent->ut_host;
#endif /* HAVE_STRUCT_UTMP_UT_HOST */
} else if ((host != NULL) && (host[0] != '\0')) {
cp = host;
} else {
cp = "";
}
if ('\0' != *cp) {
snprintf (fromhost, sizeof fromhost,
" on '%.100s' from '%.200s'", tty, cp);
SNPRINTF(fromhost, " on '%.100s' from '%.200s'", tty, cp);
} else {
snprintf (fromhost, sizeof fromhost,
" on '%.100s'", tty);
SNPRINTF(fromhost, " on '%.100s'", tty);
}
free(host);
top:
/* only allow ALARM sec. for login */
timeout = getdef_unum ("LOGIN_TIMEOUT", ALARM);
snprintf (tmsg, sizeof tmsg,
_("\nLogin timed out after %u seconds.\n"), timeout);
SNPRINTF(tmsg, _("\nLogin timed out after %u seconds.\n"), timeout);
(void) signal (SIGALRM, alarm_handler);
if (timeout > 0) {
(void) alarm (timeout);
@@ -705,7 +671,7 @@ int main (int argc, char **argv)
retries = getdef_unum ("LOGIN_RETRIES", RETRIES);
#ifdef USE_PAM
retcode = pam_start ("login", username, &conv, &pamh);
retcode = pam_start (Prog, username, &conv, &pamh);
if (retcode != PAM_SUCCESS) {
fprintf (stderr,
_("login: PAM Failure, aborting: %s\n"),
@@ -733,18 +699,15 @@ int main (int argc, char **argv)
#endif
/* if fflg, then the user has already been authenticated */
if (!fflg) {
unsigned int failcount = 0;
char hostn[256];
char loginprompt[256]; /* That's one hell of a prompt :) */
char hostn[256];
char loginprompt[256]; //That's one hell of a prompt :)
unsigned int failcount = 0;
/* Make the login prompt look like we want it */
if (gethostname (hostn, sizeof (hostn)) == 0) {
snprintf (loginprompt,
sizeof (loginprompt),
_("%s login: "), hostn);
SNPRINTF(loginprompt, _("%s login: "), hostn);
} else {
strncpy (loginprompt, _("login: "),
sizeof (loginprompt));
STRTCPY(loginprompt, _("login: "));
}
retcode = pam_set_item (pamh, PAM_USER_PROMPT, loginprompt);
@@ -919,14 +882,16 @@ int main (int argc, char **argv)
failed = false; /* haven't failed authentication yet */
if (NULL == username) { /* need to get a login id */
size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
if (subroot) {
closelog ();
exit (1);
}
preauth_flag = false;
username = xmalloc (USER_NAME_MAX_LENGTH + 1);
username[USER_NAME_MAX_LENGTH] = '\0';
login_prompt (_("\n%s login: "), username, USER_NAME_MAX_LENGTH);
username = XMALLOC(max_size, char);
username[max_size - 1] = '\0';
login_prompt(username, max_size);
if ('\0' == username[0]) {
/* Prompt for a new login */
@@ -956,7 +921,8 @@ int main (int argc, char **argv)
}
if (strcmp (user_passwd, "") == 0) {
char *prevent_no_auth = getdef_str("PREVENT_NO_AUTH");
const char *prevent_no_auth = getdef_str("PREVENT_NO_AUTH");
if (prevent_no_auth == NULL) {
prevent_no_auth = "superuser";
}
@@ -992,7 +958,7 @@ int main (int argc, char **argv)
goto auth_ok;
}
if (pw_auth (user_passwd, username, reason, (char *) 0) == 0) {
if (pw_auth (user_passwd, username, reason, NULL) == 0) {
goto auth_ok;
}
@@ -1035,23 +1001,9 @@ int main (int argc, char **argv)
if ((NULL != pwd) && getdef_bool ("FAILLOG_ENAB")) {
failure (pwd->pw_uid, tty, &faillog);
}
if (getdef_str ("FTMP_FILE") != NULL) {
#ifdef USE_UTMPX
struct utmpx *failent =
prepare_utmpx (failent_user,
tty,
/* FIXME: or fromhost? */hostname,
utent);
#else /* !USE_UTMPX */
struct utmp *failent =
prepare_utmp (failent_user,
tty,
hostname,
utent);
#endif /* !USE_UTMPX */
failtmp (failent_user, failent);
free (failent);
}
#ifndef ENABLE_LOGIND
record_failure(failent_user, tty, hostname);
#endif /* ENABLE_LOGIND */
retries--;
if (retries <= 0) {
@@ -1067,7 +1019,7 @@ int main (int argc, char **argv)
* all). --marekm
*/
if (user_passwd[0] == '\0') {
pw_auth ("!", username, reason, (char *) 0);
pw_auth ("!", username, reason, NULL);
}
/*
@@ -1107,7 +1059,7 @@ int main (int argc, char **argv)
* by Ivan Nejgebauer <ian@unsux.ns.ac.yu>. --marekm
*/
if ( getdef_bool ("PORTTIME_CHECKS_ENAB")
&& !isttytime (username, tty, time ((time_t *) 0))) {
&& !isttytime (username, tty, time (NULL))) {
SYSLOG ((LOG_WARN, "invalid login time for '%s'%s",
username, fromhost));
closelog ();
@@ -1151,11 +1103,13 @@ int main (int argc, char **argv)
#endif /* WITH_AUDIT */
#ifndef USE_PAM /* pam_lastlog handles this */
#ifdef ENABLE_LASTLOG
if ( getdef_bool ("LASTLOG_ENAB")
&& pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)) {
/* give last login and log this one */
dolastlog (&ll, pwd, tty, hostname);
}
#endif /* ENABLE_LASTLOG */
#endif
#ifndef USE_PAM /* PAM handles this as well */
@@ -1220,11 +1174,16 @@ int main (int argc, char **argv)
}
}
#ifndef ENABLE_LOGIND
/*
* The utmp entry needs to be updated to indicate the new status
* of the session, the new PID and SID.
*/
update_utmp (username, tty, hostname, utent);
err = update_utmp (username, tty, hostname);
if (err != 0) {
SYSLOG ((LOG_WARN, "Unable to update utmp entry for %s", username));
}
#endif /* ENABLE_LOGIND */
/* The pwd and spwd entries for the user have been copied.
*
@@ -1289,14 +1248,16 @@ int main (int argc, char **argv)
username, (int) faillog.fail_cnt));
}
}
#ifdef ENABLE_LASTLOG
if ( getdef_bool ("LASTLOG_ENAB")
&& pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)
&& (ll.ll_time != 0)) {
time_t ll_time = ll.ll_time;
&& (ll.ll_time != 0))
{
time_t ll_time = ll.ll_time;
struct tm tm;
(void) strftime (ptime, sizeof (ptime),
"%a %b %e %H:%M:%S %z %Y",
localtime (&ll_time));
localtime_r(&ll_time, &tm);
STRFTIME(ptime, "%a %b %e %H:%M:%S %z %Y", &tm);
printf (_("Last login: %s on %s"),
ptime, ll.ll_line);
#ifdef HAVE_LL_HOST /* __linux__ || SUN4 */
@@ -1307,6 +1268,7 @@ int main (int argc, char **argv)
#endif
printf (".\n");
}
#endif /* ENABLE_LASTLOG */
agecheck (spwd);
mailcheck (); /* report on the status of mail */
@@ -1334,7 +1296,7 @@ int main (int argc, char **argv)
err = shell (tmp, pwd->pw_shell, newenvp); /* fake shell */
} else {
/* exec the shell finally */
err = shell (pwd->pw_shell, (char *) 0, newenvp);
err = shell (pwd->pw_shell, NULL, newenvp);
}
return ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
+39 -29
View File
@@ -39,12 +39,11 @@
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
*/
#include <sys/types.h>
#include <stddef.h>
#include <stdio.h>
#include <syslog.h>
#include <ctype.h>
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <grp.h>
#ifdef PRIMARY_GROUP_MATCH
#include <pwd.h>
@@ -57,6 +56,8 @@
#include <netinet/in.h>
#include <arpa/inet.h> /* for inet_ntoa() */
#include "sizeof.h"
#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64)
#undef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
@@ -98,11 +99,11 @@ int login_access (const char *user, const char *from)
if (NULL != fp) {
int lineno = 0; /* for diagnostics */
while ( !match
&& (fgets (line, (int) sizeof (line), fp) == line)) {
int end;
&& (fgets (line, sizeof (line), fp) == line)) {
ptrdiff_t end;
lineno++;
end = (int) strlen (line) - 1;
if (line[end] != '\n') {
end = strlen (line) - 1;
if (line[0] == '\0' || line[end] != '\n') {
SYSLOG ((LOG_ERR,
"%s: line %d: missing newline or line too long",
TABLE, lineno));
@@ -119,9 +120,9 @@ int login_access (const char *user, const char *from)
continue;
}
if ( ((perm = strtok (line, fs)) == NULL)
|| ((users = strtok ((char *) 0, fs)) == NULL)
|| ((froms = strtok ((char *) 0, fs)) == NULL)
|| (strtok ((char *) 0, fs) != NULL)) {
|| ((users = strtok (NULL, fs)) == NULL)
|| ((froms = strtok (NULL, fs)) == NULL)
|| (strtok (NULL, fs) != NULL)) {
SYSLOG ((LOG_ERR,
"%s: line %d: bad field count",
TABLE, lineno));
@@ -156,7 +157,7 @@ static bool list_match (char *list, const char *item, bool (*match_fn) (const ch
* a match, look for an "EXCEPT" list and recurse to determine whether
* the match is affected by any exceptions.
*/
for (tok = strtok (list, sep); tok != NULL; tok = strtok ((char *) 0, sep)) {
for (tok = strtok (list, sep); tok != NULL; tok = strtok (NULL, sep)) {
if (strcasecmp (tok, "EXCEPT") == 0) { /* EXCEPT: give up */
break;
}
@@ -168,10 +169,10 @@ static bool list_match (char *list, const char *item, bool (*match_fn) (const ch
/* Process exceptions to matches. */
if (match) {
while ( ((tok = strtok ((char *) 0, sep)) != NULL)
while ( ((tok = strtok (NULL, sep)) != NULL)
&& (strcasecmp (tok, "EXCEPT") != 0))
/* VOID */ ;
if (tok == 0 || !list_match ((char *) 0, item, match_fn)) {
if (tok == 0 || !list_match (NULL, item, match_fn)) {
return (match);
}
}
@@ -195,9 +196,9 @@ static char *myhostname (void)
static bool
netgroup_match (const char *group, const char *machine, const char *user)
{
static char *mydomain = (char *)0;
static char *mydomain = NULL;
if (mydomain == (char *)0) {
if (mydomain == NULL) {
static char domain[MAXHOSTNAMELEN + 1];
getdomainname (domain, MAXHOSTNAMELEN);
@@ -230,7 +231,7 @@ static bool user_match (const char *tok, const char *string)
&& from_match (at + 1, myhostname ()));
#if HAVE_INNETGR
} else if (tok[0] == '@') { /* netgroup */
return (netgroup_match (tok + 1, (char *) 0, string));
return (netgroup_match (tok + 1, NULL, string));
#endif
} else if (string_match (tok, string)) { /* ALL or exact match */
return true;
@@ -244,7 +245,7 @@ static bool user_match (const char *tok, const char *string)
}
#ifdef PRIMARY_GROUP_MATCH
/*
* If the string is an user whose initial GID matches the token,
* If the string is a user whose initial GID matches the token,
* accept it. May avoid excessively long lines in /etc/group.
* Radu-Adrian Feurdean <raf@licj.soroscj.ro>
*
@@ -265,19 +266,28 @@ static bool user_match (const char *tok, const char *string)
static const char *resolve_hostname (const char *string)
{
/*
* Resolve hostname to numeric IP address, as suggested
* by Dave Hagewood <admin@arrowweb.com>. --marekm
*/
struct hostent *hp;
int gai_err;
const char *addr_str;
struct addrinfo *addrs;
hp = gethostbyname (string);
if (NULL != hp) {
return inet_ntoa (*((struct in_addr *) *(hp->h_addr_list)));
static char host[MAXHOSTNAMELEN];
gai_err = getaddrinfo(string, NULL, NULL, &addrs);
if (gai_err != 0) {
SYSLOG ((LOG_ERR, "getaddrinfo(%s): %s", string, gai_strerror(gai_err)));
return string;
}
SYSLOG ((LOG_ERR, "%s - unknown host", string));
return string;
addr_str = host;
gai_err = getnameinfo(addrs[0].ai_addr, addrs[0].ai_addrlen,
host, NITEMS(host), NULL, 0, NI_NUMERICHOST);
if (gai_err != 0) {
SYSLOG ((LOG_ERR, "getnameinfo(%s): %s", string, gai_strerror(gai_err)));
addr_str = string;
}
freeaddrinfo(addrs);
return addr_str;
}
/* from_match - match a host or tty against a list of tokens */
@@ -296,7 +306,7 @@ static bool from_match (const char *tok, const char *string)
*/
#if HAVE_INNETGR
if (tok[0] == '@') { /* netgroup */
return (netgroup_match (tok + 1, string, (char *) 0));
return (netgroup_match (tok + 1, string, NULL));
} else
#endif
if (string_match (tok, string)) { /* ALL or exact match */
@@ -313,7 +323,7 @@ static bool from_match (const char *tok, const char *string)
if (strchr (string, '.') == NULL) {
return true;
}
} else if ( (tok[(tok_len = strlen (tok)) - 1] == '.') /* network */
} else if ( (tok[0] != '\0' && tok[(tok_len = strlen (tok)) - 1] == '.') /* network */
&& (strncmp (tok, resolve_hostname (string), tok_len) == 0)) {
return true;
}
@@ -337,5 +347,5 @@ static bool string_match (const char *tok, const char *string)
}
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !USE_PAM */
+37 -59
View File
@@ -15,13 +15,16 @@
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utmpx.h>
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "sizeof.h"
#include "string/zustr2stp.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "logoutd";
#ifndef DEFAULT_HUP_MESG
#define DEFAULT_HUP_MESG _("login time exceeded\n\n")
@@ -31,38 +34,31 @@ const char *Prog;
#define HUP_MESG_FILE "/etc/logoutd.mesg"
#endif
/* local function prototypes */
#ifdef USE_UTMPX
static int check_login (const struct utmpx *ut);
#else /* !USE_UTMPX */
static int check_login (const struct utmp *ut);
#endif /* !USE_UTMPX */
static void send_mesg_to_tty (int tty_fd);
/*
* check_login - check if user (struct utmpx/utmp) allowed to stay logged in
*/
#ifdef USE_UTMPX
static int check_login (const struct utmpx *ut)
#else /* !USE_UTMPX */
static int check_login (const struct utmp *ut)
#endif /* !USE_UTMPX */
{
char user[sizeof (ut->ut_user) + 1];
time_t now;
/*
* ut_user may not have the terminating NUL.
*/
strncpy (user, ut->ut_user, sizeof (ut->ut_user));
user[sizeof (ut->ut_user)] = '\0';
/*
* check_login - check if user (struct utmpx) allowed to stay logged in
*/
static int
check_login(const struct utmpx *ut)
{
char user[sizeof(ut->ut_user) + 1];
char line[sizeof(ut->ut_line) + 1];
time_t now;
ZUSTR2STP(user, ut->ut_user);
ZUSTR2STP(line, ut->ut_line);
(void) time (&now);
/*
* Check if they are allowed to be logged in right now.
*/
if (!isttytime (user, ut->ut_line, now)) {
if (!isttytime(user, line, now)) {
return 0;
}
return 1;
@@ -116,23 +112,20 @@ static void send_mesg_to_tty (int tty_fd)
*
* logoutd is started at system boot time and enforces the login
* time and port restrictions specified in /etc/porttime. The
* utmpx/utmp file is periodically scanned and offending users are logged
* utmp file is periodically scanned and offending users are logged
* off from the system.
*/
int main (int argc, char **argv)
int
main(int argc, char **argv)
{
int i;
int status;
pid_t pid;
int i;
int status;
pid_t pid;
#ifdef USE_UTMPX
struct utmpx *ut;
#else /* !USE_UTMPX */
struct utmp *ut;
#endif /* !USE_UTMPX */
char user[sizeof (ut->ut_user) + 1]; /* terminating NUL */
char tty_name[sizeof (ut->ut_line) + 6]; /* /dev/ + NUL */
int tty_fd;
struct utmpx *ut;
char user[sizeof (ut->ut_user) + 1]; /* terminating NUL */
char tty_name[sizeof (ut->ut_line) + 6]; /* /dev/ + NUL */
int tty_fd;
if (1 != argc) {
(void) fputs (_("Usage: logoutd\n"), stderr);
@@ -164,39 +157,29 @@ int main (int argc, char **argv)
/*
* Start syslogging everything
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
OPENLOG ("logoutd");
OPENLOG (Prog);
/*
* Scan the utmpx/utmp file once per minute looking for users that
* Scan the utmp file once per minute looking for users that
* are not supposed to still be logged in.
*/
while (true) {
/*
* Attempt to re-open the utmpx/utmp file. The file is only
* Attempt to re-open the utmp file. The file is only
* open while it is being used.
*/
#ifdef USE_UTMPX
setutxent ();
#else /* !USE_UTMPX */
setutent ();
#endif /* !USE_UTMPX */
setutxent();
/*
* Read all of the entries in the utmpx/utmp file. The entries
* Read all of the entries in the utmp file. The entries
* for login sessions will be checked to see if the user
* is permitted to be signed on at this time.
*/
#ifdef USE_UTMPX
while ((ut = getutxent ()) != NULL)
#else /* !USE_UTMPX */
while ((ut = getutent ()) != NULL)
#endif /* !USE_UTMPX */
{
while ((ut = getutxent()) != NULL) {
if (ut->ut_type != USER_PROCESS) {
continue;
}
@@ -228,7 +211,7 @@ int main (int argc, char **argv)
tty_name[0] = '\0';
}
strncat (tty_name, ut->ut_line, UT_LINESIZE);
strncat(tty_name, ut->ut_line, NITEMS(ut->ut_line));
#ifndef O_NOCTTY
#define O_NOCTTY 0
#endif
@@ -246,8 +229,7 @@ int main (int argc, char **argv)
kill (-ut->ut_pid, SIGKILL);
}
strncpy (user, ut->ut_user, sizeof (user) - 1);
user[sizeof (user) - 1] = '\0';
ZUSTR2STP(user, ut->ut_user);
SYSLOG ((LOG_NOTICE,
"logged off user '%s' on '%s'", user,
@@ -259,11 +241,7 @@ int main (int argc, char **argv)
exit (EXIT_SUCCESS);
}
#ifdef USE_UTMPX
endutxent ();
#else /* !USE_UTMPX */
endutent ();
#endif /* !USE_UTMPX */
endutxent();
#ifndef DEBUG
sleep (60);
+1 -2
View File
@@ -9,7 +9,7 @@
/* Test program for the subid creation routine */
const char *Prog;
static const char Prog[] = "new_subid_range";
static void usage(void)
{
@@ -28,7 +28,6 @@ int main(int argc, char *argv[])
bool group = false; // get subuids by default
bool ok;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
while ((c = getopt(argc, argv, "gn")) != EOF) {
+19 -29
View File
@@ -23,7 +23,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "newgidmap";
static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups)
@@ -69,7 +69,7 @@ static void verify_ranges(struct passwd *pw, int ranges,
static void usage(void)
{
fprintf(stderr, _("usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
fprintf(stderr, _("usage: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
exit(EXIT_FAILURE);
}
@@ -143,18 +143,14 @@ out:
*/
int main(int argc, char **argv)
{
char proc_dir_name[32];
char *target_str;
pid_t target;
int proc_dir_fd;
int ranges;
struct map_range *mappings;
struct stat st;
struct passwd *pw;
int written;
bool allow_setgroups = false;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -168,25 +164,19 @@ int main(int argc, char **argv)
/* Find the process that needs its user namespace
* gid mapping set.
*/
target_str = argv[1];
if (!get_pid(target_str, &target))
usage();
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
target);
if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
Prog, strerror(errno));
if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) {
/* the user passed in a /proc/pid fd for the process */
target_str = &target_str[3];
proc_dir_fd = get_pidfd_from_fd(target_str);
if (proc_dir_fd < 0)
usage();
} else {
proc_dir_fd = open_pidfd(target_str);
if (proc_dir_fd < 0)
usage();
}
proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
if (proc_dir_fd < 0) {
fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
Prog, target);
return EXIT_FAILURE;
}
/* Who am i? */
pw = get_my_pwent ();
if (NULL == pw) {
@@ -200,8 +190,8 @@ int main(int argc, char **argv)
/* Get the effective uid and effective gid of the target process */
if (fstat(proc_dir_fd, &st) < 0) {
fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
Prog, target);
fprintf(stderr, _("%s: Could not stat directory for process\n"),
Prog);
return EXIT_FAILURE;
}
@@ -213,10 +203,10 @@ int main(int argc, char **argv)
(!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) ||
(pw->pw_uid != st.st_uid) ||
(getgid() != st.st_gid)) {
fprintf(stderr, _( "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
Prog, target,
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
Prog,
(unsigned long)getuid(), (unsigned long)pw->pw_uid, (unsigned long)st.st_uid,
(unsigned long)getgid(), (unsigned long)pw->pw_gid, (unsigned long)st.st_gid);
return EXIT_FAILURE;
}
+58 -69
View File
@@ -16,20 +16,24 @@
#include <pwd.h>
#include <stdio.h>
#include <assert.h>
#include "agetpass.h"
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/sprintf.h"
/*
* Global variables
*/
const char *Prog;
static const char *Prog;
extern char **newenvp;
extern char **environ;
#ifdef HAVE_SETGROUPS
static int ngroups;
@@ -158,7 +162,7 @@ static void check_perms (const struct group *grp,
* get the password from her, and set the salt for
* the decryption from the group file.
*/
cp = getpass (_("Password: "));
cp = agetpass (_("Password: "));
if (NULL == cp) {
goto failure;
}
@@ -169,7 +173,7 @@ static void check_perms (const struct group *grp,
* must match the previously encrypted value in the file.
*/
cpasswd = pw_encrypt (cp, grp->gr_passwd);
strzero (cp);
erase_pass (cp);
if (NULL == cpasswd) {
fprintf (stderr,
@@ -184,12 +188,10 @@ static void check_perms (const struct group *grp,
if (grp->gr_passwd[0] == '\0' ||
strcmp (cpasswd, grp->gr_passwd) != 0) {
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
"authentication new-gid=%lu",
(unsigned long) grp->gr_gid);
SNPRINTF(audit_buf, "authentication new-gid=%lu",
(unsigned long) grp->gr_gid);
audit_logger (AUDIT_GRP_AUTH, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
#endif
SYSLOG ((LOG_INFO,
"Invalid password for group '%s' from '%s'",
@@ -199,12 +201,10 @@ static void check_perms (const struct group *grp,
goto failure;
}
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
"authentication new-gid=%lu",
(unsigned long) grp->gr_gid);
SNPRINTF(audit_buf, "authentication new-gid=%lu",
(unsigned long) grp->gr_gid);
audit_logger (AUDIT_GRP_AUTH, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 1);
audit_buf, NULL, getuid (), 1);
#endif
}
@@ -217,21 +217,17 @@ failure:
closelog ();
#ifdef WITH_AUDIT
if (groupname) {
snprintf (audit_buf, sizeof(audit_buf),
"changing new-group=%s", groupname);
SNPRINTF(audit_buf, "changing new-group=%s", groupname);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
} else {
audit_logger (AUDIT_CHGRP_ID, Prog,
"changing", NULL,
(unsigned int) getuid (), 0);
"changing", NULL, getuid (), 0);
}
#endif
exit (EXIT_FAILURE);
}
#ifdef USE_SYSLOG
/*
* syslog_sg - log the change of group to syslog
*
@@ -292,6 +288,9 @@ static void syslog_sg (const char *name, const char *group)
(void) signal (SIGTSTP, SIG_IGN);
(void) signal (SIGTTIN, SIG_IGN);
(void) signal (SIGTTOU, SIG_IGN);
/* set SIGCHLD to default for waitpid */
(void) signal(SIGCHLD, SIG_DFL);
child = fork ();
if ((pid_t)-1 == child) {
/* error in fork() */
@@ -299,15 +298,13 @@ static void syslog_sg (const char *name, const char *group)
is_newgrp ? "newgrp" : "sg", strerror (errno));
#ifdef WITH_AUDIT
if (group) {
snprintf (audit_buf, sizeof(audit_buf),
"changing new-group=%s", group);
SNPRINTF(audit_buf,
"changing new-group=%s", group);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
} else {
audit_logger (AUDIT_CHGRP_ID, Prog,
"changing", NULL,
(unsigned int) getuid (), 0);
"changing", NULL, getuid (), 0);
}
#endif
exit (EXIT_FAILURE);
@@ -365,7 +362,6 @@ static void syslog_sg (const char *name, const char *group)
free(free_login);
free(free_tty);
}
#endif /* USE_SYSLOG */
/*
* newgrp - change the invokers current real and effective group id
@@ -394,12 +390,15 @@ int main (int argc, char **argv)
#ifdef WITH_AUDIT
audit_help_open ();
#endif
check_fds ();
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
/*
* Save my name for error messages and save my real gid incase of
* Save my name for error messages and save my real gid in case of
* errors. If there is an error i have to exec a new login shell for
* the user since her old shell won't have fork'd to create the
* process. Skip over the program name to the next command line
@@ -421,11 +420,18 @@ int main (int argc, char **argv)
* but we do not need to restore the previous process persona and we
* don't need to re-exec anything. -- JWP
*/
Prog = Basename (argv[0]);
/*
* Ensure that "Prog" is always either "newgrp" or "sg" to avoid
* injecting arbitrary strings into our stderr/stdout, as this can
* be an exploit vector.
*/
is_newgrp = (strcmp (Basename (argv[0]), "newgrp") == 0);
Prog = is_newgrp ? "newgrp" : "sg";
log_set_progname(Prog);
log_set_logfd(stderr);
is_newgrp = (strcmp (Prog, "newgrp") == 0);
OPENLOG (is_newgrp ? "newgrp" : "sg");
OPENLOG (Prog);
argc--;
argv++;
@@ -437,8 +443,7 @@ int main (int argc, char **argv)
Prog);
#ifdef WITH_AUDIT
audit_logger (AUDIT_CHGRP_ID, Prog,
"changing", NULL,
(unsigned int) getuid (), 0);
"changing", NULL, getuid (), 0);
#endif
SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
(unsigned long) getuid ()));
@@ -507,7 +512,7 @@ int main (int argc, char **argv)
if ((argc > 0) && (argv[0][0] == '-')) {
usage ();
goto failure;
} else if (argv[0] != (char *) 0) {
} else if (argv[0] != NULL) {
group = argv[0];
} else {
/*
@@ -541,7 +546,7 @@ int main (int argc, char **argv)
/* don't use getgroups(0, 0) - it doesn't work on some systems */
i = 16;
for (;;) {
grouplist = (GETGROUPS_T *) xmalloc (i * sizeof (GETGROUPS_T));
grouplist = XMALLOC(i, GETGROUPS_T);
ngroups = getgroups (i, grouplist);
if (i > ngroups && !(ngroups == -1 && errno == EINVAL)) {
break;
@@ -554,15 +559,12 @@ int main (int argc, char **argv)
perror ("getgroups");
#ifdef WITH_AUDIT
if (group) {
snprintf (audit_buf, sizeof(audit_buf),
"changing new-group=%s", group);
SNPRINTF(audit_buf, "changing new-group=%s", group);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
} else {
audit_logger (AUDIT_CHGRP_ID, Prog,
"changing", NULL,
(unsigned int) getuid (), 0);
"changing", NULL, getuid (), 0);
}
#endif
exit (EXIT_FAILURE);
@@ -628,7 +630,7 @@ int main (int argc, char **argv)
}
#endif /* HAVE_SETGROUPS */
/*
* For splitted groups (due to limitations of NIS), check all
* For split groups (due to limitations of NIS), check all
* groups of the same GID like the requested group for
* membership of the current user.
*/
@@ -665,11 +667,9 @@ int main (int argc, char **argv)
* all successful validations pass through this point. The group id
* will be set, and the group added to the concurrent groupset.
*/
#ifdef USE_SYSLOG
if (getdef_bool ("SYSLOG_SG_ENAB")) {
syslog_sg (name, group);
}
#endif /* USE_SYSLOG */
gid = grp->gr_gid;
@@ -718,11 +718,9 @@ int main (int argc, char **argv)
if (setgid (gid) != 0) {
perror ("setgid");
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
"changing new-gid=%lu", (unsigned long) gid);
SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
#endif
exit (EXIT_FAILURE);
}
@@ -730,11 +728,9 @@ int main (int argc, char **argv)
if (setuid (getuid ()) != 0) {
perror ("setuid");
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
"changing new-gid=%lu", (unsigned long) gid);
SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
#endif
exit (EXIT_FAILURE);
}
@@ -745,13 +741,11 @@ int main (int argc, char **argv)
*/
if (cflag) {
closelog ();
execl (SHELL, "sh", "-c", command, (char *) 0);
execl (SHELL, "sh", "-c", command, (char *) NULL);
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf),
"changing new-gid=%lu", (unsigned long) gid);
SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
#endif
perror (SHELL);
exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
@@ -815,17 +809,15 @@ int main (int argc, char **argv)
}
#ifdef WITH_AUDIT
snprintf (audit_buf, sizeof(audit_buf), "changing new-gid=%lu",
(unsigned long) gid);
SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 1);
audit_buf, NULL, getuid (), 1);
#endif
/*
* Exec the login shell and go away. We are trying to get back to
* the previous environment which should be the user's login shell.
*/
err = shell (prog, initflag ? (char *) 0 : progbase, newenvp);
err = shell (prog, initflag ? NULL : progbase, newenvp);
exit ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
/*@notreached@*/
failure:
@@ -843,15 +835,12 @@ int main (int argc, char **argv)
closelog ();
#ifdef WITH_AUDIT
if (NULL != group) {
snprintf (audit_buf, sizeof(audit_buf),
"changing new-group=%s", group);
SNPRINTF(audit_buf, "changing new-group=%s", group);
audit_logger (AUDIT_CHGRP_ID, Prog,
audit_buf, NULL,
(unsigned int) getuid (), 0);
audit_buf, NULL, getuid (), 0);
} else {
audit_logger (AUDIT_CHGRP_ID, Prog,
"changing", NULL,
(unsigned int) getuid (), 0);
"changing", NULL, getuid (), 0);
}
#endif
exit (EXIT_FAILURE);
+18 -29
View File
@@ -23,7 +23,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "newuidmap";
static bool verify_range(struct passwd *pw, struct map_range *range)
{
@@ -64,7 +64,7 @@ static void verify_ranges(struct passwd *pw, int ranges,
static void usage(void)
{
fprintf(stderr, _("usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
fprintf(stderr, _("usage: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
exit(EXIT_FAILURE);
}
@@ -73,17 +73,13 @@ static void usage(void)
*/
int main(int argc, char **argv)
{
char proc_dir_name[32];
char *target_str;
pid_t target;
int proc_dir_fd;
int ranges;
struct map_range *mappings;
struct stat st;
struct passwd *pw;
int written;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -94,26 +90,20 @@ int main(int argc, char **argv)
if (argc < 2)
usage();
target_str = argv[1];
/* Find the process that needs its user namespace
* uid mapping set.
*/
target_str = argv[1];
if (!get_pid(target_str, &target))
usage();
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
target);
if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
Prog, strerror(errno));
}
proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
if (proc_dir_fd < 0) {
fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
Prog, target);
return EXIT_FAILURE;
if (strlen(target_str) > 3 && strncmp(target_str, "fd:", 3) == 0) {
/* the user passed in a /proc/pid fd for the process */
target_str = &target_str[3];
proc_dir_fd = get_pidfd_from_fd(target_str);
if (proc_dir_fd < 0)
usage();
} else {
proc_dir_fd = open_pidfd(target_str);
if (proc_dir_fd < 0)
usage();
}
/* Who am i? */
@@ -129,8 +119,7 @@ int main(int argc, char **argv)
/* Get the effective uid and effective gid of the target process */
if (fstat(proc_dir_fd, &st) < 0) {
fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
Prog, target);
fprintf(stderr, _("%s: Could not stat directory for target process\n"), Prog);
return EXIT_FAILURE;
}
@@ -142,10 +131,10 @@ int main(int argc, char **argv)
(!getdef_bool("GRANT_AUX_GROUP_SUBIDS") && (getgid() != pw->pw_gid)) ||
(pw->pw_uid != st.st_uid) ||
(getgid() != st.st_gid)) {
fprintf(stderr, _( "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
Prog, target,
(unsigned long int)getuid(), (unsigned long int)pw->pw_uid, (unsigned long int)st.st_uid,
(unsigned long int)getgid(), (unsigned long int)pw->pw_gid, (unsigned long int)st.st_gid);
fprintf(stderr, _( "%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n" ),
Prog,
(unsigned long)getuid(), (unsigned long)pw->pw_uid, (unsigned long)st.st_uid,
(unsigned long)getgid(), (unsigned long)pw->pw_gid, (unsigned long)st.st_gid);
return EXIT_FAILURE;
}
+96 -95
View File
@@ -29,6 +29,8 @@
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include "alloc.h"
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
@@ -48,17 +50,19 @@
#endif /* ENABLE_SUBIDS */
#include "chkname.h"
#include "shadowlog.h"
#include "string/sprintf.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "newusers";
static bool rflg = false; /* create a system account */
#ifndef USE_PAM
static /*@null@*//*@observer@*/char *crypt_method = NULL;
#define cflg (NULL != crypt_method)
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT)
#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT)
static bool sflg = false;
#endif
#ifdef USE_SHA_CRYPT
@@ -88,8 +92,8 @@ static bool sub_gid_locked = false;
#endif /* ENABLE_SUBIDS */
/* local function prototypes */
static void usage (int status);
static void fail_exit (int);
NORETURN static void usage (int status);
NORETURN static void fail_exit (int);
static int add_group (const char *, const char *, gid_t *, gid_t);
static int get_user_id (const char *, uid_t *);
static int add_user (const char *, uid_t, gid_t);
@@ -235,7 +239,7 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid)
* new group, or an existing group.
*/
if (get_gid (gid, &grent.gr_gid) == 0) {
if (get_gid(gid, &grent.gr_gid) == -1) {
fprintf (stderr,
_("%s: invalid group ID '%s'\n"),
Prog, gid);
@@ -245,11 +249,11 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid)
/* Look in both the system database (getgrgid) and in the
* internal database (gr_locate_gid), which may contain
* uncommitted changes */
if ( (getgrgid ((gid_t) grent.gr_gid) != NULL)
|| (gr_locate_gid ((gid_t) grent.gr_gid) != NULL)) {
if ( (getgrgid (grent.gr_gid) != NULL)
|| (gr_locate_gid (grent.gr_gid) != NULL)) {
/* The user will use this ID for her
* primary group */
*ngid = (gid_t) grent.gr_gid;
*ngid = grent.gr_gid;
return 0;
}
@@ -339,7 +343,7 @@ static int get_user_id (const char *uid, uid_t *nuid) {
* caller provided, or the next available UID.
*/
if (isdigit (uid[0])) {
if ((get_uid (uid, nuid) == 0) || (*nuid == (uid_t)-1)) {
if ((get_uid(uid, nuid) == -1) || (*nuid == (uid_t)-1)) {
fprintf (stderr,
_("%s: invalid user ID '%s'\n"),
Prog, uid);
@@ -350,22 +354,20 @@ static int get_user_id (const char *uid, uid_t *nuid) {
const struct passwd *pwd;
/* local, no need for xgetpwnam */
pwd = getpwnam (uid);
if (NULL == pwd) {
if (pwd == NULL)
pwd = pw_locate (uid);
}
if (NULL != pwd) {
*nuid = pwd->pw_uid;
} else {
if (pwd == NULL) {
fprintf (stderr,
_("%s: user '%s' does not exist\n"),
Prog, uid);
return -1;
}
*nuid = pwd->pw_uid;
} else {
if (find_new_uid (rflg, nuid, NULL) < 0) {
if (find_new_uid (rflg, nuid, NULL) < 0)
return -1;
}
}
}
@@ -527,7 +529,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
}
spent.sp_pwdp = cp;
}
spent.sp_lstchg = (long) gettime () / SCALE;
spent.sp_lstchg = gettime () / DAY;
if (0 == spent.sp_lstchg) {
/* Better disable aging than requiring a password
* change */
@@ -584,7 +586,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
*/
spent.sp_pwdp = "!";
#endif
spent.sp_lstchg = (long) gettime () / SCALE;
spent.sp_lstchg = gettime () / DAY;
if (0 == spent.sp_lstchg) {
/* Better disable aging than requiring a password change */
spent.sp_lstchg = -1;
@@ -662,21 +664,28 @@ static void process_flags (int argc, char **argv)
case 's':
sflg = true;
bad_s = 0;
if (!crypt_method){
fprintf(stderr,
_("%s: Provide '--crypt-method' before number of rounds\n"),
Prog);
usage (EXIT_FAILURE);
}
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (0 == getlong(optarg, &sha_rounds)))) {
&& (-1 == getlong(optarg, &sha_rounds)))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (0 == getlong(optarg, &bcrypt_rounds)))) {
&& (-1 == getlong(optarg, &bcrypt_rounds)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (0 == getlong(optarg, &yescrypt_cost)))) {
&& (-1 == getlong(optarg, &yescrypt_cost)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */
@@ -702,8 +711,9 @@ static void process_flags (int argc, char **argv)
if (argv[optind] != NULL) {
if (freopen (argv[optind], "r", stdin) == NULL) {
char buf[BUFSIZ];
snprintf (buf, sizeof buf, "%s: %s", Prog, argv[1]);
char buf[BUFSIZ];
SNPRINTF(buf, "%s: %s", Prog, argv[1]);
perror (buf);
fail_exit (EXIT_FAILURE);
}
@@ -1039,7 +1049,6 @@ int main (int argc, char **argv)
char *cp;
const struct passwd *pw;
struct passwd newpw;
int errors = 0;
int line = 0;
uid_t uid;
gid_t gid;
@@ -1050,7 +1059,6 @@ int main (int argc, char **argv)
unsigned int nusers = 0;
#endif /* USE_PAM */
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -1088,19 +1096,16 @@ int main (int argc, char **argv)
* over 100 is allocated. The pw_gid field will be updated with that
* value.
*/
while (fgets (buf, (int) sizeof buf, stdin) != (char *) 0) {
while (fgets (buf, sizeof buf, stdin) != NULL) {
line++;
cp = strrchr (buf, '\n');
if (NULL != cp) {
if (cp == NULL && feof (stdin) == 0) {
fprintf (stderr, _("%s: line %d: line too long\n"),
Prog, line);
fail_exit (EXIT_FAILURE);
}
if (cp != NULL) {
*cp = '\0';
} else {
if (feof (stdin) == 0) {
fprintf (stderr,
_("%s: line %d: line too long\n"),
Prog, line);
errors++;
continue;
}
}
/*
@@ -1111,39 +1116,35 @@ int main (int argc, char **argv)
for (cp = buf, nfields = 0; nfields < 7; nfields++) {
fields[nfields] = cp;
cp = strchr (cp, ':');
if (NULL != cp) {
*cp = '\0';
cp++;
} else {
if (cp == NULL)
break;
}
*cp = '\0';
cp++;
}
if (nfields != 6) {
fprintf (stderr, _("%s: line %d: invalid line\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
/*
* First check if we have to create or update an user
* First check if we have to create or update a user
*/
pw = pw_locate (fields[0]);
/* local, no need for xgetpwnam */
if ( (NULL == pw)
&& (getpwnam (fields[0]) != NULL)) {
fprintf (stderr, _("%s: cannot update the entry of user %s (not in the passwd database)\n"), Prog, fields[0]);
errors++;
continue;
if (NULL == pw && getpwnam(fields[0]) != NULL) {
fprintf (stderr,
_("%s: cannot update the entry of user %s (not in the passwd database)\n"),
Prog, fields[0]);
fail_exit (EXIT_FAILURE);
}
if ( (NULL == pw)
&& (get_user_id (fields[2], &uid) != 0)) {
if (NULL == pw && get_user_id(fields[2], &uid) != 0) {
fprintf (stderr,
_("%s: line %d: can't create user\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
/*
@@ -1163,8 +1164,7 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: line %d: can't create group\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
/*
@@ -1179,8 +1179,7 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: line %d: can't create user\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
/*
@@ -1192,17 +1191,22 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: line %d: user '%s' does not exist in %s\n"),
Prog, line, fields[0], pw_dbname ());
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
newpw = *pw;
#ifdef USE_PAM
/* keep the list of user/password for later update by PAM */
nusers++;
lines = realloc (lines, sizeof (lines[0]) * nusers);
usernames = realloc (usernames, sizeof (usernames[0]) * nusers);
passwords = realloc (passwords, sizeof (passwords[0]) * nusers);
lines = REALLOCF(lines, nusers, int);
usernames = REALLOCF(usernames, nusers, char *);
passwords = REALLOCF(passwords, nusers, char *);
if (lines == NULL || usernames == NULL || passwords == NULL) {
fprintf (stderr,
_("%s: line %d: %s\n"),
Prog, line, strerror(errno));
fail_exit (EXIT_FAILURE);
}
lines[nusers-1] = line;
usernames[nusers-1] = strdup (fields[0]);
passwords[nusers-1] = strdup (fields[1]);
@@ -1211,8 +1215,7 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: line %d: can't update password\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
if ('\0' != fields[4][0]) {
newpw.pw_gecos = fields[4];
@@ -1235,21 +1238,24 @@ int main (int argc, char **argv)
fprintf(stderr,
_("%s: line %d: homedir must be an absolute path\n"),
Prog, line);
errors++;
continue;
};
fail_exit (EXIT_FAILURE);
}
if (mkdir (newpw.pw_dir, mode) != 0) {
fprintf (stderr,
_("%s: line %d: mkdir %s failed: %s\n"),
Prog, line, newpw.pw_dir,
strerror (errno));
} else if (chown (newpw.pw_dir,
newpw.pw_uid,
newpw.pw_gid) != 0) {
if (errno != EEXIST) {
fail_exit (EXIT_FAILURE);
}
}
if (chown(newpw.pw_dir, newpw.pw_uid, newpw.pw_gid) != 0)
{
fprintf (stderr,
_("%s: line %d: chown %s failed: %s\n"),
Prog, line, newpw.pw_dir,
strerror (errno));
fail_exit (EXIT_FAILURE);
}
}
@@ -1260,8 +1266,7 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: line %d: can't update entry\n"),
Prog, line);
errors++;
continue;
fail_exit (EXIT_FAILURE);
}
#ifdef ENABLE_SUBIDS
@@ -1271,17 +1276,19 @@ int main (int argc, char **argv)
if (is_sub_uid && want_subuids() && !local_sub_uid_assigned(fields[0])) {
uid_t sub_uid_start = 0;
unsigned long sub_uid_count = 0;
if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) == 0) {
if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0) {
fprintf (stderr,
_("%s: failed to prepare new %s entry\n"),
Prog, sub_uid_dbname ());
}
} else {
if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) != 0)
{
fprintf (stderr,
_("%s: can't find subordinate user range\n"),
Prog);
errors++;
fail_exit (EXIT_FAILURE);
}
if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0)
{
fprintf (stderr,
_("%s: failed to prepare new %s entry\n"),
Prog, sub_uid_dbname ());
fail_exit (EXIT_FAILURE);
}
}
@@ -1291,17 +1298,17 @@ int main (int argc, char **argv)
if (is_sub_gid && want_subgids() && !local_sub_gid_assigned(fields[0])) {
gid_t sub_gid_start = 0;
unsigned long sub_gid_count = 0;
if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) == 0) {
if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) {
fprintf (stderr,
_("%s: failed to prepare new %s entry\n"),
Prog, sub_uid_dbname ());
}
} else {
if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) != 0) {
fprintf (stderr,
_("%s: can't find subordinate group range\n"),
Prog);
errors++;
fail_exit (EXIT_FAILURE);
}
if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) {
fprintf (stderr,
_("%s: failed to prepare new %s entry\n"),
Prog, sub_uid_dbname ());
fail_exit (EXIT_FAILURE);
}
}
#endif /* ENABLE_SUBIDS */
@@ -1314,12 +1321,6 @@ int main (int argc, char **argv)
* changes to be written out all at once, and then unlocked
* afterwards.
*/
if (0 != errors) {
fprintf (stderr,
_("%s: error detected, changes ignored\n"), Prog);
fail_exit (EXIT_FAILURE);
}
close_files ();
nscd_flush_cache ("passwd");
@@ -1334,11 +1335,11 @@ int main (int argc, char **argv)
fprintf (stderr,
_("%s: (line %d, user %s) password not changed\n"),
Prog, lines[i], usernames[i]);
errors++;
exit (EXIT_FAILURE);
}
}
#endif /* USE_PAM */
return ((0 == errors) ? EXIT_SUCCESS : EXIT_FAILURE);
exit (EXIT_SUCCESS);
}
+231 -196
View File
@@ -19,8 +19,12 @@
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include "agetpass.h"
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "memzero.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -28,6 +32,9 @@
#include "pwio.h"
#include "shadowio.h"
#include "shadowlog.h"
#include "string/strtcpy.h"
#include "time/day_to_str.h"
/*
* exit status values
@@ -43,12 +50,14 @@
/*
* Global variables
*/
const char *Prog; /* Program name */
static const char Prog[] = "passwd"; /* Program name */
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 *prefix = "";
static bool
aflg = false, /* -a - show status for all users */
dflg = false, /* -d - delete password */
@@ -61,7 +70,8 @@ static bool
Sflg = false, /* -S - show password status */
uflg = false, /* -u - unlock the user's password */
wflg = false, /* -w - set warning days */
xflg = false; /* -x - set maximum days */
xflg = false, /* -x - set maximum days */
sflg = false; /* -s - read passwd from stdin */
/*
* set to 1 if there are any flags which require root privileges,
@@ -74,14 +84,16 @@ static long age_max = 0; /* Maximum days until change */
static long warn = 0; /* Warning days before change */
static long inact = 0; /* Days without change before locked */
#ifndef USE_PAM
static bool do_update_age = false;
#endif /* ! USE_PAM */
#ifdef USE_PAM
static bool use_pam = true;
#else
static bool use_pam = false;
#endif /* USE_PAM */
static bool pw_locked = false;
static bool spw_locked = false;
#ifndef USE_PAM
/*
* Size of the biggest passwd:
* $6$ 3
@@ -97,25 +109,21 @@ static bool spw_locked = false;
*/
static char crypt_passwd[256];
static bool do_update_pwd = false;
#endif /* !USE_PAM */
/*
* External identifiers
*/
/* local function prototypes */
static /*@noreturn@*/void usage (int);
NORETURN static void usage (int);
#ifndef USE_PAM
static bool reuse (const char *, const struct passwd *);
static int new_password (const struct passwd *);
static void check_password (const struct passwd *, const struct spwd *);
#endif /* !USE_PAM */
static /*@observer@*/const char *pw_status (const char *);
static void print_status (const struct passwd *);
static /*@noreturn@*/void fail_exit (int);
static /*@noreturn@*/void oom (void);
NORETURN static void fail_exit (int);
NORETURN static void oom (void);
static char *update_crypt_pw (char *);
static void update_noshadow (void);
@@ -124,7 +132,9 @@ static void update_shadow (void);
/*
* usage - print command usage and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -145,37 +155,17 @@ static /*@noreturn@*/void usage (int status)
(void) fputs (_(" -q, --quiet quiet mode\n"), usageout);
(void) fputs (_(" -r, --repository REPOSITORY change password in REPOSITORY repository\n"), usageout);
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
(void) fputs (_(" -P, --prefix PREFIX_DIR directory prefix\n"), usageout);
(void) fputs (_(" -S, --status report password status on the named account\n"), usageout);
(void) fputs (_(" -u, --unlock unlock the password of the named account\n"), usageout);
(void) fputs (_(" -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout);
(void) fputs (_(" -x, --maxdays MAX_DAYS set maximum number of days before password\n"
" change to MAX_DAYS\n"), usageout);
(void) fputs (_(" -s, --stdin read new token from stdin\n"), usageout);
(void) fputs ("\n", usageout);
exit (status);
}
#ifndef USE_PAM
static bool reuse (const char *pass, const struct passwd *pw)
{
#ifdef HAVE_LIBCRACK_HIST
const char *reason;
#ifdef HAVE_LIBCRACK_PW
const char *FascistHistoryPw (const char *, const struct passwd *);
reason = FascistHistory (pass, pw);
#else /* !HAVE_LIBCRACK_PW */
const char *FascistHistory (const char *, int);
reason = FascistHistory (pass, pw->pw_uid);
#endif /* !HAVE_LIBCRACK_PW */
if (NULL != reason) {
(void) printf (_("Bad password: %s. "), reason);
return true;
}
#endif /* HAVE_LIBCRACK_HIST */
return false;
}
/*
* new_password - validate old password and replace with new (both old and
@@ -186,25 +176,22 @@ static int new_password (const struct passwd *pw)
char *clear; /* Pointer to clear text */
char *cipher; /* Pointer to cipher text */
const char *salt; /* Pointer to new salt */
char *cp; /* Pointer to getpass() response */
char orig[200]; /* Original password */
char pass[200]; /* New password */
char *cp; /* Pointer to agetpass() response */
char orig[PASS_MAX + 1]; /* Original password */
char pass[PASS_MAX + 1]; /* New password */
int i; /* Counter for retries */
int ret;
bool warned;
int pass_max_len = -1;
const char *method;
#ifdef HAVE_LIBCRACK_HIST
int HistUpdate (const char *, const char *);
#endif /* HAVE_LIBCRACK_HIST */
/*
* Authenticate the user. The user will be prompted for their own
* password.
*/
if (!amroot && ('\0' != crypt_passwd[0])) {
clear = getpass (_("Old password: "));
clear = agetpass (_("Old password: "));
if (NULL == clear) {
return -1;
}
@@ -212,7 +199,7 @@ static int new_password (const struct passwd *pw)
cipher = pw_encrypt (clear, crypt_passwd);
if (NULL == cipher) {
strzero (clear);
erase_pass (clear);
fprintf (stderr,
_("%s: failed to crypt password with previous salt: %s\n"),
Prog, strerror (errno));
@@ -223,7 +210,7 @@ static int new_password (const struct passwd *pw)
}
if (strcmp (cipher, crypt_passwd) != 0) {
strzero (clear);
erase_pass (clear);
strzero (cipher);
SYSLOG ((LOG_WARN, "incorrect password for %s",
pw->pw_name));
@@ -233,8 +220,8 @@ static int new_password (const struct passwd *pw)
pw->pw_name);
return -1;
}
STRFCPY (orig, clear);
strzero (clear);
STRTCPY(orig, clear);
erase_pass (clear);
strzero (cipher);
} else {
orig[0] = '\0';
@@ -270,7 +257,7 @@ static int new_password (const struct passwd *pw)
pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
}
}
if (!qflg) {
if (!qflg && !sflg) {
if (pass_max_len == -1) {
(void) printf (_(
"Enter the new password (minimum of %d characters)\n"
@@ -284,62 +271,87 @@ static int new_password (const struct passwd *pw)
}
}
warned = false;
for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {
cp = getpass (_("New password: "));
if (NULL == cp) {
memzero (orig, sizeof orig);
memzero (pass, sizeof pass);
return -1;
}
if (warned && (strcmp (pass, cp) != 0)) {
warned = false;
}
STRFCPY (pass, cp);
strzero (cp);
if (!amroot && (!obscure (orig, pass, pw) || reuse (pass, pw))) {
(void) puts (_("Try again."));
continue;
}
if (sflg) {
/*
* If enabled, warn about weak passwords even if you are
* root (enter this password again to use it anyway).
* --marekm
* root is setting the passphrase from stdin
*/
if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
&& (!obscure (orig, pass, pw) || reuse (pass, pw))) {
(void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
warned = true;
continue;
}
cp = getpass (_("Re-enter new password: "));
cp = agetpass_stdin ();
if (NULL == cp) {
memzero (orig, sizeof orig);
memzero (pass, sizeof pass);
return -1;
}
if (strcmp (cp, pass) != 0) {
(void) fputs (_("They don't match; try again.\n"), stderr);
} else {
strzero (cp);
break;
ret = STRTCPY (pass, cp);
erase_pass (cp);
if (ret == -1) {
(void) fputs (_("Password is too long.\n"), stderr);
MEMZERO(pass);
return -1;
}
} else {
warned = false;
for (i = getdef_num ("PASS_CHANGE_TRIES", 5); i > 0; i--) {
cp = agetpass (_("New password: "));
if (NULL == cp) {
MEMZERO(orig);
MEMZERO(pass);
return -1;
}
if (warned && (strcmp (pass, cp) != 0)) {
warned = false;
}
ret = STRTCPY (pass, cp);
erase_pass (cp);
if (ret == -1) {
(void) fputs (_("Password is too long.\n"), stderr);
MEMZERO(orig);
MEMZERO(pass);
return -1;
}
if (!amroot && !obscure(orig, pass, pw)) {
(void) puts (_("Try again."));
continue;
}
/*
* If enabled, warn about weak passwords even if you are
* root (enter this password again to use it anyway).
* --marekm
*/
if (amroot && !warned && getdef_bool ("PASS_ALWAYS_WARN")
&& !obscure(orig, pass, pw)) {
(void) puts (_("\nWarning: weak password (enter it again to use it anyway)."));
warned = true;
continue;
}
cp = agetpass (_("Re-enter new password: "));
if (NULL == cp) {
MEMZERO(orig);
MEMZERO(pass);
return -1;
}
if (strcmp (cp, pass) != 0) {
erase_pass (cp);
(void) fputs (_("They don't match; try again.\n"), stderr);
} else {
erase_pass (cp);
break;
}
}
MEMZERO(orig);
if (i == 0) {
MEMZERO(pass);
return -1;
}
}
memzero (orig, sizeof orig);
if (i == 0) {
memzero (pass, sizeof pass);
return -1;
}
/*
* Encrypt the password, then wipe the cleartext password.
*/
salt = crypt_make_salt (NULL, NULL);
cp = pw_encrypt (pass, salt);
memzero (pass, sizeof pass);
MEMZERO(pass);
if (NULL == cp) {
fprintf (stderr,
@@ -348,10 +360,7 @@ static int new_password (const struct passwd *pw)
return -1;
}
#ifdef HAVE_LIBCRACK_HIST
HistUpdate (pw->pw_name, crypt_passwd);
#endif /* HAVE_LIBCRACK_HIST */
STRFCPY (crypt_passwd, cp);
STRTCPY(crypt_passwd, cp);
return 0;
}
@@ -363,7 +372,6 @@ static int new_password (const struct passwd *pw)
*/
static void check_password (const struct passwd *pw, const struct spwd *sp)
{
time_t now;
int exp_status;
exp_status = isexpired (pw, sp);
@@ -383,8 +391,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
return;
}
(void) time (&now);
/*
* Expired accounts cannot be changed ever. Passwords which are
* locked may not be changed. Passwords where min > max may not be
@@ -407,10 +413,12 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
* Passwords may only be changed after sp_min time is up.
*/
if (sp->sp_lstchg > 0) {
time_t ok;
ok = (time_t) sp->sp_lstchg * SCALE;
if (sp->sp_min > 0) {
ok += (time_t) sp->sp_min * SCALE;
long now, ok;
now = time(NULL) / DAY;
ok = sp->sp_lstchg;
if ( (sp->sp_min > 0)
&& __builtin_add_overflow(ok, sp->sp_min, &ok)) {
ok = LONG_MAX;
}
if (now < ok) {
@@ -423,7 +431,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
}
}
}
#endif /* !USE_PAM */
static /*@observer@*/const char *pw_status (const char *pass)
{
@@ -444,17 +451,17 @@ static void print_status (const struct passwd *pw)
char date[80];
struct spwd *sp;
sp = getspnam (pw->pw_name); /* local, no need for xgetspnam */
sp = prefix_getspnam (pw->pw_name); /* local, no need for xprefix_getspnam */
if (NULL != sp) {
date_to_str (sizeof(date), date, sp->sp_lstchg * SCALE),
(void) printf ("%s %s %s %lld %lld %lld %lld\n",
DAY_TO_STR(date, sp->sp_lstchg);
(void) printf ("%s %s %s %ld %ld %ld %ld\n",
pw->pw_name,
pw_status (sp->sp_pwdp),
date,
((long long)sp->sp_min * SCALE) / DAY,
((long long)sp->sp_max * SCALE) / DAY,
((long long)sp->sp_warn * SCALE) / DAY,
((long long)sp->sp_inact * SCALE) / DAY);
sp->sp_min,
sp->sp_max,
sp->sp_warn,
sp->sp_inact);
} else if (NULL != pw->pw_passwd) {
(void) printf ("%s %s\n",
pw->pw_name, pw_status (pw->pw_passwd));
@@ -465,7 +472,9 @@ static void print_status (const struct passwd *pw)
}
static /*@noreturn@*/void fail_exit (int status)
NORETURN
static void
fail_exit (int status)
{
if (pw_locked) {
if (pw_unlock () == 0) {
@@ -486,7 +495,9 @@ static /*@noreturn@*/void fail_exit (int status)
exit (status);
}
static /*@noreturn@*/void oom (void)
NORETURN
static void
oom (void)
{
(void) fprintf (stderr, _("%s: out of memory\n"), Prog);
fail_exit (E_FAILURE);
@@ -494,11 +505,12 @@ static /*@noreturn@*/void oom (void)
static char *update_crypt_pw (char *cp)
{
#ifndef USE_PAM
if (do_update_pwd) {
cp = xstrdup (crypt_passwd);
if (!use_pam)
{
if (do_update_pwd) {
cp = xstrdup (crypt_passwd);
}
}
#endif /* !USE_PAM */
if (dflg) {
*cp = '\0';
@@ -517,15 +529,16 @@ static char *update_crypt_pw (char *cp)
}
if (lflg && *cp != '!') {
char *newpw = xmalloc (strlen (cp) + 2);
char *newpw = XMALLOC(strlen(cp) + 2, char);
strcpy (newpw, "!");
strcat (newpw, cp);
#ifndef USE_PAM
if (do_update_pwd) {
free (cp);
if (!use_pam)
{
if (do_update_pwd) {
free (cp);
}
}
#endif /* USE_PAM */
cp = newpw;
}
return cp;
@@ -626,27 +639,28 @@ static void update_shadow (void)
}
nsp->sp_pwdp = update_crypt_pw (nsp->sp_pwdp);
if (xflg) {
nsp->sp_max = (age_max * DAY) / SCALE;
nsp->sp_max = age_max;
}
if (nflg) {
nsp->sp_min = (age_min * DAY) / SCALE;
nsp->sp_min = age_min;
}
if (wflg) {
nsp->sp_warn = (warn * DAY) / SCALE;
nsp->sp_warn = warn;
}
if (iflg) {
nsp->sp_inact = (inact * DAY) / SCALE;
nsp->sp_inact = inact;
}
#ifndef USE_PAM
if (do_update_age) {
nsp->sp_lstchg = (long) gettime () / SCALE;
if (0 == nsp->sp_lstchg) {
/* Better disable aging than requiring a password
* change */
nsp->sp_lstchg = -1;
if (!use_pam)
{
if (do_update_age) {
nsp->sp_lstchg = gettime () / DAY;
if (0 == nsp->sp_lstchg) {
/* Better disable aging than requiring a password
* change */
nsp->sp_lstchg = -1;
}
}
}
#endif /* !USE_PAM */
/*
* Force change on next login, like SunOS 4.x passwd -e or Solaris
@@ -690,18 +704,16 @@ static void update_shadow (void)
*
* -d delete the password for the named account (*)
* -e expire the password for the named account (*)
* -f execute chfn command to interpret flags
* -g execute gpasswd command to interpret flags
* -i # set sp_inact to # days (*)
* -k change password only if expired
* -l lock the password of the named account (*)
* -n # set sp_min to # days (*)
* -r # change password in # repository
* -s execute chsh command to interpret flags
* -S show password status of named account
* -u unlock the password of the named account (*)
* -w # set sp_warn to # days (*)
* -x # set sp_max to # days (*)
* -s read password from stdin (*)
*
* (*) requires root permission to execute.
*
@@ -713,19 +725,13 @@ int main (int argc, char **argv)
{
const struct passwd *pw; /* Password file entry for user */
#ifndef USE_PAM
char *cp; /* Miscellaneous character pointing */
const struct spwd *sp; /* Shadow file entry for user */
#endif /* !USE_PAM */
sanitize_env ();
check_fds ();
/*
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -734,6 +740,12 @@ int main (int argc, char **argv)
(void) textdomain (PACKAGE);
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
if (prefix[0]) {
use_pam = false;
do_update_age = true;
}
/*
* The program behaves differently when executed by root than when
@@ -741,7 +753,7 @@ int main (int argc, char **argv)
*/
amroot = (getuid () == 0);
OPENLOG ("passwd");
OPENLOG (Prog);
{
/*
@@ -760,14 +772,16 @@ int main (int argc, char **argv)
{"quiet", no_argument, NULL, 'q'},
{"repository", required_argument, NULL, 'r'},
{"root", required_argument, NULL, 'R'},
{"prefix", required_argument, NULL, 'P'},
{"status", no_argument, NULL, 'S'},
{"unlock", no_argument, NULL, 'u'},
{"warndays", required_argument, NULL, 'w'},
{"maxdays", required_argument, NULL, 'x'},
{"stdin", no_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}
};
while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:Suw:x:",
while ((c = getopt_long (argc, argv, "adehi:kln:qr:R:P:Suw:x:s",
long_options, NULL)) != -1) {
switch (c) {
case 'a':
@@ -785,7 +799,7 @@ int main (int argc, char **argv)
usage (E_SUCCESS);
/*@notreached@*/break;
case 'i':
if ( (getlong (optarg, &inact) == 0)
if ( (getlong(optarg, &inact) == -1)
|| (inact < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -804,7 +818,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'n':
if ( (getlong (optarg, &age_min) == 0)
if ( (getlong(optarg, &age_min) == -1)
|| (age_min < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -829,6 +843,8 @@ int main (int argc, char **argv)
break;
case 'R': /* no-op, handled in process_root_flag () */
break;
case 'P': /* no-op, handled in process_prefix_flag () */
break;
case 'S':
Sflg = true; /* ok for users */
break;
@@ -837,7 +853,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'w':
if ( (getlong (optarg, &warn) == 0)
if ( (getlong(optarg, &warn) == -1)
|| (warn < -1)) {
(void) fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -848,7 +864,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'x':
if ( (getlong (optarg, &age_max) == 0)
if ( (getlong(optarg, &age_max) == -1)
|| (age_max < -1)) {
(void) fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -858,6 +874,15 @@ int main (int argc, char **argv)
xflg = true;
anyflag = true;
break;
case 's':
if (!amroot) {
(void) fprintf (stderr,
_("%s: only root can use --stdin/-s option\n"),
Prog);
usage (E_BAD_ARG);
}
sflg = true;
break;
default:
usage (E_BAD_ARG);
}
@@ -906,11 +931,11 @@ int main (int argc, char **argv)
Prog);
exit (E_NOPERM);
}
setpwent ();
while ( (pw = getpwent ()) != NULL ) {
prefix_setpwent ();
while ( (pw = prefix_getpwent ()) != NULL ) {
print_status (pw);
}
endpwent ();
prefix_endpwent ();
exit (E_SUCCESS);
}
#if 0
@@ -947,7 +972,7 @@ int main (int argc, char **argv)
exit (E_NOPERM);
}
pw = xgetpwnam (name);
pw = xprefix_getpwnam (name);
if (NULL == pw) {
(void) fprintf (stderr,
_("%s: user '%s' does not exist\n"),
@@ -957,7 +982,7 @@ int main (int argc, char **argv)
#ifdef WITH_SELINUX
/* only do this check when getuid()==0 because it's a pre-condition for
changing a password without entering the old one */
if (amroot && (check_selinux_permit ("passwd") != 0)) {
if (amroot && (check_selinux_permit (Prog) != 0)) {
SYSLOG ((LOG_ALERT,
"root is not authorized by SELinux to change the password of %s",
name));
@@ -977,8 +1002,8 @@ int main (int argc, char **argv)
_("%s: You may not view or modify password information for %s.\n"),
Prog, name);
SYSLOG ((LOG_WARN,
"%s: can't view or modify password information for %s",
Prog, name));
"can't view or modify password information for %s",
name));
closelog ();
exit (E_NOPERM);
}
@@ -987,53 +1012,55 @@ int main (int argc, char **argv)
print_status (pw);
exit (E_SUCCESS);
}
#ifndef USE_PAM
/*
* The user name is valid, so let's get the shadow file entry.
*/
sp = getspnam (name); /* !USE_PAM, no need for xgetspnam */
if (NULL == sp) {
if (errno == EACCES) {
(void) fprintf (stderr,
_("%s: Permission denied.\n"),
Prog);
exit (E_NOPERM);
if (!use_pam)
{
/*
* The user name is valid, so let's get the shadow file entry.
*/
sp = prefix_getspnam (name); /* !use_pam, no need for xprefix_getspnam */
if (NULL == sp) {
if (errno == EACCES) {
(void) fprintf (stderr,
_("%s: Permission denied.\n"),
Prog);
exit (E_NOPERM);
}
sp = pwd_to_spwd (pw);
}
sp = pwd_to_spwd (pw);
}
cp = sp->sp_pwdp;
/*
* If there are no other flags, just change the password.
*/
if (!anyflag) {
STRFCPY (crypt_passwd, cp);
cp = sp->sp_pwdp;
/*
* See if the user is permitted to change the password.
* Otherwise, go ahead and set a new password.
* If there are no other flags, just change the password.
*/
check_password (pw, sp);
if (!anyflag) {
STRTCPY(crypt_passwd, cp);
/*
* Let the user know whose password is being changed.
*/
if (!qflg) {
(void) printf (_("Changing password for %s\n"), name);
}
/*
* See if the user is permitted to change the password.
* Otherwise, go ahead and set a new password.
*/
check_password (pw, sp);
if (new_password (pw) != 0) {
(void) fprintf (stderr,
_("The password for %s is unchanged.\n"),
name);
closelog ();
exit (E_NOPERM);
/*
* Let the user know whose password is being changed.
*/
if (!qflg) {
(void) printf (_("Changing password for %s\n"), name);
}
if (new_password (pw) != 0) {
(void) fprintf (stderr,
_("The password for %s is unchanged.\n"),
name);
closelog ();
exit (E_NOPERM);
}
do_update_pwd = true;
do_update_age = true;
}
do_update_pwd = true;
do_update_age = true;
}
#endif /* !USE_PAM */
/*
* Before going any further, raise the ulimit to prevent colliding
* into a lowered ulimit, and set the real UID to root to protect
@@ -1046,8 +1073,17 @@ int main (int argc, char **argv)
/*
* Don't set the real UID for PAM...
*/
if (!anyflag) {
do_pam_passwd (name, qflg, kflg);
if (!anyflag && use_pam) {
if (sflg) {
cp = agetpass_stdin ();
if (cp == NULL) {
exit (E_FAILURE);
}
do_pam_passwd_non_interactive ("passwd", name, cp);
erase_pass (cp);
} else {
do_pam_passwd (name, qflg, kflg);
}
exit (E_SUCCESS);
}
#endif /* USE_PAM */
@@ -1081,4 +1117,3 @@ int main (int argc, char **argv)
return E_SUCCESS;
}
+11 -13
View File
@@ -47,7 +47,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "pwck";
static bool use_system_pw_file = true;
static bool use_system_spw_file = true;
@@ -66,7 +66,7 @@ static bool quiet = false; /* don't report warnings, only errors */
/* local function prototypes */
static void fail_exit (int code);
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv);
static void open_files (void);
static void close_files (bool changed);
@@ -109,7 +109,9 @@ static void fail_exit (int code)
/*
* usage - print syntax message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
#ifdef WITH_TCB
@@ -367,8 +369,8 @@ static void check_pw_file (int *errors, bool *changed)
struct commonio_entry *pfe, *tpfe;
struct passwd *pwd;
const struct spwd *spw;
uid_t min_sys_id = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL);
uid_t max_sys_id = (uid_t) getdef_ulong ("SYS_UID_MAX", 999UL);
uid_t min_sys_id = getdef_ulong ("SYS_UID_MIN", 101UL);
uid_t max_sys_id = getdef_ulong ("SYS_UID_MAX", 999UL);
/*
* Loop through the entire password file.
@@ -607,7 +609,7 @@ static void check_pw_file (int *errors, bool *changed)
sp.sp_inact = -1;
sp.sp_expire = -1;
sp.sp_flag = SHADOW_SP_FLAG_UNSET;
sp.sp_lstchg = (long) gettime () / SCALE;
sp.sp_lstchg = gettime () / DAY;
if (0 == sp.sp_lstchg) {
/* Better disable aging than
* requiring a password change
@@ -812,9 +814,9 @@ static void check_spw_file (int *errors, bool *changed)
* Warn if last password change in the future. --marekm
*/
if (!quiet) {
time_t t = time ((time_t *) 0);
time_t t = time (NULL);
if ( (t != 0)
&& (spw->sp_lstchg > (long) t / SCALE)) {
&& (spw->sp_lstchg > t / DAY)) {
printf (_("user %s: last password change in the future\n"),
spw->sp_namp);
*errors += 1;
@@ -831,10 +833,6 @@ int main (int argc, char **argv)
int errors = 0;
bool changed = false;
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -844,7 +842,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("pwck");
OPENLOG (Prog);
/* Parse the command line arguments */
process_flags (argc, argv);
+6 -5
View File
@@ -40,9 +40,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
@@ -66,7 +68,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "pwconv";
static bool spw_locked = false;
static bool pw_locked = false;
@@ -153,7 +155,6 @@ int main (int argc, char **argv)
const struct spwd *sp;
struct spwd spent;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -163,7 +164,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("pwconv");
OPENLOG (Prog);
process_flags (argc, argv);
@@ -237,7 +238,7 @@ int main (int argc, char **argv)
spent = *sp;
} else {
/* add new shadow entry */
memset (&spent, 0, sizeof spent);
bzero(&spent, sizeof spent);
spent.sp_namp = pw->pw_name;
spent.sp_min = getdef_num ("PASS_MIN_DAYS", -1);
spent.sp_max = getdef_num ("PASS_MAX_DAYS", -1);
@@ -247,7 +248,7 @@ int main (int argc, char **argv)
spent.sp_flag = SHADOW_SP_FLAG_UNSET;
}
spent.sp_pwdp = pw->pw_passwd;
spent.sp_lstchg = (long) gettime () / SCALE;
spent.sp_lstchg = gettime () / DAY;
if (0 == spent.sp_lstchg) {
/* Better disable aging than requiring a password
* change */
+3 -3
View File
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <getopt.h>
#include "defines.h"
#include "getdef.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -30,7 +31,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "pwunconv";
static bool spw_locked = false;
static bool pw_locked = false;
@@ -114,7 +115,6 @@ int main (int argc, char **argv)
struct passwd pwent;
const struct spwd *spwd;
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -124,7 +124,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
OPENLOG ("pwunconv");
OPENLOG (Prog);
process_flags (argc, argv);
+71 -44
View File
@@ -45,6 +45,10 @@
#include <sys/stat.h>
#include <fcntl.h>
#endif /* !USE_PAM */
#include "alloc.h"
#include "attr.h"
#include "cast.h"
#include "prototypes.h"
#include "defines.h"
#include "pwauth.h"
@@ -55,11 +59,14 @@
/*@-exitarg@*/
#include "exitcodes.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/strtcpy.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "su";
static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */
static bool caller_is_root = false;
static uid_t caller_uid;
@@ -95,8 +102,8 @@ static pid_t pid_child = 0;
* External identifiers
*/
extern char **newenvp; /* libmisc/env.c */
extern size_t newenvc; /* libmisc/env.c */
extern char **newenvp; /* lib/env.c */
extern size_t newenvc; /* lib/env.c */
/* local function prototypes */
@@ -104,15 +111,16 @@ static void execve_shell (const char *shellname,
char *args[],
char *const envp[]);
#ifdef USE_PAM
static void kill_child (int unused(s));
static void kill_child (MAYBE_UNUSED int s);
static void prepare_pam_close_session (void);
#else /* !USE_PAM */
static void die (int);
static bool iswheel (const char *);
#endif /* !USE_PAM */
static bool restricted_shell (const char *shellname);
static /*@noreturn@*/void su_failure (const char *tty, bool su_to_root);
NORETURN static void su_failure (const char *tty, bool su_to_root);
static /*@only@*/struct passwd * check_perms (void);
static /*@only@*/struct passwd * do_check_perms (void);
#ifdef USE_PAM
static void check_perms_pam (const struct passwd *pw);
#else /* !USE_PAM */
@@ -157,13 +165,13 @@ static bool iswheel (const char *username)
return is_on_list (grp->gr_mem, username);
}
#else /* USE_PAM */
static void kill_child (int unused(s))
static void kill_child (MAYBE_UNUSED int s)
{
if (0 != pid_child) {
(void) kill (-pid_child, SIGKILL);
(void) write (STDERR_FILENO, kill_msg, strlen (kill_msg));
(void) write_full(STDERR_FILENO, kill_msg, strlen(kill_msg));
} else {
(void) write (STDERR_FILENO, wait_msg, strlen (wait_msg));
(void) write_full(STDERR_FILENO, wait_msg, strlen(wait_msg));
}
_exit (255);
}
@@ -185,10 +193,11 @@ static bool restricted_shell (const char *shellname)
return true;
}
static /*@noreturn@*/void su_failure (const char *tty, bool su_to_root)
NORETURN
static void
su_failure (const char *tty, bool su_to_root)
{
sulog (tty, false, caller_name, name); /* log failed attempt */
#ifdef USE_SYSLOG
if (getdef_bool ("SYSLOG_SU_ENAB")) {
SYSLOG ((su_to_root ? LOG_NOTICE : LOG_INFO,
"- %s %s:%s", tty,
@@ -196,7 +205,6 @@ static /*@noreturn@*/void su_failure (const char *tty, bool su_to_root)
('\0' != name[0]) ? name : "???"));
}
closelog ();
#endif
#ifdef WITH_AUDIT
audit_fd = audit_open ();
@@ -225,7 +233,7 @@ static void execve_shell (const char *shellname,
char *const envp[])
{
int err;
(void) execve (shellname, (char **) args, envp);
(void) execve (shellname, args, envp);
err = errno;
if (access (shellname, R_OK|X_OK) == 0) {
@@ -238,7 +246,7 @@ static void execve_shell (const char *shellname,
while (NULL != args[n_args]) {
n_args++;
}
targs = (char **) xmalloc ((n_args + 3) * sizeof (args[0]));
targs = XMALLOC(n_args + 3, char *);
targs[0] = "sh";
targs[1] = "-";
targs[2] = xstrdup (shellname);
@@ -382,8 +390,8 @@ static void prepare_pam_close_session (void)
stderr);
(void) kill (-pid_child, caught);
snprintf (kill_msg, sizeof kill_msg, _(" ...killed.\n"));
snprintf (wait_msg, sizeof wait_msg, _(" ...waiting for child to terminate.\n"));
SNPRINTF(kill_msg, _(" ...killed.\n"));
SNPRINTF(wait_msg, _(" ...waiting for child to terminate.\n"));
/* Any signals other than SIGCHLD and SIGALRM will no longer have any effect,
* so it's time to block all of them. */
@@ -430,6 +438,7 @@ static void prepare_pam_close_session (void)
/*
* usage - print command line syntax and exit
*/
NORETURN
static void usage (int status)
{
(void)
@@ -501,7 +510,8 @@ static void check_perms_nopam (const struct passwd *pw)
}
if (strcmp (pw->pw_passwd, "") == 0) {
char *prevent_no_auth = getdef_str("PREVENT_NO_AUTH");
const char *prevent_no_auth = getdef_str("PREVENT_NO_AUTH");
if (prevent_no_auth == NULL) {
prevent_no_auth = "superuser";
}
@@ -577,7 +587,7 @@ static void check_perms_nopam (const struct passwd *pw)
* The first character of an administrator defined method is an '@'
* character.
*/
if (pw_auth (password, name, PW_SU, (char *) 0) != 0) {
if (pw_auth (password, name, PW_SU, NULL) != 0) {
SYSLOG (((pw->pw_uid != 0)? LOG_NOTICE : LOG_WARN,
"Authentication failed for %s", name));
fprintf(stderr, _("%s: Authentication failure\n"), Prog);
@@ -600,7 +610,7 @@ static void check_perms_nopam (const struct passwd *pw)
* there is a "SU" entry in the /etc/porttime file denying access to
* the account.
*/
if (!isttytime (name, "SU", time ((time_t *) 0))) {
if (!isttytime (name, "SU", time (NULL))) {
SYSLOG (((0 != pw->pw_uid) ? LOG_WARN : LOG_CRIT,
"SU by %s to restricted account %s",
caller_name, name));
@@ -615,14 +625,30 @@ static void check_perms_nopam (const struct passwd *pw)
/*
* check_perms - check permissions to switch to the user 'name'
*
* In case of subsystem login, the user is first authenticated in the
* caller's root subsystem, and then in the user's target subsystem.
* The user is authenticated in all subsystems iterately.
*/
static /*@only@*/struct passwd * check_perms (void)
{
struct passwd *pw = NULL;
while (pw == NULL)
pw = do_check_perms();
return pw;
}
/*
* do_check_perms - check permissions to switch to the user 'name'
*
* The user is authenticated in current subsystem, if any. Returns
* NULL if permissions have to be checked in next subsystem, in
* which case the subsystem has already been entered.
*/
static /*@only@*/struct passwd * do_check_perms (void)
{
#ifdef USE_PAM
const char *tmp_name;
int ret;
int ret;
const char *tmp_name;
const void *item;
#endif /* !USE_PAM */
/*
* The password file entries for the user is gotten and the account
@@ -642,7 +668,7 @@ static /*@only@*/struct passwd * check_perms (void)
#ifdef USE_PAM
check_perms_pam (pw);
/* PAM authentication can request a change of account */
ret = pam_get_item(pamh, PAM_USER, (const void **) &tmp_name);
ret = pam_get_item(pamh, PAM_USER, &item);
if (ret != PAM_SUCCESS) {
SYSLOG((LOG_ERR, "pam_get_item: internal PAM error\n"));
(void) fprintf (stderr,
@@ -651,12 +677,18 @@ static /*@only@*/struct passwd * check_perms (void)
(void) pam_end (pamh, ret);
su_failure (caller_tty, 0 == pw->pw_uid);
}
tmp_name = item;
if (strcmp (name, tmp_name) != 0) {
SYSLOG ((LOG_INFO,
"Change user from '%s' to '%s' as requested by PAM",
name, tmp_name));
strncpy (name, tmp_name, sizeof(name) - 1);
name[sizeof(name) - 1] = '\0';
if (STRTCPY(name, tmp_name) == -1) {
fprintf (stderr, _("Overlong user name '%s'\n"),
tmp_name);
SYSLOG ((LOG_NOTICE, "Overlong user name '%s'",
tmp_name));
su_failure (caller_tty, true);
}
pw = xgetpwnam (name);
if (NULL == pw) {
(void) fprintf (stderr,
@@ -684,7 +716,7 @@ static /*@only@*/struct passwd * check_perms (void)
endpwent (); /* close the old password databases */
endspent ();
pw_free (pw);
return check_perms (); /* authenticate in the subsystem */
return NULL; /* authenticate in the subsystem */
}
return pw;
@@ -706,11 +738,6 @@ static void save_caller_context (char **argv)
const char *password = NULL;
#endif /* SU_ACCESS */
#endif /* !USE_PAM */
/*
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -752,7 +779,7 @@ static void save_caller_context (char **argv)
(unsigned long) caller_uid));
su_failure (caller_tty, true); /* unknown target UID*/
}
STRFCPY (caller_name, pw->pw_name);
STRTCPY(caller_name, pw->pw_name);
#ifndef USE_PAM
#ifdef SU_ACCESS
@@ -808,7 +835,7 @@ static void process_flags (int argc, char **argv)
case 'm':
case 'p':
/* This will only have an effect if the target
* user do not have a restricted shell, or if
* user does not have a restricted shell, or if
* su is called by root.
*/
change_environment = false;
@@ -827,7 +854,7 @@ static void process_flags (int argc, char **argv)
}
if (optind < argc) {
STRFCPY (name, argv[optind++]); /* use this login id */
STRTCPY(name, argv[optind++]); /* use this login id */
}
if ('\0' == name[0]) { /* use default user */
struct passwd *root_pw = getpwnam ("root");
@@ -980,20 +1007,22 @@ int main (int argc, char **argv)
int ret;
#endif /* USE_PAM */
check_fds ();
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
save_caller_context (argv);
OPENLOG ("su");
OPENLOG (Prog);
process_flags (argc, argv);
initenv ();
#ifdef USE_PAM
ret = pam_start ("su", name, &conv, &pamh);
ret = pam_start (Prog, name, &conv, &pamh);
if (PAM_SUCCESS != ret) {
SYSLOG ((LOG_ERR, "pam_start: error %d", ret);
fprintf (stderr,
@@ -1002,9 +1031,9 @@ int main (int argc, char **argv)
exit (1);
}
ret = pam_set_item (pamh, PAM_TTY, (const void *) caller_tty);
ret = pam_set_item (pamh, PAM_TTY, caller_tty);
if (PAM_SUCCESS == ret) {
ret = pam_set_item (pamh, PAM_RUSER, (const void *) caller_name);
ret = pam_set_item (pamh, PAM_RUSER, caller_name);
}
if (PAM_SUCCESS != ret) {
SYSLOG ((LOG_ERR, "pam_set_item: %s",
@@ -1017,7 +1046,7 @@ int main (int argc, char **argv)
pw = check_perms ();
/* If the user do not want to change the environment,
/* If the user does not want to change the environment,
* use the current SHELL.
* (unless another shell is required by the command line)
*/
@@ -1050,13 +1079,11 @@ int main (int argc, char **argv)
}
sulog (caller_tty, true, caller_name, name); /* save SU information */
#ifdef USE_SYSLOG
if (getdef_bool ("SYSLOG_SU_ENAB")) {
SYSLOG ((LOG_INFO, "+ %s %s:%s", caller_tty,
('\0' != caller_name[0]) ? caller_name : "???",
('\0' != name[0]) ? name : "???"));
}
#endif
#ifdef USE_PAM
/* set primary group id and supplementary groups */
@@ -1135,7 +1162,7 @@ int main (int argc, char **argv)
int fd = open ("/dev/tty", O_RDWR);
if (fd >= 0) {
err = ioctl (fd, TIOCNOTTY, (char *) 0);
err = ioctl (fd, TIOCNOTTY, (char *) NULL);
(void) close (fd);
} else if (ENXIO == errno) {
/* There are no controlling terminal already */
@@ -1178,7 +1205,7 @@ int main (int argc, char **argv)
cp = Basename (shellstr);
}
arg0 = xmalloc (strlen (cp) + 2);
arg0 = XMALLOC(strlen(cp) + 2, char);
arg0[0] = '-';
strcpy (arg0 + 1, cp);
cp = arg0;
@@ -1199,7 +1226,7 @@ int main (int argc, char **argv)
* Use the shell and create an argv
* with the rest of the command line included.
*/
argv[-1] = cp;
argv[-1] = const_cast(char *, cp);
execve_shell (shellstr, &argv[-1], environ);
err = errno;
(void) fprintf (stderr,
+5 -4
View File
@@ -68,8 +68,9 @@ int check_su_auth (const char *actual_id,
while (fgets (temp, sizeof (temp), authfile_fd) != NULL) {
lines++;
endline = strlen(temp) - 1;
if (temp[endline = strlen (temp) - 1] != '\n') {
if (temp[0] == '\0' || temp[endline] != '\n') {
SYSLOG ((LOG_ERR,
"%s, line %d: line too long or missing newline",
SUAUTHFILE, lines));
@@ -91,9 +92,9 @@ int check_su_auth (const char *actual_id,
continue;
}
if (!(to_users = strtok (temp + posn, field))
|| !(from_users = strtok ((char *) NULL, field))
|| !(action = strtok ((char *) NULL, field))
|| strtok ((char *) NULL, field)) {
|| !(from_users = strtok (NULL, field))
|| !(action = strtok (NULL, field))
|| strtok (NULL, field)) {
SYSLOG ((LOG_ERR,
"%s, line %d. Bad number of fields.\n",
SUAUTHFILE, lines));
+81 -101
View File
@@ -16,6 +16,11 @@
#include <signal.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "agetpass.h"
#include "alloc.h"
#include "attr.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
@@ -24,113 +29,76 @@
#include "exitcodes.h"
#include "shadowlog.h"
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "sulogin";
static char name[BUFSIZ];
static char pass[BUFSIZ];
static struct passwd pwent;
extern char **newenvp;
extern size_t newenvc;
extern char **environ;
#ifndef ALARM
#define ALARM 60
#endif
/* local function prototypes */
static void catch_signals (int);
static void catch_signals (unused int sig)
static void catch_signals (int);
static int pw_entry(const char *name, struct passwd *pwent);
static void catch_signals (MAYBE_UNUSED int sig)
{
_exit (1);
}
/*
* syslogd is usually not running at the time when sulogin is typically
* called, cluttering the screen with unnecessary messages. Suggested by
* Ivan Nejgebauer <ian@unsux.ns.ac.yu>. --marekm
*/
#undef USE_SYSLOG
/*ARGSUSED*/ int main (int argc, char **argv)
int
main(int argc, char *argv[])
{
int err = 0;
char **envp = environ;
TERMIO termio;
struct passwd pwent = {};
bool done;
#ifndef USE_PAM
const char *env;
#endif /* !USE_PAM */
char **envp = environ;
TERMIO termio;
int err = 0;
#ifdef USE_TERMIO
ioctl (0, TCGETA, &termio);
termio.c_iflag |= (ICRNL | IXON);
termio.c_oflag |= (OPOST | ONLCR);
termio.c_cflag |= (CREAD);
termio.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK);
ioctl (0, TCSETAF, &termio);
const char *env;
#endif
#ifdef USE_TERMIOS
tcgetattr (0, &termio);
termio.c_iflag |= (ICRNL | IXON);
termio.c_oflag |= (CREAD);
termio.c_lflag |= (ECHO | ECHOE | ECHOK | ICANON | ISIG);
tcsetattr (0, TCSANOW, &termio);
#endif
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
#ifdef USE_SYSLOG
OPENLOG ("sulogin");
#endif
initenv ();
initenv();
if (argc > 1) {
close (0);
close (1);
close (2);
close(0);
close(1);
close(2);
if (open (argv[1], O_RDWR) >= 0) {
dup (0);
dup (0);
} else {
#ifdef USE_SYSLOG
SYSLOG (LOG_WARN, "cannot open %s\n", argv[1]);
closelog ();
#endif
exit (1);
}
if (open(argv[1], O_RDWR) == -1)
exit(1);
dup(0);
dup(0);
}
if (access (PASSWD_FILE, F_OK) == -1) { /* must be a password file! */
(void) puts (_("No password file"));
#ifdef USE_SYSLOG
SYSLOG (LOG_WARN, "No password file\n");
closelog ();
#endif
exit (1);
}
#if !defined(DEBUG) && defined(SULOGIN_ONLY_INIT)
if (getppid () != 1) { /* parent must be INIT */
#ifdef USE_SYSLOG
SYSLOG (LOG_WARN, "Pid == %d, not 1\n", getppid ());
closelog ();
#endif
exit (1);
}
#endif
if ((isatty (0) == 0) || (isatty (1) == 0) || (isatty (2) == 0)) {
#ifdef USE_SYSLOG
closelog ();
#endif
exit (1); /* must be a terminal */
}
/* If we were init, we need to start a new session */
@@ -156,24 +124,17 @@ static void catch_signals (unused int sig)
}
#endif /* !USE_PAM */
(void) strcpy (name, "root"); /* KLUDGE!!! */
(void) signal (SIGALRM, catch_signals); /* exit if the timer expires */
(void) alarm (ALARM); /* only wait so long ... */
while (true) { /* repeatedly get login/password pairs */
char *cp;
pw_entry (name, &pwent); /* get entry from password file */
if (pwent.pw_name == (char *) 0) {
do { /* repeatedly get login/password pairs */
char *pass;
if (pw_entry("root", &pwent) == -1) { /* get entry from password file */
/*
* Fail secure
*/
(void) puts (_("No password entry for 'root'"));
#ifdef USE_SYSLOG
SYSLOG (LOG_WARN, "No password entry for 'root'\n");
closelog ();
#endif
exit (1);
(void) puts(_("No password entry for 'root'"));
exit(1);
}
/*
@@ -182,7 +143,7 @@ static void catch_signals (unused int sig)
*/
/* get a password for root */
cp = getpass (_(
pass = agetpass (_(
"\n"
"Type control-d to proceed with normal startup,\n"
"(or give root password for system maintenance):"));
@@ -192,46 +153,65 @@ static void catch_signals (unused int sig)
* it will work with standard getpass() (no NULL on EOF).
* --marekm
*/
if ((NULL == cp) || ('\0' == *cp)) {
#ifdef USE_SYSLOG
SYSLOG (LOG_INFO, "Normal startup\n");
closelog ();
#endif
if ((NULL == pass) || ('\0' == *pass)) {
erase_pass (pass);
(void) puts ("");
#ifdef TELINIT
execl (PATH_TELINIT, "telinit", RUNLEVEL, (char *) 0);
execl (PATH_TELINIT, "telinit", RUNLEVEL, (char *) NULL);
#endif
exit (0);
} else {
STRFCPY (pass, cp);
strzero (cp);
}
if (valid (pass, &pwent)) { /* check encrypted passwords ... */
break; /* ... encrypted passwords matched */
}
#ifdef USE_SYSLOG
SYSLOG (LOG_WARN, "Incorrect root password\n");
#endif
sleep (2);
(void) puts (_("Login incorrect"));
}
memzero (pass, sizeof pass);
done = valid(pass, &pwent);
erase_pass (pass);
if (!done) { /* check encrypted passwords ... */
/* ... encrypted passwords did not match */
sleep (2);
(void) puts (_("Login incorrect"));
}
} while (!done);
(void) alarm (0);
(void) signal (SIGALRM, SIG_DFL);
environ = newenvp; /* make new environment active */
(void) puts (_("Entering System Maintenance Mode"));
#ifdef USE_SYSLOG
SYSLOG (LOG_INFO, "System Maintenance Mode\n");
#endif
#ifdef USE_SYSLOG
closelog ();
#endif
/* exec the shell finally. */
err = shell (pwent.pw_shell, (char *) 0, environ);
err = shell (pwent.pw_shell, NULL, environ);
return ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
}
static int
pw_entry(const char *name, struct passwd *pwent)
{
struct spwd *spwd;
struct passwd *passwd;
if (!(passwd = getpwnam(name))) /* local, no need for xgetpwnam */
return -1;
free(pwent->pw_name);
pwent->pw_name = xstrdup(passwd->pw_name);
pwent->pw_uid = passwd->pw_uid;
pwent->pw_gid = passwd->pw_gid;
free(pwent->pw_gecos);
pwent->pw_gecos = xstrdup(passwd->pw_gecos);
free(pwent->pw_dir);
pwent->pw_dir = xstrdup(passwd->pw_dir);
free(pwent->pw_shell);
pwent->pw_shell = xstrdup(passwd->pw_shell);
#if !defined(AUTOSHADOW)
/* local, no need for xgetspnam */
if ((spwd = getspnam(name))) {
free(pwent->pw_passwd);
pwent->pw_passwd = xstrdup(spwd->sp_pwdp);
return 0;
}
#endif
free(pwent->pw_passwd);
pwent->pw_passwd = xstrdup(passwd->pw_passwd);
return 0;
}
+442 -434
View File
File diff suppressed because it is too large Load Diff
+47 -109
View File
@@ -19,6 +19,8 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "alloc.h"
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
@@ -50,6 +52,8 @@
#include "subordinateio.h"
#endif /* ENABLE_SUBIDS */
#include "shadowlog.h"
#include "string/sprintf.h"
/*
* exit status values
@@ -68,7 +72,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "userdel";
static char *user_name;
static uid_t user_id;
@@ -204,8 +208,7 @@ static void update_groups (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting user from group",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
#endif /* WITH_AUDIT */
SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n",
user_name, ngrp->gr_name));
@@ -266,8 +269,7 @@ static void update_groups (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting user from shadow group",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
#endif /* WITH_AUDIT */
SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n",
user_name, nsgrp->sg_name));
@@ -526,8 +528,7 @@ static void fail_exit (int code)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting user",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
exit (code);
@@ -548,8 +549,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking password file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_PW_UPDATE);
}
@@ -560,8 +560,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening password file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_PW_UPDATE);
}
@@ -573,8 +572,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking shadow password file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_PW_UPDATE);
}
@@ -586,8 +584,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening shadow password file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_PW_UPDATE);
}
@@ -599,8 +596,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_GRP_UPDATE);
}
@@ -610,8 +606,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_GRP_UPDATE);
}
@@ -624,8 +619,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking shadow group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_GRP_UPDATE);
}
@@ -636,8 +630,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening shadow group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_GRP_UPDATE);
}
@@ -652,8 +645,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking subordinate user file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SUB_UID_UPDATE);
}
@@ -664,8 +656,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening subordinate user file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SUB_UID_UPDATE);
}
@@ -678,8 +669,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"locking subordinate group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SUB_GID_UPDATE);
}
@@ -690,8 +680,7 @@ static void open_files (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"opening subordinate group file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SUB_GID_UPDATE);
}
@@ -738,8 +727,7 @@ static void update_user (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting user entries",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
#endif /* WITH_AUDIT */
SYSLOG ((LOG_INFO, "delete user '%s'\n", user_name));
}
@@ -763,7 +751,7 @@ static void user_cancel (const char *user)
}
argv[0] = cmd;
argv[1] = user;
argv[2] = (char *)0;
argv[2] = NULL;
(void) run_command (cmd, argv, NULL, &status);
}
@@ -802,11 +790,9 @@ static int is_owner (uid_t uid, const char *path)
static int remove_mailbox (void)
{
const char *maildir;
char* mailfile;
int i;
int errors = 0;
size_t len;
int i, errors = 0;
char *mailfile;
const char *maildir;
maildir = getdef_str ("MAIL_DIR");
#ifdef MAIL_SPOOL_DIR
@@ -818,18 +804,11 @@ static int remove_mailbox (void)
return 0;
}
len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 2;
mailfile = xmalloc (len);
if (prefix[0]) {
(void) snprintf (mailfile, len, "%s/%s/%s",
prefix, maildir, user_name);
xasprintf(&mailfile, "%s/%s/%s", prefix, maildir, user_name);
} else {
xasprintf(&mailfile, "%s/%s", maildir, user_name);
}
else {
(void) snprintf (mailfile, len, "%s/%s",
maildir, user_name);
}
mailfile[len-1] = '\0';
if (access (mailfile, F_OK) != 0) {
if (ENOENT == errno) {
@@ -846,8 +825,7 @@ static int remove_mailbox (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
free(mailfile);
return -1;
@@ -863,8 +841,7 @@ static int remove_mailbox (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
errors = 1;
/* continue */
@@ -874,8 +851,7 @@ static int remove_mailbox (void)
{
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
}
#endif /* WITH_AUDIT */
free(mailfile);
@@ -892,8 +868,7 @@ static int remove_mailbox (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
free(mailfile);
return 1;
@@ -909,8 +884,7 @@ static int remove_mailbox (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
errors = 1;
/* continue */
@@ -920,8 +894,7 @@ static int remove_mailbox (void)
{
audit_logger (AUDIT_DEL_USER, Prog,
"deleting mail file",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
}
#endif /* WITH_AUDIT */
free(mailfile);
@@ -931,22 +904,19 @@ static int remove_mailbox (void)
#ifdef WITH_TCB
static int remove_tcbdir (const char *user_name, uid_t user_id)
{
char *buf;
int ret = 0;
size_t buflen = (sizeof TCB_DIR) + strlen (user_name) + 2;
int ret = 0;
char *buf;
if (!getdef_bool ("USE_TCB")) {
return 0;
}
buf = malloc (buflen);
if (NULL == buf) {
fprintf (stderr, _("%s: Can't allocate memory, "
"tcb entry for %s not removed.\n"),
Prog, user_name);
if (asprintf(&buf, TCB_DIR "/%s", user_name) == -1) {
fprintf(stderr,
_("%s: Can't allocate memory, tcb entry for %s not removed.\n"),
Prog, user_name);
return 1;
}
snprintf (buf, buflen, TCB_DIR "/%s", user_name);
if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
fprintf (stderr, _("%s: Cannot drop privileges: %s\n"),
Prog, strerror (errno));
@@ -989,10 +959,6 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
(void) setlocale (LC_ALL, "");
@@ -1002,7 +968,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("userdel");
OPENLOG (Prog);
#ifdef WITH_AUDIT
audit_help_open ();
#endif /* WITH_AUDIT */
@@ -1086,7 +1052,7 @@ int main (int argc, char **argv)
exit (E_PW_UPDATE);
}
retval = pam_start ("userdel", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
@@ -1148,15 +1114,9 @@ int main (int argc, char **argv)
user_gid = pwd->pw_gid;
if (prefix[0]) {
size_t len = strlen(prefix) + strlen(pwd->pw_dir) + 2;
int wlen;
user_home = xmalloc(len);
wlen = snprintf(user_home, len, "%s/%s", prefix, pwd->pw_dir);
assert (wlen == (int) len -1);
}
else {
user_home = xstrdup (pwd->pw_dir);
xasprintf(&user_home, "%s/%s", prefix, pwd->pw_dir);
} else {
user_home = xstrdup(pwd->pw_dir);
}
pw_close();
}
@@ -1165,26 +1125,6 @@ int main (int argc, char **argv)
exit (E_NOTFOUND);
}
#endif /* WITH_TCB */
#ifdef USE_NIS
/*
* Now make sure it isn't an NIS user.
*/
if (__ispwNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: user %s is a NIS user\n"), Prog, user_name);
if ( !yp_get_default_domain (&nis_domain)
&& !yp_master (nis_domain, "passwd.byname", &nis_master)) {
fprintf (stderr,
_("%s: %s is the NIS master\n"),
Prog, nis_master);
}
exit (E_NOTFOUND);
}
#endif /* USE_NIS */
/*
* Check to make certain the user isn't logged in.
* Note: This is a best effort basis. The user may log in between,
@@ -1290,8 +1230,7 @@ int main (int argc, char **argv)
{
audit_logger (AUDIT_DEL_USER, Prog,
"deleting home directory",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_SUCCESS);
user_name, user_id, SHADOW_AUDIT_SUCCESS);
}
#endif /* WITH_AUDIT */
}
@@ -1313,8 +1252,7 @@ int main (int argc, char **argv)
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"removing SELinux user mapping",
user_name, (unsigned int) user_id,
SHADOW_AUDIT_FAILURE);
user_name, user_id, SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SE_UPDATE);
}
+142 -153
View File
@@ -17,7 +17,9 @@
#include <fcntl.h>
#include <getopt.h>
#include <grp.h>
#ifdef ENABLE_LASTLOG
#include <lastlog.h>
#endif /* ENABLE_LASTLOG */
#include <pwd.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
@@ -25,14 +27,18 @@
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include <stdio.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include "alloc.h"
#include "chkname.h"
#include "defines.h"
#include "faillog.h"
#include "getdef.h"
#include "groupio.h"
#include "memzero.h"
#include "nscd.h"
#include "sssd.h"
#include "prototypes.h"
@@ -52,6 +58,9 @@
#include "tcbfuncs.h"
#endif
#include "shadowlog.h"
#include "string/sprintf.h"
#include "time/day_to_str.h"
/*
* exit status values
@@ -82,7 +91,7 @@
/*
* Global variables
*/
const char *Prog;
static const char Prog[] = "usermod";
static char *user_name;
static char *user_newname;
@@ -98,6 +107,7 @@ static char *user_newhome;
static char *user_shell;
#ifdef WITH_SELINUX
static const char *user_selinux = "";
static const char *user_selinux_range = NULL;
#endif /* WITH_SELINUX */
static char *user_newshell;
static long user_expire;
@@ -163,10 +173,10 @@ static bool sub_gid_locked = false;
/* local function prototypes */
static int get_groups (char *);
static /*@noreturn@*/void usage (int status);
NORETURN static void usage (int status);
static void new_pwent (struct passwd *);
static void new_spent (struct spwd *);
static /*@noreturn@*/void fail_exit (int);
NORETURN static void fail_exit (int);
static void update_group (void);
#ifdef SHADOWGRP
@@ -179,7 +189,9 @@ static void close_files (void);
static void open_files (void);
static void usr_update (void);
static void move_home (void);
#ifdef ENABLE_LASTLOG
static void update_lastlog (void);
#endif /* ENABLE_LASTLOG */
static void update_faillog (void);
#ifndef NO_MOVE_MAILBOX
@@ -198,14 +210,14 @@ extern int allow_bad_names;
static int get_groups (char *list)
{
char *cp;
const struct group *grp;
struct group *grp;
int errors = 0;
int ngroups = 0;
/*
* Initialize the list to be empty
*/
user_groups[0] = (char *) 0;
user_groups[0] = NULL;
if ('\0' == *list) {
return 0;
@@ -251,25 +263,11 @@ static int get_groups (char *list)
continue;
}
#ifdef USE_NIS
/*
* Don't add this group if they are an NIS group. Tell the
* user to go to the server for this group.
*/
if (__isgrNIS ()) {
fprintf (stderr,
_("%s: group '%s' is a NIS group.\n"),
Prog, grp->gr_name);
gr_free ((struct group *)grp);
continue;
}
#endif
if (ngroups == sys_ngroups) {
fprintf (stderr,
_("%s: too many groups specified (max %d).\n"),
Prog, ngroups);
gr_free ((struct group *)grp);
gr_free (grp);
break;
}
@@ -277,10 +275,10 @@ static int get_groups (char *list)
* Add the group name to the user's list of groups.
*/
user_groups[ngroups++] = xstrdup (grp->gr_name);
gr_free ((struct group *)grp);
gr_free (grp);
} while (NULL != list);
user_groups[ngroups] = (char *) 0;
user_groups[ngroups] = NULL;
/*
* Any errors in finding group names are fatal
@@ -307,21 +305,28 @@ static struct ulong_range getulong_range(const char *str)
errno = 0;
first = strtoll(str, &pos, 10);
if (('\0' == *str) || ('-' != *pos ) || (ERANGE == errno) ||
(first != (unsigned long int)first))
if (('\0' == *str) || ('-' != *pos ) || (0 != errno) ||
(first != (unsigned long)first))
goto out;
errno = 0;
last = strtoll(pos + 1, &pos, 10);
if (('\0' != *pos ) || (ERANGE == errno) ||
(last != (unsigned long int)last))
if (('\0' != *pos ) || (0 != errno) ||
(last != (unsigned long)last))
goto out;
if (first > last)
goto out;
result.first = (unsigned long int)first;
result.last = (unsigned long int)last;
/*
* uid_t in linux is an unsigned int, anything over this is an invalid
* range will be later refused anyway by get_map_ranges().
*/
if (first > UINT_MAX || last > UINT_MAX)
goto out;
result.first = (unsigned long)first;
result.last = (unsigned long)last;
out:
return result;
}
@@ -342,7 +347,7 @@ static int prepend_range(const char *str, struct ulong_range_list_entry **head)
if (range.first > range.last)
return 0;
entry = malloc(sizeof(*entry));
entry = MALLOC(1, struct ulong_range_list_entry);
if (!entry) {
fprintf (stderr,
_("%s: failed to allocate memory: %s\n"),
@@ -359,7 +364,9 @@ static int prepend_range(const char *str, struct ulong_range_list_entry **head)
/*
* usage - display usage message and exit
*/
static /*@noreturn@*/void usage (int status)
NORETURN
static void
usage (int status)
{
FILE *usageout = (E_SUCCESS != status) ? stderr : stdout;
(void) fprintf (usageout,
@@ -401,6 +408,7 @@ static /*@noreturn@*/void usage (int status)
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
(void) fputs (_(" -Z, --selinux-user SEUSER new SELinux user mapping for the user account\n"), usageout);
(void) fputs (_(" --selinux-range SERANGE new SELinux MLS range for the user account\n"), usageout);
#endif /* WITH_SELINUX */
(void) fputs ("\n", usageout);
exit (status);
@@ -413,20 +421,17 @@ static /*@noreturn@*/void usage (int status)
static char *new_pw_passwd (char *pw_pass)
{
if (Lflg && ('!' != pw_pass[0])) {
char *buf = xmalloc (strlen (pw_pass) + 2);
char *buf = XMALLOC(strlen(pw_pass) + 2, char);
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"updating passwd",
user_newname, (unsigned int) user_newid, 0);
"updating passwd", user_newname, user_newid, 0);
#endif
SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname));
strcpy (buf, "!");
strcat (buf, pw_pass);
pw_pass = buf;
} else if (Uflg && pw_pass[0] == '!') {
char *s;
if (pw_pass[1] == '\0') {
fprintf (stderr,
_("%s: unlocking the user's password would result in a passwordless account.\n"
@@ -437,20 +442,14 @@ static char *new_pw_passwd (char *pw_pass)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"updating password",
user_newname, (unsigned int) user_newid, 0);
"updating password", user_newname, user_newid, 0);
#endif
SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname));
s = pw_pass;
while ('\0' != *s) {
*s = *(s + 1);
s++;
}
memmove(pw_pass, pw_pass + 1, strlen(pw_pass));
} else if (pflg) {
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing password",
user_newname, (unsigned int) user_newid, 1);
"changing password", user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO, "change user '%s' password", user_newname));
pw_pass = xstrdup (user_pass);
@@ -479,8 +478,7 @@ static void new_pwent (struct passwd *pwent)
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing name",
user_newname, (unsigned int) user_newid, 1);
"changing name", user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user name '%s' to '%s'",
@@ -500,8 +498,7 @@ static void new_pwent (struct passwd *pwent)
if (uflg) {
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing uid",
user_newname, (unsigned int) user_newid, 1);
"changing uid", user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' UID from '%d' to '%d'",
@@ -512,7 +509,7 @@ static void new_pwent (struct passwd *pwent)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing primary group",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' GID from '%d' to '%d'",
@@ -522,8 +519,7 @@ static void new_pwent (struct passwd *pwent)
if (cflg) {
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing comment",
user_newname, (unsigned int) user_newid, 1);
"changing comment", user_newname, user_newid, 1);
#endif
pwent->pw_gecos = user_newcomment;
}
@@ -532,7 +528,7 @@ static void new_pwent (struct passwd *pwent)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing home directory",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' home from '%s' to '%s'",
@@ -549,7 +545,7 @@ static void new_pwent (struct passwd *pwent)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing user shell",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' shell from '%s' to '%s'",
@@ -580,7 +576,7 @@ static void new_spent (struct spwd *spent)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing inactive days",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' inactive from '%ld' to '%ld'",
@@ -590,12 +586,13 @@ static void new_spent (struct spwd *spent)
if (eflg) {
/* log dates rather than numbers of days. */
char new_exp[16], old_exp[16];
date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY);
date_to_str (sizeof(old_exp), old_exp, user_expire * DAY);
DAY_TO_STR(new_exp, user_newexpire);
DAY_TO_STR(old_exp, user_expire);
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing expiration date",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
#endif
SYSLOG ((LOG_INFO,
"change user '%s' expiration from '%s' to '%s'",
@@ -615,7 +612,7 @@ static void new_spent (struct spwd *spent)
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
if (pflg) {
spent->sp_lstchg = (long) gettime () / SCALE;
spent->sp_lstchg = gettime () / DAY;
if (0 == spent->sp_lstchg) {
/* Better disable aging than requiring a password
* change. */
@@ -627,7 +624,9 @@ static void new_spent (struct spwd *spent)
/*
* fail_exit - exit with an error code after unlocking files
*/
static /*@noreturn@*/void fail_exit (int code)
NORETURN
static void
fail_exit (int code)
{
if (gr_locked) {
if (gr_unlock () == 0) {
@@ -967,7 +966,6 @@ static void grp_update (void)
*/
static void process_flags (int argc, char **argv)
{
const struct group *grp;
struct stat st;
bool anyflag = false;
@@ -978,6 +976,7 @@ static void process_flags (int argc, char **argv)
int c;
static struct option long_options[] = {
{"append", no_argument, NULL, 'a'},
{"badname", no_argument, NULL, 'b'},
{"badnames", no_argument, NULL, 'b'},
{"comment", required_argument, NULL, 'c'},
{"home", required_argument, NULL, 'd'},
@@ -1000,11 +999,12 @@ static void process_flags (int argc, char **argv)
#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'},
{"add-subgids", required_argument, NULL, 'w'},
{"del-subgids", required_argument, NULL, 'W'},
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
{"selinux-user", required_argument, NULL, 'Z'},
{"selinux-user", required_argument, NULL, 'Z'},
{"selinux-range", required_argument, NULL, 202},
#endif /* WITH_SELINUX */
{NULL, 0, NULL, '\0'}
};
@@ -1058,11 +1058,10 @@ static void process_flags (int argc, char **argv)
Prog, optarg);
exit (E_BAD_ARG);
}
user_newexpire *= DAY / SCALE;
eflg = true;
break;
case 'f':
if ( (getlong (optarg, &user_newinactive) == 0)
if ( (getlong(optarg, &user_newinactive) == -1)
|| (user_newinactive < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -1072,7 +1071,10 @@ static void process_flags (int argc, char **argv)
fflg = true;
break;
case 'g':
grp = getgr_nam_gid (optarg);
{
struct group *grp;
grp = prefix_getgr_nam_gid (optarg);
if (NULL == grp) {
fprintf (stderr,
_("%s: group '%s' does not exist\n"),
@@ -1083,6 +1085,7 @@ static void process_flags (int argc, char **argv)
gflg = true;
gr_free (grp);
break;
}
case 'G':
if (get_groups (optarg) != 0) {
exit (E_NOTFOUND);
@@ -1146,7 +1149,7 @@ static void process_flags (int argc, char **argv)
sflg = true;
break;
case 'u':
if ( (get_uid (optarg, &user_newid) ==0)
if ( (get_uid(optarg, &user_newid) == -1)
|| (user_newid == (uid_t)-1)) {
fprintf (stderr,
_("%s: invalid user ID '%s'\n"),
@@ -1214,6 +1217,9 @@ static void process_flags (int argc, char **argv)
exit (E_BAD_ARG);
}
break;
case 202:
user_selinux_range = optarg;
break;
#endif /* WITH_SELINUX */
default:
usage (E_USAGE);
@@ -1258,46 +1264,16 @@ static void process_flags (int argc, char **argv)
user_newgid = user_gid;
}
if (prefix[0]) {
size_t len = strlen(prefix) + strlen(user_home) + 2;
int wlen;
prefix_user_home = xmalloc(len);
wlen = snprintf(prefix_user_home, len, "%s/%s", prefix, user_home);
assert (wlen == (int) len -1);
xasprintf(&prefix_user_home, "%s/%s", prefix, user_home);
if (user_newhome) {
len = strlen(prefix) + strlen(user_newhome) + 2;
prefix_user_newhome = xmalloc(len);
wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome);
assert (wlen == (int) len -1);
xasprintf(&prefix_user_newhome, "%s/%s",
prefix, user_newhome);
}
}
else {
} else {
prefix_user_home = user_home;
prefix_user_newhome = user_newhome;
}
#ifdef USE_NIS
/*
* Now make sure it isn't an NIS user.
*/
if (__ispwNIS ()) {
char *nis_domain;
char *nis_master;
fprintf (stderr,
_("%s: user %s is a NIS user\n"),
Prog, user_name);
if ( !yp_get_default_domain (&nis_domain)
&& !yp_master (nis_domain, "passwd.byname", &nis_master)) {
fprintf (stderr,
_("%s: %s is the NIS master\n"),
Prog, nis_master);
}
exit (E_NOTFOUND);
}
#endif
{
const struct spwd *spwd = NULL;
/* local, no need for xgetspnam */
@@ -1354,6 +1330,15 @@ static void process_flags (int argc, char **argv)
usage (E_USAGE);
}
#ifdef WITH_SELINUX
if (user_selinux_range && !Zflg) {
fprintf (stderr,
_("%s: %s flag is only allowed with the %s flag\n"),
Prog, "--selinux-range", "--selinux-user");
usage (E_USAGE);
}
#endif /* WITH_SELINUX */
if (user_newid == user_id) {
uflg = false;
oflg = false;
@@ -1723,7 +1708,7 @@ static void usr_update (void)
* a shadowed password
* + aging information is requested
*/
memset (&spent, 0, sizeof spent);
bzero(&spent, sizeof spent);
spent.sp_namp = user_name;
/* The user explicitly asked for a shadow feature.
@@ -1732,7 +1717,7 @@ static void usr_update (void)
spent.sp_pwdp = xstrdup (pwent.pw_passwd);
pwent.pw_passwd = xstrdup (SHADOW_PASSWD_STRING);
spent.sp_lstchg = (long) gettime () / SCALE;
spent.sp_lstchg = gettime () / DAY;
if (0 == spent.sp_lstchg) {
/* Better disable aging than
* requiring a password change */
@@ -1819,7 +1804,7 @@ static void move_home (void)
if (uflg || gflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing home directory owner",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
}
#endif
@@ -1838,8 +1823,7 @@ static void move_home (void)
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"moving home directory",
user_newname, (unsigned int) user_newid,
1);
user_newname, user_newid, 1);
#endif
return;
} else {
@@ -1869,7 +1853,7 @@ static void move_home (void)
Prog,
"moving home directory",
user_newname,
(unsigned int) user_newid,
user_newid,
1);
#endif
return;
@@ -1897,6 +1881,7 @@ static void move_home (void)
* left alone in case the UID was shared. It doesn't hurt anything
* to just leave it be.
*/
#ifdef ENABLE_LASTLOG
static void update_lastlog (void)
{
struct lastlog ll;
@@ -1909,7 +1894,7 @@ static void update_lastlog (void)
return;
}
max_uid = (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
max_uid = getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
if (user_newid > max_uid) {
/* do not touch lastlog for large uids */
return;
@@ -1928,7 +1913,7 @@ static void update_lastlog (void)
&& (read (fd, &ll, sizeof ll) == (ssize_t) sizeof ll)) {
/* Copy the old entry to its new location */
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|| (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|| (write_full(fd, &ll, sizeof ll) == -1)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
@@ -1944,7 +1929,7 @@ static void update_lastlog (void)
/* Reset the new uid's lastlog entry */
memzero (&ll, sizeof (ll));
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|| (write (fd, &ll, sizeof ll) != (ssize_t) sizeof ll)
|| (write_full(fd, &ll, sizeof ll) == -1)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"),
@@ -1953,8 +1938,13 @@ static void update_lastlog (void)
}
}
(void) close (fd);
if (close (fd) != 0 && errno != EINTR) {
fprintf (stderr,
_("%s: failed to copy the lastlog entry of user %ju to user %ju: %s\n"),
Prog, (uintmax_t) user_id, (uintmax_t) user_newid, strerror (errno));
}
}
#endif /* ENABLE_LASTLOG */
/*
* update_faillog - update the faillog file
@@ -1984,10 +1974,10 @@ static void update_faillog (void)
}
if ( (lseek (fd, off_uid, SEEK_SET) == off_uid)
&& (read (fd, (char *) &fl, sizeof fl) == (ssize_t) sizeof fl)) {
&& (read (fd, &fl, sizeof fl) == (ssize_t) sizeof fl)) {
/* Copy the old entry to its new location */
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|| (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)
|| (write_full(fd, &fl, sizeof fl) == -1)
|| (fsync (fd) != 0)) {
fprintf (stderr,
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
@@ -2003,7 +1993,8 @@ static void update_faillog (void)
/* Reset the new uid's faillog entry */
memzero (&fl, sizeof (fl));
if ( (lseek (fd, off_newuid, SEEK_SET) != off_newuid)
|| (write (fd, &fl, sizeof fl) != (ssize_t) sizeof fl)) {
|| (write_full(fd, &fl, sizeof fl) == -1))
{
fprintf (stderr,
_("%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"),
Prog, (unsigned long) user_id, (unsigned long) user_newid, strerror (errno));
@@ -2011,7 +2002,11 @@ static void update_faillog (void)
}
}
(void) close (fd);
if (close (fd) != 0 && errno != EINTR) {
fprintf (stderr,
_("%s: failed to copy the faillog entry of user %ju to user %ju: %s\n"),
Prog, (uintmax_t) user_id, (uintmax_t) user_newid, strerror (errno));
}
}
#ifndef NO_MOVE_MAILBOX
@@ -2024,12 +2019,10 @@ static void update_faillog (void)
*/
static void move_mailbox (void)
{
const char *maildir;
char* mailfile;
char* newmailfile;
int fd;
struct stat st;
size_t len;
int fd;
char *mailfile;
const char *maildir;
struct stat st;
maildir = getdef_str ("MAIL_DIR");
#ifdef MAIL_SPOOL_DIR
@@ -2040,8 +2033,6 @@ static void move_mailbox (void)
if (NULL == maildir) {
return;
}
len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 2;
mailfile = alloca (len);
/*
* O_NONBLOCK is to make sure open won't hang on mandatory locks.
@@ -2050,14 +2041,10 @@ static void move_mailbox (void)
* between stat and chown). --marekm
*/
if (prefix[0]) {
(void) snprintf (mailfile, len, "%s/%s/%s",
prefix, maildir, user_name);
xasprintf(&mailfile, "%s/%s/%s", prefix, maildir, user_name);
} else {
xasprintf(&mailfile, "%s/%s", maildir, user_name);
}
else {
(void) snprintf (mailfile, len, "%s/%s",
maildir, user_name);
}
mailfile[len-1] = '\0';
fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0);
if (fd < 0) {
@@ -2065,11 +2052,13 @@ static void move_mailbox (void)
if (errno != ENOENT) {
perror (mailfile);
}
free(mailfile);
return;
}
if (fstat (fd, &st) < 0) {
perror ("fstat");
(void) close (fd);
free(mailfile);
return;
}
if (st.st_uid != user_id) {
@@ -2077,6 +2066,7 @@ static void move_mailbox (void)
fprintf (stderr, _("%s: warning: %s not owned by %s\n"),
Prog, mailfile, user_name);
(void) close (fd);
free(mailfile);
return;
}
if (uflg) {
@@ -2087,7 +2077,7 @@ static void move_mailbox (void)
else {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing mail file owner",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
}
#endif
}
@@ -2095,17 +2085,14 @@ static void move_mailbox (void)
(void) close (fd);
if (lflg) {
len = strlen (prefix) + strlen (maildir) + strlen (user_newname) + 2;
newmailfile = alloca(len);
char *newmailfile;
if (prefix[0]) {
(void) snprintf (newmailfile, len, "%s/%s/%s",
prefix, maildir, user_newname);
xasprintf(&newmailfile, "%s/%s/%s",
prefix, maildir, user_newname);
} else {
xasprintf(&newmailfile, "%s/%s", maildir, user_newname);
}
else {
(void) snprintf (newmailfile, len, "%s/%s",
maildir, user_newname);
}
newmailfile[len - 1] = '\0';
if ( (link (mailfile, newmailfile) != 0)
|| (unlink (mailfile) != 0)) {
perror (_("failed to rename mailbox"));
@@ -2114,10 +2101,14 @@ static void move_mailbox (void)
else {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing mail file name",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
}
free(newmailfile);
#endif
}
free(mailfile);
}
#endif
@@ -2133,10 +2124,6 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
/*
* Get my name so that I can use it to report errors.
*/
Prog = Basename (argv[0]);
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -2147,14 +2134,14 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
prefix = process_prefix_flag ("-P", argc, argv);
OPENLOG ("usermod");
OPENLOG (Prog);
#ifdef WITH_AUDIT
audit_help_open ();
#endif
sys_ngroups = sysconf (_SC_NGROUPS_MAX);
user_groups = (char **) malloc (sizeof (char *) * (1 + sys_ngroups));
user_groups[0] = (char *) 0;
user_groups = XMALLOC(sys_ngroups + 1, char *);
user_groups[0] = NULL;
is_shadow_pwd = spw_file_present ();
#ifdef SHADOWGRP
@@ -2193,7 +2180,7 @@ int main (int argc, char **argv)
exit (1);
}
retval = pam_start ("usermod", pampw->pw_name, &conv, &pamh);
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
@@ -2305,14 +2292,14 @@ int main (int argc, char **argv)
#ifdef WITH_SELINUX
if (Zflg) {
if ('\0' != *user_selinux) {
if (set_seuser (user_name, user_selinux) != 0) {
if (set_seuser (user_name, user_selinux, user_selinux_range) != 0) {
fprintf (stderr,
_("%s: warning: the user name %s to %s SELinux user mapping failed.\n"),
Prog, user_name, user_selinux);
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"modifying User mapping ",
user_name, (unsigned int) user_id,
user_name, user_id,
SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SE_UPDATE);
@@ -2325,7 +2312,7 @@ int main (int argc, char **argv)
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"removing SELinux user mapping",
user_name, (unsigned int) user_id,
user_name, user_id,
SHADOW_AUDIT_FAILURE);
#endif /* WITH_AUDIT */
fail_exit (E_SE_UPDATE);
@@ -2345,7 +2332,9 @@ int main (int argc, char **argv)
#endif /* NO_MOVE_MAILBOX */
if (uflg) {
#ifdef ENABLE_LASTLOG
update_lastlog ();
#endif /* ENABLE_LASTLOG */
update_faillog ();
}
@@ -2367,7 +2356,7 @@ int main (int argc, char **argv)
if (uflg || gflg) {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing home directory owner",
user_newname, (unsigned int) user_newid, 1);
user_newname, user_newid, 1);
}
#endif
if (chown_tree (dflg ? prefix_user_newhome : prefix_user_home,
+57 -56
View File
@@ -26,7 +26,10 @@
#include <sys/types.h>
#include <unistd.h>
#include <utime.h>
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "groupio.h"
#include "nscd.h"
#include "sssd.h"
@@ -41,6 +44,8 @@
#include "tcbfuncs.h"
#endif /* WITH_TCB */
#include "shadowlog.h"
#include "string/sprintf.h"
#define MSG_WARN_EDIT_OTHER_FILE _( \
"You have modified %s.\n"\
@@ -50,7 +55,7 @@
/*
* Global variables
*/
const char *Prog;
static const char *Prog;
static const char *filename, *fileeditname;
static bool filelocked = false;
@@ -190,18 +195,17 @@ static void vipwexit (const char *msg, int syserr, int ret)
static void
vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
{
const char *editor;
pid_t pid;
struct stat st1, st2;
int status;
FILE *f;
pid_t orig_pgrp, editor_pgrp = -1;
sigset_t mask, omask;
int status;
char *to_rename;
FILE *f;
pid_t pid, orig_pgrp, editor_pgrp = -1;
sigset_t mask, omask;
const char *editor;
struct stat st1, st2;
/* FIXME: the following should have variable sizes */
char filebackup[1024], fileedit[1024];
char *to_rename;
char filebackup[1024], fileedit[1024];
snprintf (filebackup, sizeof filebackup, "%s-", file);
SNPRINTF(filebackup, "%s-", file);
#ifdef WITH_TCB
if (tcb_mode) {
if ( (mkdir (TCB_DIR "/" SHADOWTCB_SCRATCHDIR, 0700) != 0)
@@ -211,12 +215,12 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
vipwexit (_("failed to drop privileges"), errno, 1);
}
snprintf (fileedit, sizeof fileedit,
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s",
user);
SNPRINTF(fileedit,
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s",
user);
} else {
#endif /* WITH_TCB */
snprintf (fileedit, sizeof fileedit, "%s.edit", file);
SNPRINTF(fileedit, "%s.edit", file);
#ifdef WITH_TCB
}
#endif /* WITH_TCB */
@@ -292,7 +296,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
} else if (0 == pid) {
/* use the system() call to invoke the editor so that it accepts
command line args in the EDITOR and VISUAL environment vars */
char *buf;
char *buf;
/* Wait for parent to make us the foreground pgrp. */
if (orig_pgrp != -1) {
@@ -302,9 +306,8 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
continue;
}
buf = (char *) malloc (strlen (editor) + strlen (fileedit) + 2);
snprintf (buf, strlen (editor) + strlen (fileedit) + 2,
"%s %s", editor, fileedit);
xasprintf(&buf, "%s %s", editor, fileedit);
status = system (buf);
if (-1 == status) {
fprintf (stderr, _("%s: %s: %s\n"), Prog, editor,
@@ -418,13 +421,11 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
if (stat (file, &st1) != 0) {
vipwexit (_("failed to stat edited file"), errno, 1);
}
to_rename = malloc (strlen (file) + 2);
if (NULL == to_rename) {
vipwexit (_("failed to allocate memory"), errno, 1);
}
snprintf (to_rename, strlen (file) + 2, "%s+", file);
if (asprintf(&to_rename, "%s+", file) == -1)
vipwexit (_("asprintf(3) failed"), errno, 1);
if (create_backup_file (f, to_rename, &st1) != 0) {
free (to_rename);
free(to_rename);
vipwexit (_("failed to create backup file"), errno, 1);
}
(void) fclose (f);
@@ -442,7 +443,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
Prog, file, strerror (errno), to_rename);
#ifdef WITH_TCB
if (tcb_mode) {
free (to_rename);
free(to_rename);
}
#endif /* WITH_TCB */
vipwexit (0, 0, 1);
@@ -450,7 +451,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
#ifdef WITH_TCB
if (tcb_mode) {
free (to_rename);
free(to_rename);
if (shadowtcb_gain_priv () == SHADOWTCB_FAILURE) {
vipwexit (_("failed to gain privileges"), errno, 1);
}
@@ -467,10 +468,12 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
int main (int argc, char **argv)
{
bool editshadow = false;
bool do_vipw;
bool editshadow = false;
bool do_vigr;
Prog = Basename (argv[0]);
do_vigr = (strcmp(Basename(argv[0]), "vigr") == 0);
Prog = do_vigr ? "vigr" : "vipw";
log_set_progname(Prog);
log_set_logfd(stderr);
@@ -480,9 +483,7 @@ int main (int argc, char **argv)
process_root_flag ("-R", argc, argv);
do_vipw = (strcmp (Prog, "vigr") != 0);
OPENLOG (do_vipw ? "vipw" : "vigr");
OPENLOG(Prog);
{
/*
@@ -510,13 +511,13 @@ int main (int argc, char **argv)
long_options, NULL)) != -1) {
switch (c) {
case 'g':
do_vipw = false;
do_vigr = true;
break;
case 'h':
usage (E_SUCCESS);
break;
case 'p':
do_vipw = true;
do_vigr = false;
break;
case 'q':
quiet = true;
@@ -541,7 +542,27 @@ int main (int argc, char **argv)
}
}
if (do_vipw) {
if (do_vigr) {
#ifdef SHADOWGRP
if (editshadow) {
vipwedit (sgr_dbname (), sgr_lock, sgr_unlock);
printf (MSG_WARN_EDIT_OTHER_FILE,
sgr_dbname (),
gr_dbname (),
"vigr");
} else {
#endif /* SHADOWGRP */
vipwedit (gr_dbname (), gr_lock, gr_unlock);
#ifdef SHADOWGRP
if (sgr_file_present ()) {
printf (MSG_WARN_EDIT_OTHER_FILE,
gr_dbname (),
sgr_dbname (),
"vigr -s");
}
}
#endif /* SHADOWGRP */
} else {
if (editshadow) {
#ifdef WITH_TCB
if (getdef_bool ("USE_TCB") && (NULL != user)) {
@@ -568,26 +589,6 @@ int main (int argc, char **argv)
"vipw -s");
}
}
} else {
#ifdef SHADOWGRP
if (editshadow) {
vipwedit (sgr_dbname (), sgr_lock, sgr_unlock);
printf (MSG_WARN_EDIT_OTHER_FILE,
sgr_dbname (),
gr_dbname (),
"vigr");
} else {
#endif /* SHADOWGRP */
vipwedit (gr_dbname (), gr_lock, gr_unlock);
#ifdef SHADOWGRP
if (sgr_file_present ()) {
printf (MSG_WARN_EDIT_OTHER_FILE,
gr_dbname (),
sgr_dbname (),
"vigr -s");
}
}
#endif /* SHADOWGRP */
}
nscd_flush_cache ("passwd");