New upstream version 4.15.1
This commit is contained in:
+18
-24
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 = ∅
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 = ∅
|
||||
@@ -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
@@ -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]);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+47
-109
@@ -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
@@ -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
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user