[svn-upgrade] Integrating new upstream version, shadow (4.0.13)
This commit is contained in:
@@ -50,29 +50,30 @@ LDADD = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM)
|
||||
chage_LDADD = $(LDADD) $(LIBPAM)
|
||||
chage_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
chfn_LDADD = $(LDADD) $(LIBPAM)
|
||||
chsh_SOURCES = \
|
||||
chsh.c \
|
||||
chsh_chkshell.c
|
||||
chsh_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupmod_LDADD = $(LDADD) $(LIBPAM)
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM)
|
||||
gpasswd_LDADD = $(LDADD) $(LIBAUDIT)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
groupmod_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
login_SOURCES = \
|
||||
login.c \
|
||||
login_nopam.c
|
||||
login_LDADD = $(LDADD) $(LIBPAM)
|
||||
newusers_LDADD = $(LDADD) $(LIBPAM)
|
||||
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK)
|
||||
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT)
|
||||
su_SOURCES = \
|
||||
su.c \
|
||||
suauth.c
|
||||
su_LDADD = $(LDADD) $(LIBPAM)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM)
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM)
|
||||
usermod_LDADD = $(LDADD) $(LIBPAM)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
usermod_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
|
||||
install-am: all-am
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
@@ -50,7 +50,8 @@ noinst_PROGRAMS = id$(EXEEXT) sulogin$(EXEEXT)
|
||||
subdir = src
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.in
|
||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
@@ -68,7 +69,8 @@ chage_OBJECTS = chage.$(OBJEXT)
|
||||
am__DEPENDENCIES_1 = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
am__DEPENDENCIES_2 =
|
||||
chage_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
chage_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
chfn_SOURCES = chfn.c
|
||||
chfn_OBJECTS = chfn.$(OBJEXT)
|
||||
chfn_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
@@ -90,18 +92,19 @@ faillog_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
gpasswd_SOURCES = gpasswd.c
|
||||
gpasswd_OBJECTS = gpasswd.$(OBJEXT)
|
||||
gpasswd_LDADD = $(LDADD)
|
||||
gpasswd_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
gpasswd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
groupadd_SOURCES = groupadd.c
|
||||
groupadd_OBJECTS = groupadd.$(OBJEXT)
|
||||
groupadd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
groupadd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
groupdel_SOURCES = groupdel.c
|
||||
groupdel_OBJECTS = groupdel.$(OBJEXT)
|
||||
groupdel_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
groupdel_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
groupmod_SOURCES = groupmod.c
|
||||
groupmod_OBJECTS = groupmod.$(OBJEXT)
|
||||
groupmod_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
groupmod_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
groups_SOURCES = groups.c
|
||||
groups_OBJECTS = groups.$(OBJEXT)
|
||||
groups_LDADD = $(LDADD)
|
||||
@@ -151,7 +154,7 @@ newusers_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
passwd_SOURCES = passwd.c
|
||||
passwd_OBJECTS = passwd.$(OBJEXT)
|
||||
passwd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_2)
|
||||
pwck_SOURCES = pwck.c
|
||||
pwck_OBJECTS = pwck.$(OBJEXT)
|
||||
pwck_LDADD = $(LDADD)
|
||||
@@ -177,13 +180,16 @@ sulogin_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
useradd_SOURCES = useradd.c
|
||||
useradd_OBJECTS = useradd.$(OBJEXT)
|
||||
useradd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
useradd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
userdel_SOURCES = userdel.c
|
||||
userdel_OBJECTS = userdel.$(OBJEXT)
|
||||
userdel_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
userdel_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
usermod_SOURCES = usermod.c
|
||||
usermod_OBJECTS = usermod.$(OBJEXT)
|
||||
usermod_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
usermod_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_2)
|
||||
vipw_SOURCES = vipw.c
|
||||
vipw_OBJECTS = vipw.$(OBJEXT)
|
||||
vipw_LDADD = $(LDADD)
|
||||
@@ -241,6 +247,8 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ENABLE_REGENERATE_MAN_FALSE = @ENABLE_REGENERATE_MAN_FALSE@
|
||||
ENABLE_REGENERATE_MAN_TRUE = @ENABLE_REGENERATE_MAN_TRUE@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
FFLAGS = @FFLAGS@
|
||||
@@ -252,6 +260,7 @@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBAUDIT = @LIBAUDIT@
|
||||
LIBCRACK = @LIBCRACK@
|
||||
LIBCRYPT = @LIBCRYPT@
|
||||
LIBICONV = @LIBICONV@
|
||||
@@ -291,6 +300,9 @@ U = @U@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
XGETTEXT = @XGETTEXT@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
@@ -350,32 +362,33 @@ LDADD = $(top_builddir)/libmisc/libmisc.a \
|
||||
$(top_builddir)/lib/libshadow.la
|
||||
|
||||
AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM)
|
||||
chage_LDADD = $(LDADD) $(LIBPAM)
|
||||
chage_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
chfn_LDADD = $(LDADD) $(LIBPAM)
|
||||
chsh_SOURCES = \
|
||||
chsh.c \
|
||||
chsh_chkshell.c
|
||||
|
||||
chsh_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM)
|
||||
groupmod_LDADD = $(LDADD) $(LIBPAM)
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM)
|
||||
gpasswd_LDADD = $(LDADD) $(LIBAUDIT)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
groupmod_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
login_SOURCES = \
|
||||
login.c \
|
||||
login_nopam.c
|
||||
|
||||
login_LDADD = $(LDADD) $(LIBPAM)
|
||||
newusers_LDADD = $(LDADD) $(LIBPAM)
|
||||
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK)
|
||||
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT)
|
||||
su_SOURCES = \
|
||||
su.c \
|
||||
suauth.c
|
||||
|
||||
su_LDADD = $(LDADD) $(LIBPAM)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM)
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM)
|
||||
usermod_LDADD = $(LDADD) $(LIBPAM)
|
||||
useradd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
userdel_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
usermod_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -389,9 +402,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu src/Makefile
|
||||
$(AUTOMAKE) --foreign src/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
|
173
src/chage.c
173
src/chage.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: chage.c,v 1.55 2005/08/09 17:20:02 kloczek Exp $")
|
||||
#ident "$Id: chage.c,v 1.66 2005/10/04 20:26:41 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
@@ -102,7 +102,6 @@ int isnum (const char *s)
|
||||
/*
|
||||
* usage - print command line syntax and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: chage [options] user\n"
|
||||
@@ -144,7 +143,6 @@ static void date_to_str (char *buf, size_t maxsize, time_t date)
|
||||
* any other negative value is an error. very large positive values will
|
||||
* be handled elsewhere.
|
||||
*/
|
||||
|
||||
static int new_fields (void)
|
||||
{
|
||||
char buf[200];
|
||||
@@ -225,7 +223,6 @@ static void print_date (time_t date)
|
||||
* values will be displayed as a calendar date, or the word "never" if
|
||||
* the date is 1/1/70, which is day number 0.
|
||||
*/
|
||||
|
||||
static void list_fields (void)
|
||||
{
|
||||
long changed = 0;
|
||||
@@ -235,7 +232,6 @@ static void list_fields (void)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
printf (_("Last password change\t\t\t\t\t: "));
|
||||
if (lastday <= 0) {
|
||||
printf (_("never\n"));
|
||||
@@ -248,7 +244,6 @@ static void list_fields (void)
|
||||
* The password expiration date is determined from the last change
|
||||
* date plus the number of days the password is valid for.
|
||||
*/
|
||||
|
||||
printf (_("Password expires\t\t\t\t\t: "));
|
||||
if (lastday <= 0 || maxdays >= 10000 * (DAY / SCALE)
|
||||
|| maxdays < 0) {
|
||||
@@ -264,7 +259,6 @@ static void list_fields (void)
|
||||
* number of inactive days is added. The resulting date is when the
|
||||
* active will be disabled.
|
||||
*/
|
||||
|
||||
printf (_("Password inactive\t\t\t\t\t: "));
|
||||
if (lastday <= 0 || inactdays < 0 ||
|
||||
maxdays >= 10000 * (DAY / SCALE) || maxdays < 0) {
|
||||
@@ -278,7 +272,6 @@ static void list_fields (void)
|
||||
* The account will expire on the given date regardless of the
|
||||
* password expiring or not.
|
||||
*/
|
||||
|
||||
printf (_("Account expires\t\t\t\t\t\t: "));
|
||||
if (expdays < 0) {
|
||||
printf (_("never\n"));
|
||||
@@ -294,7 +287,6 @@ static void list_fields (void)
|
||||
* expires that the user is told, and the number of days after the
|
||||
* password expires that the account becomes unusable.
|
||||
*/
|
||||
|
||||
printf (_("Minimum number of days between password change\t\t: %ld\n"),
|
||||
mindays);
|
||||
printf (_("Maximum number of days between password change\t\t: %ld\n"),
|
||||
@@ -366,6 +358,9 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
sanitize_env ();
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
@@ -373,7 +368,8 @@ int main (int argc, char **argv)
|
||||
|
||||
ruid = getuid ();
|
||||
#ifdef WITH_SELINUX
|
||||
amroot = (ruid == 0 && checkPasswdAccess (PASSWD__ROOTOK) == 0);
|
||||
amroot = (ruid == 0
|
||||
&& selinux_check_passwd_access (PASSWD__ROOTOK) == 0);
|
||||
#else
|
||||
amroot = (ruid == 0);
|
||||
#endif
|
||||
@@ -470,6 +466,10 @@ int main (int argc, char **argv)
|
||||
|
||||
if (!amroot && !lflg) {
|
||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age", NULL,
|
||||
getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
@@ -537,6 +537,15 @@ int main (int argc, char **argv)
|
||||
pwent = *pw;
|
||||
STRFCPY (name, pwent.pw_name);
|
||||
|
||||
if (!spw_file_present ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: the shadow password file is not present\n"),
|
||||
Prog);
|
||||
SYSLOG ((LOG_ERR, "can't find the shadow password file"));
|
||||
closelog ();
|
||||
exit (E_SHADOW_NOTFOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
* For shadow password files we have to lock the file and read in
|
||||
* the entries as was done for the password file. The user entries
|
||||
@@ -549,6 +558,10 @@ int main (int argc, char **argv)
|
||||
cleanup (1);
|
||||
SYSLOG ((LOG_ERR, "failed locking %s", SHADOW_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age", name,
|
||||
getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (!spw_open (locks ? O_RDWR : O_RDONLY)) {
|
||||
@@ -557,12 +570,20 @@ int main (int argc, char **argv)
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_ERR, "failed opening %s", SHADOW_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age", name,
|
||||
getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
if (lflg && (setgid (getgid ()) || setuid (ruid))) {
|
||||
fprintf (stderr, "%s: failed to drop privileges (%s)\n",
|
||||
fprintf (stderr, _("%s: failed to drop privileges (%s)\n"),
|
||||
Prog, strerror (errno));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age", name,
|
||||
getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
@@ -572,7 +593,6 @@ int main (int argc, char **argv)
|
||||
* Set the fields that aren't being set from the command line from
|
||||
* the password file.
|
||||
*/
|
||||
|
||||
if (sp) {
|
||||
spwd = *sp;
|
||||
|
||||
@@ -588,6 +608,49 @@ int main (int argc, char **argv)
|
||||
inactdays = spwd.sp_inact;
|
||||
if (!Eflg)
|
||||
expdays = spwd.sp_expire;
|
||||
#ifdef WITH_AUDIT
|
||||
if (Mflg)
|
||||
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change max age", pw->pw_name, pw->pw_uid,
|
||||
1);
|
||||
if (mflg)
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change min age", pw->pw_name, pw->pw_uid,
|
||||
1);
|
||||
if (dflg) {
|
||||
char new_lastchg[200];
|
||||
char old_lastchg[200];
|
||||
|
||||
date_to_str (new_lastchg, sizeof new_lastchg,
|
||||
lastday * DAY);
|
||||
date_to_str (old_lastchg, sizeof old_lastchg,
|
||||
spwd.sp_lstchg * DAY);
|
||||
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change last change date", pw->pw_name,
|
||||
pw->pw_uid, 1);
|
||||
}
|
||||
if (Wflg)
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change passwd warning", pw->pw_name,
|
||||
pw->pw_uid, 1);
|
||||
if (Iflg)
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change inactive days", pw->pw_name,
|
||||
pw->pw_uid, 1);
|
||||
if (Eflg) {
|
||||
char new_exp[200];
|
||||
char old_exp[200];
|
||||
|
||||
date_to_str (new_exp, sizeof new_exp, expdays * DAY);
|
||||
date_to_str (old_exp, sizeof old_exp,
|
||||
spwd.sp_expire * DAY);
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change passwd expiration", pw->pw_name,
|
||||
pw->pw_uid, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -597,10 +660,18 @@ int main (int argc, char **argv)
|
||||
|
||||
if (lflg) {
|
||||
if (!amroot && (ruid != pwent.pw_uid)) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, pw->pw_uid, 0);
|
||||
#endif
|
||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||
closelog ();
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "display aging info",
|
||||
pw->pw_name, pw->pw_uid, 1);
|
||||
#endif
|
||||
list_fields ();
|
||||
cleanup (2);
|
||||
closelog ();
|
||||
@@ -611,7 +682,6 @@ int main (int argc, char **argv)
|
||||
* If none of the fields were changed from the command line, let the
|
||||
* user interactively change them.
|
||||
*/
|
||||
|
||||
if (!mflg && !Mflg && !dflg && !Wflg && !Iflg && !Eflg) {
|
||||
printf (_("Changing the aging information for %s\n"), name);
|
||||
if (!new_fields ()) {
|
||||
@@ -619,15 +689,24 @@ int main (int argc, char **argv)
|
||||
Prog);
|
||||
cleanup (2);
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
else
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"change all aging information",
|
||||
pw->pw_name, getuid (), 1);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* There was no shadow entry. The new entry will have the encrypted
|
||||
* password transferred from the normal password file along with the
|
||||
* aging information.
|
||||
*/
|
||||
|
||||
if (sp == 0) {
|
||||
sp = &spwd;
|
||||
memzero (&spwd, sizeof spwd);
|
||||
@@ -643,6 +722,10 @@ int main (int argc, char **argv)
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_ERR, "failed updating %s", PASSWD_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
}
|
||||
@@ -652,7 +735,6 @@ int main (int argc, char **argv)
|
||||
* modified entry back to the shadow file. Closing the shadow and
|
||||
* password files will commit any changes that have been made.
|
||||
*/
|
||||
|
||||
spwd.sp_max = maxdays;
|
||||
spwd.sp_min = mindays;
|
||||
spwd.sp_lstchg = lastday;
|
||||
@@ -666,6 +748,10 @@ int main (int argc, char **argv)
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_ERR, "failed updating %s", SHADOW_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
@@ -679,73 +765,34 @@ int main (int argc, char **argv)
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_ERR, "failed rewriting %s", SHADOW_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
retval = PAM_SUCCESS;
|
||||
|
||||
pampw = getpwuid (getuid ());
|
||||
if (pampw == NULL) {
|
||||
retval = PAM_USER_UNKNOWN;
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_start ("chage", pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* Close the password file. If any entries were modified, the file
|
||||
* will be re-written.
|
||||
*/
|
||||
|
||||
if (!pw_close ()) {
|
||||
fprintf (stderr, _("%s: can't rewrite password file\n"), Prog);
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_ERR, "failed rewriting %s", PASSWD_FILE));
|
||||
closelog ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "change age",
|
||||
pw->pw_name, getuid (), 0);
|
||||
#endif
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
cleanup (2);
|
||||
SYSLOG ((LOG_INFO, "changed password expiry for %s", name));
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (!lflg) {
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
|
||||
#endif /* USE_PAM */
|
||||
|
||||
closelog ();
|
||||
|
102
src/chfn.c
102
src/chfn.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: chfn.c,v 1.31 2005/08/02 13:39:43 kloczek Exp $")
|
||||
#ident "$Id: chfn.c,v 1.37 2005/10/04 20:25:55 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
@@ -77,7 +77,6 @@ static char *copy_field (char *, char *, char *);
|
||||
/*
|
||||
* usage - print command line syntax and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
if (amroot)
|
||||
@@ -134,7 +133,6 @@ static int may_change_field (int field)
|
||||
* prompt the user for each of the four fields and fill in the fields from
|
||||
* the user's response, or leave alone if nothing was entered.
|
||||
*/
|
||||
|
||||
static void new_fields (void)
|
||||
{
|
||||
printf (_("Enter the new value, or press ENTER for the default\n"));
|
||||
@@ -173,7 +171,6 @@ static void new_fields (void)
|
||||
* out - where to copy the field to
|
||||
* extra - fields with '=' get copied here
|
||||
*/
|
||||
|
||||
static char *copy_field (char *in, char *out, char *extra)
|
||||
{
|
||||
char *cp = NULL;
|
||||
@@ -199,6 +196,12 @@ static char *copy_field (char *in, char *out, char *extra)
|
||||
return cp;
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
static struct pam_conv conv = {
|
||||
misc_conv,
|
||||
NULL
|
||||
};
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* chfn - change a user's password file information
|
||||
@@ -216,7 +219,6 @@ static char *copy_field (char *in, char *out, char *extra)
|
||||
*
|
||||
* (*) requires root permission to execute.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char *cp; /* temporary character pointer */
|
||||
@@ -232,6 +234,12 @@ int main (int argc, char **argv)
|
||||
int oflg = 0; /* -o - set other information */
|
||||
char *user;
|
||||
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
struct passwd *pampw;
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
sanitize_env ();
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
@@ -241,14 +249,12 @@ int main (int argc, char **argv)
|
||||
* This command behaves different for root and non-root
|
||||
* users.
|
||||
*/
|
||||
|
||||
amroot = (getuid () == 0);
|
||||
|
||||
/*
|
||||
* Get the program name. The program name is used as a
|
||||
* prefix to most error messages.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
OPENLOG ("chfn");
|
||||
@@ -260,7 +266,6 @@ int main (int argc, char **argv)
|
||||
* environment and must agree with the real UID. Also, the UID will
|
||||
* be checked for any commands which are restricted to root only.
|
||||
*/
|
||||
|
||||
while ((flag = getopt (argc, argv, "f:r:w:h:o:")) != EOF) {
|
||||
switch (flag) {
|
||||
case 'f':
|
||||
@@ -317,7 +322,6 @@ int main (int argc, char **argv)
|
||||
* Get the name of the user to check. It is either the command line
|
||||
* name, or the name getlogin() returns.
|
||||
*/
|
||||
|
||||
if (optind < argc) {
|
||||
user = argv[optind];
|
||||
pw = getpwnam (user);
|
||||
@@ -342,7 +346,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Now we make sure this is a LOCAL password entry for this user ...
|
||||
*/
|
||||
|
||||
if (__ispwNIS ()) {
|
||||
char *nis_domain;
|
||||
char *nis_master;
|
||||
@@ -358,7 +361,7 @@ int main (int argc, char **argv)
|
||||
("%s: `%s' is the NIS master for this client.\n"),
|
||||
Prog, nis_master);
|
||||
}
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -366,7 +369,6 @@ int main (int argc, char **argv)
|
||||
* Non-privileged users are only allowed to change the gecos field
|
||||
* if the UID of the user matches the current real UID.
|
||||
*/
|
||||
|
||||
if (!amroot && pw->pw_uid != getuid ()) {
|
||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||
closelog ();
|
||||
@@ -377,9 +379,8 @@ int main (int argc, char **argv)
|
||||
* If the UID of the user does not match the current real UID,
|
||||
* check if the change is allowed by SELinux policy.
|
||||
*/
|
||||
|
||||
if ((pw->pw_uid != getuid ())
|
||||
&& (checkPasswdAccess (PASSWD__CHFN) != 0)) {
|
||||
&& (selinux_check_passwd_access (PASSWD__CHFN) != 0)) {
|
||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||
closelog ();
|
||||
exit (E_NOPERM);
|
||||
@@ -393,17 +394,45 @@ int main (int argc, char **argv)
|
||||
* any changes can be made. Idea from util-linux chfn/chsh.
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
if (!amroot && getdef_bool ("CHFN_AUTH"))
|
||||
passwd_check (pw->pw_name, pw->pw_passwd, "chfn");
|
||||
|
||||
#endif /* !USE_PAM */
|
||||
#else /* !USE_PAM */
|
||||
retval = PAM_SUCCESS;
|
||||
|
||||
pampw = getpwuid (getuid ());
|
||||
if (pampw == NULL) {
|
||||
retval = PAM_USER_UNKNOWN;
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_start ("chfn", pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* Now get the full name. It is the first comma separated field in
|
||||
* the GECOS field.
|
||||
*/
|
||||
|
||||
STRFCPY (old_gecos, pw->pw_gecos);
|
||||
cp = copy_field (old_gecos, fflg ? (char *) 0 : fullnm, slop);
|
||||
|
||||
@@ -411,21 +440,18 @@ int main (int argc, char **argv)
|
||||
* Now get the room number. It is the next comma separated field,
|
||||
* if there is indeed one.
|
||||
*/
|
||||
|
||||
if (cp)
|
||||
cp = copy_field (cp, rflg ? (char *) 0 : roomno, slop);
|
||||
|
||||
/*
|
||||
* Now get the work phone number. It is the third field.
|
||||
*/
|
||||
|
||||
if (cp)
|
||||
cp = copy_field (cp, wflg ? (char *) 0 : workph, slop);
|
||||
|
||||
/*
|
||||
* Now get the home phone number. It is the fourth field.
|
||||
*/
|
||||
|
||||
if (cp)
|
||||
cp = copy_field (cp, hflg ? (char *) 0 : homeph, slop);
|
||||
|
||||
@@ -454,44 +480,43 @@ int main (int argc, char **argv)
|
||||
if (valid_field (fullnm, ":,=")) {
|
||||
fprintf (stderr, _("%s: invalid name: \"%s\"\n"), Prog, fullnm);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (valid_field (roomno, ":,=")) {
|
||||
fprintf (stderr, _("%s: invalid room number: \"%s\"\n"),
|
||||
Prog, roomno);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (valid_field (workph, ":,=")) {
|
||||
fprintf (stderr, _("%s: invalid work phone: \"%s\"\n"),
|
||||
Prog, workph);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (valid_field (homeph, ":,=")) {
|
||||
fprintf (stderr, _("%s: invalid home phone: \"%s\"\n"),
|
||||
Prog, homeph);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (valid_field (slop, ":")) {
|
||||
fprintf (stderr,
|
||||
_("%s: \"%s\" contains illegal characters\n"),
|
||||
Prog, slop);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the new GECOS field by plastering all the pieces together,
|
||||
* if they will fit ...
|
||||
*/
|
||||
|
||||
if (strlen (fullnm) + strlen (roomno) + strlen (workph) +
|
||||
strlen (homeph) + strlen (slop) > (unsigned int) 80) {
|
||||
fprintf (stderr, _("%s: fields too long\n"), Prog);
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
snprintf (new_gecos, sizeof new_gecos, "%s,%s,%s,%s%s%s",
|
||||
fullnm, roomno, workph, homeph, slop[0] ? "," : "", slop);
|
||||
@@ -502,12 +527,11 @@ int main (int argc, char **argv)
|
||||
* against unexpected signals. Any keyboard signals are set to be
|
||||
* ignored.
|
||||
*/
|
||||
|
||||
if (setuid (0)) {
|
||||
fprintf (stderr, _("Cannot change ID to root.\n"));
|
||||
SYSLOG ((LOG_ERR, "can't setuid(0)"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
pwd_init ();
|
||||
|
||||
@@ -515,21 +539,20 @@ int main (int argc, char **argv)
|
||||
* The passwd entry is now ready to be committed back to the
|
||||
* password file. Get a lock on the file and open it.
|
||||
*/
|
||||
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
("Cannot lock the password file; try again later.\n"));
|
||||
SYSLOG ((LOG_WARN, "can't lock /etc/passwd"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (!pw_open (O_RDWR)) {
|
||||
fprintf (stderr, _("Cannot open the password file.\n"));
|
||||
pw_unlock ();
|
||||
SYSLOG ((LOG_ERR, "can't open /etc/passwd"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -543,7 +566,7 @@ int main (int argc, char **argv)
|
||||
pw_unlock ();
|
||||
fprintf (stderr,
|
||||
_("%s: %s not found in /etc/passwd\n"), Prog, user);
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -562,7 +585,7 @@ int main (int argc, char **argv)
|
||||
pw_unlock ();
|
||||
SYSLOG ((LOG_ERR, "error updating passwd entry"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -573,18 +596,23 @@ int main (int argc, char **argv)
|
||||
pw_unlock ();
|
||||
SYSLOG ((LOG_ERR, "can't rewrite /etc/passwd"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
if (!pw_unlock ()) {
|
||||
fprintf (stderr, _("Cannot unlock the password file.\n"));
|
||||
SYSLOG ((LOG_ERR, "can't unlock /etc/passwd"));
|
||||
closelog ();
|
||||
exit (1);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
SYSLOG ((LOG_INFO, "changed user `%s' information", user));
|
||||
|
||||
nscd_flush_cache ("passwd");
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
||||
closelog ();
|
||||
exit (E_SUCCESS);
|
||||
}
|
||||
|
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: chpasswd.c,v 1.29 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#ident "$Id: chpasswd.c,v 1.33 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
@@ -40,10 +40,10 @@ RCSID (PKG_VER "$Id: chpasswd.c,v 1.29 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#endif /* USE_PAM */
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "pwio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
/*
|
||||
* Global variables
|
||||
@@ -60,7 +60,6 @@ static void usage (void);
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: chpasswd [options]\n"
|
||||
@@ -178,7 +177,6 @@ int main (int argc, char **argv)
|
||||
* Lock the password file and open it for reading. This will bring
|
||||
* all of the entries into memory where they may be updated.
|
||||
*/
|
||||
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr, _("%s: can't lock password file\n"), Prog);
|
||||
exit (1);
|
||||
@@ -214,7 +212,6 @@ int main (int argc, char **argv)
|
||||
* last change date is set in the age only if aging information is
|
||||
* present.
|
||||
*/
|
||||
|
||||
while (fgets (buf, sizeof buf, stdin) != (char *) 0) {
|
||||
line++;
|
||||
if ((cp = strrchr (buf, '\n'))) {
|
||||
@@ -260,7 +257,6 @@ int main (int argc, char **argv)
|
||||
* Get the password file entry for this user. The user must
|
||||
* already exist.
|
||||
*/
|
||||
|
||||
pw = pw_locate (name);
|
||||
if (!pw) {
|
||||
fprintf (stderr,
|
||||
@@ -279,7 +275,6 @@ int main (int argc, char **argv)
|
||||
* user's password file entry and the last password change
|
||||
* date is set to the current date.
|
||||
*/
|
||||
|
||||
if (sp) {
|
||||
newsp = *sp;
|
||||
newsp.sp_pwdp = cp;
|
||||
@@ -294,7 +289,6 @@ int main (int argc, char **argv)
|
||||
* be written to the password file later, after all the
|
||||
* other entries have been updated as well.
|
||||
*/
|
||||
|
||||
if (sp)
|
||||
ok = spw_update (&newsp);
|
||||
else
|
||||
@@ -317,7 +311,6 @@ int main (int argc, char **argv)
|
||||
* changes to be written out all at once, and then unlocked
|
||||
* afterwards.
|
||||
*/
|
||||
|
||||
if (errors) {
|
||||
fprintf (stderr,
|
||||
_("%s: error detected, changes ignored\n"), Prog);
|
||||
@@ -345,18 +338,6 @@ int main (int argc, char **argv)
|
||||
pw_unlock ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
79
src/chsh.c
79
src/chsh.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: chsh.c,v 1.30 2005/07/24 15:22:45 kloczek Exp $")
|
||||
#ident "$Id: chsh.c,v 1.35 2005/10/04 21:02:22 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
@@ -56,7 +56,9 @@ RCSID (PKG_VER "$Id: chsh.c,v 1.30 2005/07/24 15:22:45 kloczek Exp $")
|
||||
#ifndef SHELLS_FILE
|
||||
#define SHELLS_FILE "/etc/shells"
|
||||
#endif
|
||||
/* global variables */
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *Prog; /* Program name */
|
||||
static int amroot; /* Real UID is root */
|
||||
static char loginsh[BUFSIZ]; /* Name of new login shell */
|
||||
@@ -71,7 +73,6 @@ static int restricted_shell (const char *);
|
||||
/*
|
||||
* usage - print command line syntax and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-s shell] [name]\n"), Prog);
|
||||
@@ -84,7 +85,6 @@ static void usage (void)
|
||||
* prompt the user for the login shell and change it according to the
|
||||
* response, or leave it alone if nothing was entered.
|
||||
*/
|
||||
|
||||
static void new_fields (void)
|
||||
{
|
||||
printf (_("Enter the new value, or press ENTER for the default\n"));
|
||||
@@ -97,7 +97,6 @@ static void new_fields (void)
|
||||
* If the first letter of the filename is 'r' or 'R', the shell is
|
||||
* considered to be restricted.
|
||||
*/
|
||||
|
||||
static int restricted_shell (const char *sh)
|
||||
{
|
||||
/*
|
||||
@@ -108,6 +107,12 @@ static int restricted_shell (const char *sh)
|
||||
return !check_shell (sh);
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
static struct pam_conv conv = {
|
||||
misc_conv,
|
||||
NULL
|
||||
};
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* chsh - this command controls changes to the user's shell
|
||||
@@ -115,7 +120,6 @@ static int restricted_shell (const char *sh)
|
||||
* The only supported option is -s which permits the the login shell to
|
||||
* be set from the command line.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char *user; /* User name */
|
||||
@@ -124,6 +128,12 @@ int main (int argc, char **argv)
|
||||
const struct passwd *pw; /* Password entry from /etc/passwd */
|
||||
struct passwd pwent; /* New password entry */
|
||||
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
struct passwd *pampw;
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
sanitize_env ();
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -133,14 +143,12 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* This command behaves different for root and non-root users.
|
||||
*/
|
||||
|
||||
amroot = getuid () == 0;
|
||||
|
||||
/*
|
||||
* Get the program name. The program name is used as a prefix to
|
||||
* most error messages.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
OPENLOG ("chsh");
|
||||
@@ -165,7 +173,6 @@ int main (int argc, char **argv)
|
||||
* There should be only one remaining argument at most and it should
|
||||
* be the user's name.
|
||||
*/
|
||||
|
||||
if (argc > optind + 1)
|
||||
usage ();
|
||||
|
||||
@@ -173,7 +180,6 @@ int main (int argc, char **argv)
|
||||
* Get the name of the user to check. It is either the command line
|
||||
* name, or the name getlogin() returns.
|
||||
*/
|
||||
|
||||
if (optind < argc) {
|
||||
user = argv[optind];
|
||||
pw = getpwnam (user);
|
||||
@@ -198,7 +204,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Now we make sure this is a LOCAL password entry for this user ...
|
||||
*/
|
||||
|
||||
if (__ispwNIS ()) {
|
||||
char *nis_domain;
|
||||
char *nis_master;
|
||||
@@ -222,7 +227,6 @@ int main (int argc, char **argv)
|
||||
* Non-privileged users are only allowed to change the shell if the
|
||||
* UID of the user matches the current real UID.
|
||||
*/
|
||||
|
||||
if (!amroot && pw->pw_uid != getuid ()) {
|
||||
SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
|
||||
closelog ();
|
||||
@@ -235,7 +239,6 @@ int main (int argc, char **argv)
|
||||
* Non-privileged users are only allowed to change the shell if it
|
||||
* is not a restricted one.
|
||||
*/
|
||||
|
||||
if (!amroot && restricted_shell (pw->pw_shell)) {
|
||||
SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
|
||||
closelog ();
|
||||
@@ -248,9 +251,8 @@ int main (int argc, char **argv)
|
||||
* If the UID of the user does not match the current real UID,
|
||||
* check if the change is allowed by SELinux policy.
|
||||
*/
|
||||
|
||||
if ((pw->pw_uid != getuid ())
|
||||
&& (checkPasswdAccess (PASSWD__CHSH) != 0)) {
|
||||
&& (selinux_check_passwd_access (PASSWD__CHSH) != 0)) {
|
||||
SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
|
||||
closelog ();
|
||||
fprintf (stderr,
|
||||
@@ -266,17 +268,45 @@ int main (int argc, char **argv)
|
||||
* before any changes can be made. Idea from util-linux
|
||||
* chfn/chsh. --marekm
|
||||
*/
|
||||
|
||||
if (!amroot && getdef_bool ("CHSH_AUTH"))
|
||||
passwd_check (pw->pw_name, pw->pw_passwd, "chsh");
|
||||
|
||||
#endif /* !USE_PAM */
|
||||
#else /* !USE_PAM */
|
||||
retval = PAM_SUCCESS;
|
||||
|
||||
pampw = getpwuid (getuid ());
|
||||
if (pampw == NULL) {
|
||||
retval = PAM_USER_UNKNOWN;
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_start ("chsh", pampw->pw_name, &conv, &pamh);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_acct_mgmt (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* Now get the login shell. Either get it from the password
|
||||
* file, or use the value from the command line.
|
||||
*/
|
||||
|
||||
if (!sflg)
|
||||
STRFCPY (loginsh, pw->pw_shell);
|
||||
|
||||
@@ -284,7 +314,6 @@ int main (int argc, char **argv)
|
||||
* If the login shell was not set on the command line, let the user
|
||||
* interactively change it.
|
||||
*/
|
||||
|
||||
if (!sflg) {
|
||||
printf (_("Changing the login shell for %s\n"), user);
|
||||
new_fields ();
|
||||
@@ -296,7 +325,6 @@ int main (int argc, char **argv)
|
||||
* users are restricted to using the shells in /etc/shells.
|
||||
* The shell must be executable by the user.
|
||||
*/
|
||||
|
||||
if (valid_field (loginsh, ":,=")) {
|
||||
fprintf (stderr, _("%s: Invalid entry: %s\n"), Prog, loginsh);
|
||||
closelog ();
|
||||
@@ -314,7 +342,6 @@ int main (int argc, char **argv)
|
||||
* to root to protect against unexpected signals. Any
|
||||
* keyboard signals are set to be ignored.
|
||||
*/
|
||||
|
||||
if (setuid (0)) {
|
||||
SYSLOG ((LOG_ERR, "can't setuid(0)"));
|
||||
closelog ();
|
||||
@@ -327,7 +354,6 @@ int main (int argc, char **argv)
|
||||
* The passwd entry is now ready to be committed back to
|
||||
* the password file. Get a lock on the file and open it.
|
||||
*/
|
||||
|
||||
if (!pw_lock ()) {
|
||||
SYSLOG ((LOG_WARN, "can't lock /etc/passwd"));
|
||||
closelog ();
|
||||
@@ -369,7 +395,6 @@ int main (int argc, char **argv)
|
||||
* Update the passwd file entry. If there is a DBM file, update
|
||||
* that entry as well.
|
||||
*/
|
||||
|
||||
if (!pw_update (&pwent)) {
|
||||
SYSLOG ((LOG_ERR, "error updating passwd entry"));
|
||||
closelog ();
|
||||
@@ -381,7 +406,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Changes have all been made, so commit them and unlock the file.
|
||||
*/
|
||||
|
||||
if (!pw_close ()) {
|
||||
SYSLOG ((LOG_ERR, "can't rewrite /etc/passwd"));
|
||||
closelog ();
|
||||
@@ -399,6 +423,11 @@ int main (int argc, char **argv)
|
||||
|
||||
nscd_flush_cache ("passwd");
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
||||
closelog ();
|
||||
exit (E_SUCCESS);
|
||||
}
|
||||
|
@@ -29,13 +29,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID ("$Id: chsh_chkshell.c,v 1.1 2005/07/07 08:40:27 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#ident "$Id: chsh_chkshell.c,v 1.3 2005/08/31 17:25:00 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "prototypes.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#ifndef SHELLS_FILE
|
||||
#define SHELLS_FILE "/etc/shells"
|
||||
#endif
|
||||
|
35
src/expiry.c
35
src/expiry.c
@@ -29,14 +29,14 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: expiry.c,v 1.14 2005/05/25 18:20:25 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#ident "$Id: expiry.c,v 1.18 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "prototypes.h"
|
||||
/* local function prototypes */
|
||||
static RETSIGTYPE catch (int);
|
||||
static void usage (void);
|
||||
@@ -44,7 +44,6 @@ static void usage (void);
|
||||
/*
|
||||
* catch - signal catcher
|
||||
*/
|
||||
|
||||
static RETSIGTYPE catch (int sig)
|
||||
{
|
||||
exit (10);
|
||||
@@ -53,7 +52,6 @@ static RETSIGTYPE catch (int sig)
|
||||
/*
|
||||
* usage - print syntax message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: expiry {-f|-c}\n"));
|
||||
@@ -66,7 +64,6 @@ static void usage (void)
|
||||
* expiry checks (-c) the current password expiraction and forces (-f)
|
||||
* changes when required. It is callable as a normal user command.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
@@ -79,7 +76,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Start by disabling all of the keyboard signals.
|
||||
*/
|
||||
|
||||
signal (SIGHUP, catch);
|
||||
signal (SIGINT, catch);
|
||||
signal (SIGQUIT, catch);
|
||||
@@ -91,7 +87,6 @@ int main (int argc, char **argv)
|
||||
* expiry takes one of two arguments. The default action is to give
|
||||
* the usage message.
|
||||
*/
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
@@ -99,23 +94,9 @@ int main (int argc, char **argv)
|
||||
if (argc != 2 || (strcmp (argv[1], "-f") && strcmp (argv[1], "-c")))
|
||||
usage ();
|
||||
|
||||
#if 0 /* could be setgid shadow with /etc/shadow mode 0640 */
|
||||
/*
|
||||
* Make sure I am root. Can't open /etc/shadow without root
|
||||
* authority.
|
||||
*/
|
||||
|
||||
if (geteuid () != 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: WARNING! Must be set-UID root!\n"), argv[0]);
|
||||
exit (10);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get user entries for /etc/passwd and /etc/shadow
|
||||
*/
|
||||
|
||||
if (!(pwd = get_my_pwent ())) {
|
||||
fprintf (stderr, _("%s: unknown user\n"), Prog);
|
||||
exit (10);
|
||||
@@ -125,26 +106,22 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* If checking accounts, use agecheck() function.
|
||||
*/
|
||||
|
||||
if (strcmp (argv[1], "-c") == 0) {
|
||||
|
||||
/*
|
||||
* Print out number of days until expiration.
|
||||
*/
|
||||
|
||||
agecheck (pwd, spwd);
|
||||
|
||||
/*
|
||||
* Exit with status indicating state of account.
|
||||
*/
|
||||
|
||||
exit (isexpired (pwd, spwd));
|
||||
}
|
||||
|
||||
/*
|
||||
* If forcing password change, use expire() function.
|
||||
*/
|
||||
|
||||
if (strcmp (argv[1], "-f") == 0) {
|
||||
|
||||
/*
|
||||
@@ -152,7 +129,6 @@ int main (int argc, char **argv)
|
||||
* message indicating what to do. And it doesn't return at
|
||||
* all unless the account is unexpired.
|
||||
*/
|
||||
|
||||
expire (pwd, spwd);
|
||||
exit (0);
|
||||
}
|
||||
@@ -160,7 +136,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Can't get here ...
|
||||
*/
|
||||
|
||||
usage ();
|
||||
exit (1);
|
||||
}
|
||||
|
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: faillog.c,v 1.24 2005/08/03 17:40:59 kloczek Exp $")
|
||||
#ident "$Id: faillog.c,v 1.26 2005/08/31 17:25:00 kloczek Exp $"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
@@ -41,7 +41,9 @@ RCSID (PKG_VER "$Id: faillog.c,v 1.24 2005/08/03 17:40:59 kloczek Exp $")
|
||||
#include "exitcodes.h"
|
||||
#include "faillog.h"
|
||||
#include "prototypes.h"
|
||||
/* global variables */
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static FILE *fail; /* failure file stream */
|
||||
static uid_t user; /* one single user, specified on command line */
|
||||
static int days; /* number of days to consider for print command */
|
||||
|
180
src/gpasswd.c
180
src/gpasswd.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: gpasswd.c,v 1.28 2005/08/09 15:27:51 kloczek Exp $")
|
||||
#ident "$Id: gpasswd.c,v 1.34 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
@@ -45,7 +45,9 @@ RCSID (PKG_VER "$Id: gpasswd.c,v 1.28 2005/08/09 15:27:51 kloczek Exp $")
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
/* global variables */
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *Prog;
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
@@ -55,6 +57,8 @@ static int is_shadowgrp;
|
||||
static int
|
||||
aflg = 0, Aflg = 0, dflg = 0, Mflg = 0, rflg = 0, Rflg = 0;
|
||||
|
||||
unsigned int bywho = -1;
|
||||
|
||||
#ifndef RETRIES
|
||||
#define RETRIES 3
|
||||
#endif
|
||||
@@ -67,7 +71,6 @@ static int check_list (const char *);
|
||||
/*
|
||||
* usage - display usage message
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-r|-R] group\n"), Prog);
|
||||
@@ -89,7 +92,6 @@ static void usage (void)
|
||||
* with die() as the signal handler. If signal later calls die() with a
|
||||
* signal number, the terminal modes are then reset.
|
||||
*/
|
||||
|
||||
static RETSIGTYPE die (int killed)
|
||||
{
|
||||
static TERMIO sgtty;
|
||||
@@ -112,7 +114,6 @@ static RETSIGTYPE die (int killed)
|
||||
* check_list scans a comma-separated list of user names and checks
|
||||
* that each listed name exists.
|
||||
*/
|
||||
|
||||
static int check_list (const char *users)
|
||||
{
|
||||
const char *start, *end;
|
||||
@@ -146,13 +147,11 @@ static int check_list (const char *users)
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
static void failure (void)
|
||||
{
|
||||
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
|
||||
exit (1);
|
||||
/*NOTREACHED*/}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* gpasswd - administer the /etc/group file
|
||||
@@ -164,7 +163,6 @@ static void failure (void)
|
||||
* -A user,... make list of users the administrative users
|
||||
* -M user,... make list of users the group members
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int flag;
|
||||
@@ -186,6 +184,10 @@ int main (int argc, char **argv)
|
||||
char *group = NULL;
|
||||
char *members = NULL;
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
sanitize_env ();
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
@@ -198,8 +200,8 @@ int main (int argc, char **argv)
|
||||
* prevent the invoker from issuing signals which would interfer
|
||||
* with this command.
|
||||
*/
|
||||
|
||||
amroot = getuid () == 0;
|
||||
bywho = getuid ();
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
OPENLOG ("gpasswd");
|
||||
@@ -217,14 +219,24 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_("%s: unknown user %s\n"), Prog,
|
||||
user);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding to group", user, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
aflg++;
|
||||
break;
|
||||
#ifdef SHADOWGRP
|
||||
case 'A':
|
||||
if (!amroot)
|
||||
if (!amroot) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"Listing administrators", NULL,
|
||||
bywho, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
if (!is_shadowgrp) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
@@ -245,8 +257,14 @@ int main (int argc, char **argv)
|
||||
case 'g': /* no-op from normal password */
|
||||
break;
|
||||
case 'M':
|
||||
if (!amroot)
|
||||
if (!amroot) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"listing members", NULL, bywho,
|
||||
0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
members = optarg;
|
||||
if (check_list (members))
|
||||
exit (1);
|
||||
@@ -280,7 +298,11 @@ int main (int argc, char **argv)
|
||||
pw = get_my_pwent ();
|
||||
if (!pw) {
|
||||
fprintf (stderr, _("Who are you?\n"));
|
||||
exit (1);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "user lookup", NULL,
|
||||
bywho, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
myname = xstrdup (pw->pw_name);
|
||||
|
||||
@@ -293,13 +315,16 @@ int main (int argc, char **argv)
|
||||
* XXX - should get the entry using gr_locate() and modify that,
|
||||
* getgrnam() could give us a NIS group. --marekm
|
||||
*/
|
||||
|
||||
if (!(group = argv[optind]))
|
||||
usage ();
|
||||
|
||||
if (!(gr = getgrnam (group))) {
|
||||
fprintf (stderr, _("unknown group: %s\n"), group);
|
||||
exit (1);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "group lookup", group,
|
||||
-1, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
grent = *gr;
|
||||
grent.gr_name = xstrdup (gr->gr_name);
|
||||
@@ -339,9 +364,13 @@ int main (int argc, char **argv)
|
||||
* Administrative members can do anything to a group that the root
|
||||
* user can.
|
||||
*/
|
||||
|
||||
if (!amroot && !is_on_list (sgent.sg_adm, myname))
|
||||
if (!amroot && !is_on_list (sgent.sg_adm, myname)) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modify group", group,
|
||||
-1, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
#else /* ! SHADOWGRP */
|
||||
|
||||
#ifdef FIRST_MEMBER_IS_ADMIN
|
||||
@@ -352,13 +381,22 @@ int main (int argc, char **argv)
|
||||
* the root user can. The rationale for this hack is that the FIRST
|
||||
* user is probably the most important user in this entire group.
|
||||
*/
|
||||
|
||||
if (!amroot) {
|
||||
if (grent.gr_mem[0] == (char *) 0)
|
||||
if (grent.gr_mem[0] == (char *) 0) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"modifying group", group, -1, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
|
||||
if (strcmp (grent.gr_mem[0], myname) != 0)
|
||||
if (strcmp (grent.gr_mem[0], myname) != 0) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"modifying group", myname, -1, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
}
|
||||
#else
|
||||
/*
|
||||
@@ -366,9 +404,13 @@ int main (int argc, char **argv)
|
||||
* installed on existing systems where the first group member might
|
||||
* be just a normal user. --marekm
|
||||
*/
|
||||
|
||||
if (!amroot)
|
||||
if (!amroot) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying group",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
failure ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SHADOWGRP */
|
||||
@@ -377,11 +419,14 @@ int main (int argc, char **argv)
|
||||
* Removing a password is straight forward. Just set the password
|
||||
* field to a "".
|
||||
*/
|
||||
|
||||
if (rflg) {
|
||||
grent.gr_passwd = ""; /* XXX warning: const */
|
||||
#ifdef SHADOWGRP
|
||||
sgent.sg_passwd = ""; /* XXX warning: const */
|
||||
#endif
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting group password", group, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "remove password from group %s by %s",
|
||||
group, myname));
|
||||
@@ -391,10 +436,13 @@ int main (int argc, char **argv)
|
||||
* Same thing for restricting the group. Set the password
|
||||
* field to "!".
|
||||
*/
|
||||
|
||||
grent.gr_passwd = "!"; /* XXX warning: const */
|
||||
#ifdef SHADOWGRP
|
||||
sgent.sg_passwd = "!"; /* XXX warning: const */
|
||||
#endif
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"restrict access to group", group, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "restrict access to group %s by %s",
|
||||
group, myname));
|
||||
@@ -405,12 +453,15 @@ int main (int argc, char **argv)
|
||||
* Adding a member to a member list is pretty straightforward as
|
||||
* well. Call the appropriate routine and split.
|
||||
*/
|
||||
|
||||
if (aflg) {
|
||||
printf (_("Adding user %s to group %s\n"), user, group);
|
||||
grent.gr_mem = add_list (grent.gr_mem, user);
|
||||
#ifdef SHADOWGRP
|
||||
sgent.sg_mem = add_list (sgent.sg_mem, user);
|
||||
#endif
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group member",
|
||||
user, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "add member %s to group %s by %s", user,
|
||||
group, myname));
|
||||
@@ -421,7 +472,6 @@ int main (int argc, char **argv)
|
||||
* Removing a member from the member list is the same deal as adding
|
||||
* one, except the routine is different.
|
||||
*/
|
||||
|
||||
if (dflg) {
|
||||
int removed = 0;
|
||||
|
||||
@@ -440,8 +490,16 @@ int main (int argc, char **argv)
|
||||
if (!removed) {
|
||||
fprintf (stderr, _("%s: unknown member %s\n"),
|
||||
Prog, user);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting member", user, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting member",
|
||||
user, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "remove member %s from group %s by %s",
|
||||
user, group, myname));
|
||||
goto output;
|
||||
@@ -452,8 +510,11 @@ int main (int argc, char **argv)
|
||||
* list to make sure everyone is a real user. Then slap the new list
|
||||
* in place.
|
||||
*/
|
||||
|
||||
if (Aflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "setting group admin",
|
||||
group, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "set administrators of %s to %s",
|
||||
group, admins));
|
||||
sgent.sg_adm = comma_to_list (admins);
|
||||
@@ -467,8 +528,11 @@ int main (int argc, char **argv)
|
||||
* make sure everyone is a real user. Then slap the new list in
|
||||
* place.
|
||||
*/
|
||||
|
||||
if (Mflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"setting group members", group, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "set members of %s to %s", group, members));
|
||||
#ifdef SHADOWGRP
|
||||
sgent.sg_mem = comma_to_list (members);
|
||||
@@ -482,9 +546,12 @@ int main (int argc, char **argv)
|
||||
* be a tty. The typical keyboard signals are caught so the termio
|
||||
* modes can be restored.
|
||||
*/
|
||||
|
||||
if (!isatty (0) || !isatty (1)) {
|
||||
fprintf (stderr, _("%s: Not a tty\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@@ -504,7 +571,6 @@ int main (int argc, char **argv)
|
||||
* identical. There is no need to validate the old password since
|
||||
* the invoker is either the group owner, or root.
|
||||
*/
|
||||
|
||||
printf (_("Changing the password for group %s\n"), group);
|
||||
|
||||
for (retries = 0; retries < RETRIES; retries++) {
|
||||
@@ -524,8 +590,13 @@ int main (int argc, char **argv)
|
||||
strzero (cp);
|
||||
memzero (pass, sizeof pass);
|
||||
|
||||
if (retries + 1 < RETRIES)
|
||||
if (retries + 1 < RETRIES) {
|
||||
puts (_("They don't match; try again"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing password", group, -1, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (retries == RETRIES) {
|
||||
@@ -541,6 +612,10 @@ int main (int argc, char **argv)
|
||||
else
|
||||
#endif
|
||||
grent.gr_passwd = cp;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password", group,
|
||||
-1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "change the password for group %s by %s", group,
|
||||
myname));
|
||||
|
||||
@@ -550,11 +625,14 @@ int main (int argc, char **argv)
|
||||
* will be locked and opened for writing. The new entry will be
|
||||
* output, etc.
|
||||
*/
|
||||
|
||||
output:
|
||||
if (setuid (0)) {
|
||||
fprintf (stderr, _("Cannot change ID to root.\n"));
|
||||
SYSLOG ((LOG_ERR, "can't setuid(0)"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing id to root",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
closelog ();
|
||||
exit (1);
|
||||
}
|
||||
@@ -563,48 +641,80 @@ int main (int argc, char **argv)
|
||||
if (!gr_lock ()) {
|
||||
fprintf (stderr, _("%s: can't get lock\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "failed to get lock for /etc/group"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "locking /etc/group",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp && !sgr_lock ()) {
|
||||
fprintf (stderr, _("%s: can't get shadow lock\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "failed to get lock for /etc/gshadow"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking /etc/gshadow", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
if (!gr_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: can't open file\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot open /etc/group"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "opening /etc/group",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp && !sgr_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: can't open shadow file\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot open /etc/gshadow"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening /etc/gshadow", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
if (!gr_update (&grent)) {
|
||||
fprintf (stderr, _("%s: can't update entry\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot update /etc/group"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "updating /etc/group",
|
||||
group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp && !sgr_update (&sgent)) {
|
||||
fprintf (stderr, _("%s: can't update shadow entry\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot update /etc/gshadow"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"updating /etc/gshadow", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#endif
|
||||
if (!gr_close ()) {
|
||||
fprintf (stderr, _("%s: can't re-write file\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot re-write /etc/group"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"rewriting /etc/group", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadowgrp && !sgr_close ()) {
|
||||
fprintf (stderr, _("%s: can't re-write shadow file\n"), Prog);
|
||||
SYSLOG ((LOG_WARN, "cannot re-write /etc/gshadow"));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"rewriting /etc/gshadow", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
if (is_shadowgrp)
|
||||
@@ -612,6 +722,10 @@ int main (int argc, char **argv)
|
||||
#endif
|
||||
if (!gr_unlock ()) {
|
||||
fprintf (stderr, _("%s: can't unlock file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"unlocking group file", group, -1, 0);
|
||||
#endif
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
@@ -29,25 +29,25 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: groupadd.c,v 1.41 2005/08/11 13:45:41 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <grp.h>
|
||||
#ident "$Id: groupadd.c,v 1.48 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#include <pwd.h>
|
||||
#endif /* USE_PAM */
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
static int is_shadow_grp;
|
||||
@@ -56,7 +56,6 @@ static int is_shadow_grp;
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
|
||||
#define E_SUCCESS 0 /* success */
|
||||
#define E_USAGE 2 /* invalid command syntax */
|
||||
#define E_BAD_ARG 3 /* invalid argument to option */
|
||||
@@ -64,6 +63,9 @@ static int is_shadow_grp;
|
||||
#define E_NAME_IN_USE 9 /* group name not unique */
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *group_name;
|
||||
static gid_t group_id;
|
||||
static char *empty_list = NULL;
|
||||
@@ -92,7 +94,6 @@ static void fail_exit (int);
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: groupadd [options] group\n"
|
||||
@@ -114,7 +115,6 @@ static void usage (void)
|
||||
* new_grent() takes all of the values that have been entered and fills
|
||||
* in a (struct group) with them.
|
||||
*/
|
||||
|
||||
static void new_grent (struct group *grent)
|
||||
{
|
||||
memzero (grent, sizeof *grent);
|
||||
@@ -131,7 +131,6 @@ static void new_grent (struct group *grent)
|
||||
* new_sgent() takes all of the values that have been entered and fills
|
||||
* in a (struct sgrp) with them.
|
||||
*/
|
||||
|
||||
static void new_sgent (struct sgrp *sgent)
|
||||
{
|
||||
memzero (sgent, sizeof *sgent);
|
||||
@@ -147,7 +146,6 @@ static void new_sgent (struct sgrp *sgent)
|
||||
*
|
||||
* grp_update() writes the new records to the group files.
|
||||
*/
|
||||
|
||||
static void grp_update (void)
|
||||
{
|
||||
struct group grp;
|
||||
@@ -180,6 +178,10 @@ static void grp_update (void)
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#endif /* SHADOWGRP */
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group", group_name,
|
||||
group_id, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u",
|
||||
group_name, (unsigned int) group_id));
|
||||
}
|
||||
@@ -191,13 +193,12 @@ static void grp_update (void)
|
||||
* file, or checks the given group ID against the existing ones for
|
||||
* uniqueness.
|
||||
*/
|
||||
|
||||
static void find_new_gid (void)
|
||||
{
|
||||
const struct group *grp;
|
||||
gid_t gid_min, gid_max;
|
||||
|
||||
gid_min = getdef_unum ("GID_MIN", 100);
|
||||
gid_min = getdef_unum ("GID_MIN", 1000);
|
||||
gid_max = getdef_unum ("GID_MAX", 60000);
|
||||
|
||||
/*
|
||||
@@ -213,7 +214,6 @@ static void find_new_gid (void)
|
||||
* user specified one with -g) or looking for the largest unused
|
||||
* value.
|
||||
*/
|
||||
|
||||
#ifdef NO_GETGRENT
|
||||
gr_rewind ();
|
||||
while ((grp = gr_next ())) {
|
||||
@@ -276,7 +276,6 @@ static void find_new_gid (void)
|
||||
* check_new_name() insures that the new name doesn't contain any
|
||||
* illegal characters.
|
||||
*/
|
||||
|
||||
static void check_new_name (void)
|
||||
{
|
||||
if (check_group_name (group_name))
|
||||
@@ -298,7 +297,6 @@ static void check_new_name (void)
|
||||
* close_files() closes all of the files that were opened for this new
|
||||
* group. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!gr_close ()) {
|
||||
@@ -322,15 +320,22 @@ static void close_files (void)
|
||||
*
|
||||
* open_files() opens the two group files.
|
||||
*/
|
||||
|
||||
static void open_files (void)
|
||||
{
|
||||
if (!gr_lock ()) {
|
||||
fprintf (stderr, _("%s: unable to lock group file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "locking group file",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
if (!gr_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: unable to open group file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "opening group file",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
@@ -350,13 +355,17 @@ static void open_files (void)
|
||||
/*
|
||||
* fail_exit - exit with an error code after unlocking files
|
||||
*/
|
||||
|
||||
static void fail_exit (int code)
|
||||
{
|
||||
(void) gr_unlock ();
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp)
|
||||
sgr_unlock ();
|
||||
#endif
|
||||
if (code != E_SUCCESS)
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (code);
|
||||
}
|
||||
@@ -380,10 +389,12 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -514,12 +525,15 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Start with a quick check to see if the group exists.
|
||||
*/
|
||||
|
||||
if (getgrnam (group_name)) {
|
||||
if (fflg) {
|
||||
exit (E_SUCCESS);
|
||||
}
|
||||
fprintf (stderr, _("%s: group %s exists\n"), Prog, group_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NAME_IN_USE);
|
||||
}
|
||||
|
||||
@@ -538,18 +552,6 @@ int main (int argc, char **argv)
|
||||
close_files ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
@@ -29,37 +29,40 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: groupdel.c,v 1.23 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#ident "$Id: groupdel.c,v 1.29 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#endif /* USE_PAM */
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *group_name;
|
||||
static char *Prog;
|
||||
static int errors;
|
||||
|
||||
#include "groupio.h"
|
||||
static gid_t group_id = -1;
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
|
||||
static int is_shadow_grp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
|
||||
#define E_SUCCESS 0 /* success */
|
||||
#define E_USAGE 2 /* invalid command syntax */
|
||||
#define E_NOTFOUND 6 /* specified group doesn't exist */
|
||||
@@ -76,7 +79,6 @@ static void group_busy (gid_t);
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: groupdel group\n"));
|
||||
@@ -88,7 +90,6 @@ static void usage (void)
|
||||
*
|
||||
* grp_update() writes the new records to the group files.
|
||||
*/
|
||||
|
||||
static void grp_update (void)
|
||||
{
|
||||
if (!gr_remove (group_name)) {
|
||||
@@ -105,6 +106,10 @@ static void grp_update (void)
|
||||
errors++;
|
||||
}
|
||||
#endif /* SHADOWGRP */
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group", group_name,
|
||||
group_id, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "remove group `%s'\n", group_name));
|
||||
return;
|
||||
}
|
||||
@@ -115,7 +120,6 @@ static void grp_update (void)
|
||||
* close_files() closes all of the files that were opened for this
|
||||
* new group. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!gr_close ()) {
|
||||
@@ -139,7 +143,6 @@ static void close_files (void)
|
||||
*
|
||||
* open_files() opens the two group files.
|
||||
*/
|
||||
|
||||
static void open_files (void)
|
||||
{
|
||||
if (!gr_lock ()) {
|
||||
@@ -171,7 +174,6 @@ static void open_files (void)
|
||||
* for any user. You must remove all users before you remove
|
||||
* the group.
|
||||
*/
|
||||
|
||||
static void group_busy (gid_t gid)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
@@ -196,7 +198,6 @@ static void group_busy (gid_t gid)
|
||||
/*
|
||||
* Can't remove the group.
|
||||
*/
|
||||
|
||||
fprintf (stderr, _("%s: cannot remove user's primary group.\n"), Prog);
|
||||
exit (E_GROUP_BUSY);
|
||||
}
|
||||
@@ -228,6 +229,10 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
@@ -287,8 +292,15 @@ int main (int argc, char **argv)
|
||||
if (!(grp = getgrnam (group_name))) {
|
||||
fprintf (stderr, _("%s: group %s does not exist\n"),
|
||||
Prog, group_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NOTFOUND);
|
||||
}
|
||||
|
||||
group_id = grp->gr_gid; /* LAUS */
|
||||
|
||||
#ifdef USE_NIS
|
||||
/*
|
||||
* Make sure this isn't a NIS group
|
||||
@@ -300,6 +312,10 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr, _("%s: group %s is a NIS group\n"),
|
||||
Prog, group_name);
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
if (!yp_get_default_domain (&nis_domain) &&
|
||||
!yp_master (nis_domain, "group.byname", &nis_master)) {
|
||||
fprintf (stderr, _("%s: %s is the NIS master\n"),
|
||||
@@ -327,21 +343,14 @@ int main (int argc, char **argv)
|
||||
close_files ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
if (errors != 0)
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (errors == 0 ? E_SUCCESS : E_GRP_UPDATE);
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
115
src/groupmod.c
115
src/groupmod.c
@@ -29,32 +29,29 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: groupmod.c,v 1.30 2005/08/02 17:49:17 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#ident "$Id: groupmod.c,v 1.36 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#include <pwd.h>
|
||||
#endif /* USE_PAM */
|
||||
#include "prototypes.h"
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
static int is_shadow_grp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
|
||||
#define E_SUCCESS 0 /* success */
|
||||
#define E_USAGE 2 /* invalid command syntax */
|
||||
#define E_BAD_ARG 3 /* invalid argument to option */
|
||||
@@ -62,7 +59,12 @@ static int is_shadow_grp;
|
||||
#define E_NOTFOUND 6 /* specified group doesn't exist */
|
||||
#define E_NAME_IN_USE 9 /* group name already in use */
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
#ifdef SHADOWGRP
|
||||
static int is_shadow_grp;
|
||||
#endif
|
||||
static char *group_name;
|
||||
static char *group_newname;
|
||||
static gid_t group_id;
|
||||
@@ -105,7 +107,6 @@ static void usage (void)
|
||||
* new_grent() takes all of the values that have been entered and fills
|
||||
* in a (struct group) with them.
|
||||
*/
|
||||
|
||||
static void new_grent (struct group *grent)
|
||||
{
|
||||
if (nflg)
|
||||
@@ -122,7 +123,6 @@ static void new_grent (struct group *grent)
|
||||
* new_sgent() takes all of the values that have been entered and fills
|
||||
* in a (struct sgrp) with them.
|
||||
*/
|
||||
|
||||
static void new_sgent (struct sgrp *sgent)
|
||||
{
|
||||
if (nflg)
|
||||
@@ -135,7 +135,6 @@ static void new_sgent (struct sgrp *sgent)
|
||||
*
|
||||
* grp_update() writes the new records to the group files.
|
||||
*/
|
||||
|
||||
static void grp_update (void)
|
||||
{
|
||||
struct group grp;
|
||||
@@ -149,12 +148,15 @@ static void grp_update (void)
|
||||
/*
|
||||
* Get the current settings for this group.
|
||||
*/
|
||||
|
||||
ogrp = gr_locate (group_name);
|
||||
if (!ogrp) {
|
||||
fprintf (stderr,
|
||||
_("%s: %s not found in /etc/group\n"),
|
||||
Prog, group_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
grp = *ogrp;
|
||||
@@ -169,40 +171,58 @@ static void grp_update (void)
|
||||
/*
|
||||
* Write out the new group file entry.
|
||||
*/
|
||||
|
||||
if (!gr_update (&grp)) {
|
||||
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
if (nflg && !gr_remove (group_name)) {
|
||||
fprintf (stderr, _("%s: error removing group entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
|
||||
/*
|
||||
* Make sure there was a shadow entry to begin with. Skip down to
|
||||
* "out" if there wasn't. Can't just return because there might be
|
||||
* some syslogging to do.
|
||||
*/
|
||||
|
||||
if (!osgrp)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Write out the new shadow group entries as well.
|
||||
*/
|
||||
|
||||
if (!sgr_update (&sgrp)) {
|
||||
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
if (nflg && !sgr_remove (group_name)) {
|
||||
fprintf (stderr, _("%s: error removing group entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_GRP_UPDATE);
|
||||
}
|
||||
out:
|
||||
#endif /* SHADOWGRP */
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifing group", group_name,
|
||||
group_id, 1);
|
||||
#endif
|
||||
if (nflg)
|
||||
SYSLOG ((LOG_INFO, "change group `%s' to `%s'",
|
||||
group_name, group_newname));
|
||||
@@ -217,7 +237,6 @@ static void grp_update (void)
|
||||
*
|
||||
* check_new_gid() insures that the new GID value is unique.
|
||||
*/
|
||||
|
||||
static void check_new_gid (void)
|
||||
{
|
||||
/*
|
||||
@@ -225,7 +244,6 @@ static void check_new_gid (void)
|
||||
* didn't really change, just return. If the ID didn't change, turn
|
||||
* off those flags. No sense doing needless work.
|
||||
*/
|
||||
|
||||
if (group_id == group_newid) {
|
||||
gflg = 0;
|
||||
return;
|
||||
@@ -237,8 +255,11 @@ static void check_new_gid (void)
|
||||
/*
|
||||
* Tell the user what they did wrong.
|
||||
*/
|
||||
|
||||
fprintf (stderr, _("%s: %u is not a unique GID\n"), Prog, group_newid);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modify gid", NULL,
|
||||
group_newid, 0);
|
||||
#endif
|
||||
exit (E_GID_IN_USE);
|
||||
}
|
||||
|
||||
@@ -248,13 +269,11 @@ static void check_new_gid (void)
|
||||
* check_new_name() insures that the new name does not exist already.
|
||||
* You can't have the same name twice, period.
|
||||
*/
|
||||
|
||||
static void check_new_name (void)
|
||||
{
|
||||
/*
|
||||
* Make sure they are actually changing the name.
|
||||
*/
|
||||
|
||||
if (strcmp (group_name, group_newname) == 0) {
|
||||
nflg = 0;
|
||||
return;
|
||||
@@ -265,11 +284,14 @@ static void check_new_name (void)
|
||||
/*
|
||||
* If the entry is found, too bad.
|
||||
*/
|
||||
|
||||
if (getgrnam (group_newname)) {
|
||||
fprintf (stderr,
|
||||
_("%s: %s is not a unique name\n"), Prog,
|
||||
group_newname);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"modifying group", group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NAME_IN_USE);
|
||||
}
|
||||
return;
|
||||
@@ -281,6 +303,10 @@ static void check_new_name (void)
|
||||
|
||||
fprintf (stderr, _("%s: %s is not a valid group name\n"),
|
||||
Prog, group_newname);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying group", group_name,
|
||||
-1, 0);
|
||||
#endif
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
|
||||
@@ -291,7 +317,6 @@ static void check_new_name (void)
|
||||
* values that the user will be created with accordingly. The values
|
||||
* are checked for sanity.
|
||||
*/
|
||||
|
||||
static void process_flags (int argc, char **argv)
|
||||
{
|
||||
char *end;
|
||||
@@ -306,6 +331,11 @@ static void process_flags (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_("%s: invalid group %s\n"),
|
||||
Prog, optarg);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"modifying group", NULL,
|
||||
group_newid, 0);
|
||||
#endif
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
break;
|
||||
@@ -335,7 +365,6 @@ static void process_flags (int argc, char **argv)
|
||||
* close_files() closes all of the files that were opened for this new
|
||||
* group. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!gr_close ()) {
|
||||
@@ -359,7 +388,6 @@ static void close_files (void)
|
||||
*
|
||||
* open_files() opens the two group files.
|
||||
*/
|
||||
|
||||
static void open_files (void)
|
||||
{
|
||||
if (!gr_lock ()) {
|
||||
@@ -403,7 +431,6 @@ static struct pam_conv conv = {
|
||||
* -o - permit the group ID value to be non-unique
|
||||
* -n - specify a new group name
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
struct group *grp;
|
||||
@@ -414,10 +441,13 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -469,10 +499,22 @@ int main (int argc, char **argv)
|
||||
if (!(grp = getgrnam (group_name))) {
|
||||
fprintf (stderr, _("%s: group %s does not exist\n"),
|
||||
Prog, group_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NOTFOUND);
|
||||
} else
|
||||
group_id = grp->gr_gid;
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
/* Set new name/id to original if not specified on command line */
|
||||
if (nflg == 0)
|
||||
group_newname = group_name;
|
||||
if (gflg == 0)
|
||||
group_newid = group_id;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NIS
|
||||
/*
|
||||
* Now make sure it isn't an NIS group.
|
||||
@@ -484,6 +526,10 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr, _("%s: group %s is a NIS group\n"),
|
||||
Prog, group_name);
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying group",
|
||||
group_name, -1, 0);
|
||||
#endif
|
||||
if (!yp_get_default_domain (&nis_domain) &&
|
||||
!yp_master (nis_domain, "group.byname", &nis_master)) {
|
||||
fprintf (stderr, _("%s: %s is the NIS master\n"),
|
||||
@@ -503,7 +549,6 @@ int main (int argc, char **argv)
|
||||
* Do the hard stuff - open the files, create the group entries,
|
||||
* then close and update the files.
|
||||
*/
|
||||
|
||||
open_files ();
|
||||
|
||||
grp_update ();
|
||||
@@ -512,18 +557,6 @@ int main (int argc, char **argv)
|
||||
close_files ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
18
src/groups.c
18
src/groups.c
@@ -29,13 +29,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: groups.c,v 1.10 2005/03/31 05:14:54 kloczek Exp $")
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#ident "$Id: groups.c,v 1.13 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
@@ -50,7 +50,6 @@ static void print_groups (const char *);
|
||||
* print_groups() scans the groups file for the list of groups which
|
||||
* the user is listed as being a member of.
|
||||
*/
|
||||
|
||||
static void print_groups (const char *member)
|
||||
{
|
||||
int groups = 0;
|
||||
@@ -87,7 +86,6 @@ static void print_groups (const char *member)
|
||||
/*
|
||||
* groups - print out the groups a process is a member of
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
long sys_ngroups;
|
||||
@@ -114,7 +112,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Get the program name so that error messages can use it.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
if (argc == 1) {
|
||||
@@ -130,7 +127,6 @@ int main (int argc, char **argv)
|
||||
* the system to tell me which groups are currently set for
|
||||
* this process.
|
||||
*/
|
||||
|
||||
ngroups = getgroups (sys_ngroups, groups);
|
||||
if (ngroups < 0) {
|
||||
perror ("getgroups");
|
||||
@@ -140,7 +136,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* The groupset includes the primary group as well.
|
||||
*/
|
||||
|
||||
pri_grp = getegid ();
|
||||
for (i = 0; i < ngroups; i++)
|
||||
if (pri_grp == (int) groups[i])
|
||||
@@ -154,7 +149,6 @@ int main (int argc, char **argv)
|
||||
* set. Unknown groups are printed as their decimal group ID
|
||||
* values.
|
||||
*/
|
||||
|
||||
if (pri_grp != -1) {
|
||||
if ((gr = getgrgid (pri_grp)))
|
||||
printf ("%s", gr->gr_name);
|
||||
@@ -177,7 +171,6 @@ int main (int argc, char **argv)
|
||||
* This system does not have the getgroups() system call, so
|
||||
* I must check the groups file directly.
|
||||
*/
|
||||
|
||||
if ((logname = getlogin ()))
|
||||
print_groups (logname);
|
||||
else
|
||||
@@ -189,7 +182,6 @@ int main (int argc, char **argv)
|
||||
* The invoker wanted to know about some other user. Use
|
||||
* that name to look up the groups instead.
|
||||
*/
|
||||
|
||||
print_groups (argv[1]);
|
||||
}
|
||||
exit (0);
|
||||
|
60
src/grpck.c
60
src/grpck.c
@@ -29,17 +29,17 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: grpck.c,v 1.25 2005/08/09 15:27:51 kloczek Exp $")
|
||||
#include <stdio.h>
|
||||
#ident "$Id: grpck.c,v 1.28 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include "chkname.h"
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "groupio.h"
|
||||
#include "prototypes.h"
|
||||
extern void __gr_del_entry (const struct commonio_entry *);
|
||||
extern struct commonio_entry *__gr_get_head (void);
|
||||
|
||||
@@ -61,9 +61,8 @@ extern struct commonio_entry *__sgr_get_head (void);
|
||||
#define E_CANT_UPDATE 5
|
||||
|
||||
/*
|
||||
* Local variables
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
static char *Prog;
|
||||
static const char *grp_file = GROUP_FILE;
|
||||
|
||||
@@ -80,7 +79,6 @@ static void delete_member (char **, const char *);
|
||||
/*
|
||||
* usage - print syntax message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
#ifdef SHADOWGRP
|
||||
@@ -94,7 +92,6 @@ static void usage (void)
|
||||
/*
|
||||
* yes_or_no - get answer to question from the user
|
||||
*/
|
||||
|
||||
static int yes_or_no (void)
|
||||
{
|
||||
char buf[80];
|
||||
@@ -102,7 +99,6 @@ static int yes_or_no (void)
|
||||
/*
|
||||
* In read-only mode all questions are answered "no".
|
||||
*/
|
||||
|
||||
if (read_only) {
|
||||
printf (_("No\n"));
|
||||
return 0;
|
||||
@@ -111,7 +107,6 @@ static int yes_or_no (void)
|
||||
/*
|
||||
* Get a line and see what the first character is.
|
||||
*/
|
||||
|
||||
if (fgets (buf, sizeof buf, stdin))
|
||||
return buf[0] == 'y' || buf[0] == 'Y';
|
||||
|
||||
@@ -121,7 +116,6 @@ static int yes_or_no (void)
|
||||
/*
|
||||
* delete_member - delete an entry in a list of members
|
||||
*/
|
||||
|
||||
static void delete_member (char **list, const char *member)
|
||||
{
|
||||
int i;
|
||||
@@ -138,7 +132,6 @@ static void delete_member (char **list, const char *member)
|
||||
/*
|
||||
* grpck - verify group file integrity
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int arg;
|
||||
@@ -158,7 +151,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -170,7 +162,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Parse the command line arguments
|
||||
*/
|
||||
|
||||
while ((arg = getopt (argc, argv, "qrs")) != EOF) {
|
||||
switch (arg) {
|
||||
case 'q':
|
||||
@@ -195,7 +186,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make certain we have the right number of arguments
|
||||
*/
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
if (optind != argc && optind + 1 != argc && optind + 2 != argc)
|
||||
#else
|
||||
@@ -207,7 +197,6 @@ int main (int argc, char **argv)
|
||||
* If there are two left over filenames, use those as the group and
|
||||
* group password filenames.
|
||||
*/
|
||||
|
||||
if (optind != argc) {
|
||||
grp_file = argv[optind];
|
||||
gr_name (grp_file);
|
||||
@@ -224,7 +213,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Lock the files if we aren't in "read-only" mode
|
||||
*/
|
||||
|
||||
if (!read_only) {
|
||||
if (!gr_lock ()) {
|
||||
fprintf (stderr, _("%s: cannot lock file %s\n"),
|
||||
@@ -250,7 +238,6 @@ int main (int argc, char **argv)
|
||||
* Open the files. Use O_RDONLY if we are in read_only mode,
|
||||
* O_RDWR otherwise.
|
||||
*/
|
||||
|
||||
if (!gr_open (read_only ? O_RDONLY : O_RDWR)) {
|
||||
fprintf (stderr, _("%s: cannot open file %s\n"), Prog,
|
||||
grp_file);
|
||||
@@ -282,7 +269,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Loop through the entire group file.
|
||||
*/
|
||||
|
||||
for (gre = __gr_get_head (); gre; gre = gre->next) {
|
||||
/*
|
||||
* Skip all NIS entries.
|
||||
@@ -296,14 +282,12 @@ int main (int argc, char **argv)
|
||||
* have no (struct group) entry because they couldn't be
|
||||
* parsed properly.
|
||||
*/
|
||||
|
||||
if (!gre->eptr) {
|
||||
|
||||
/*
|
||||
* Tell the user this entire line is bogus and ask
|
||||
* them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("invalid group file entry\n"));
|
||||
printf (_("delete line `%s'? "), gre->line);
|
||||
errors++;
|
||||
@@ -311,7 +295,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (!yes_or_no ())
|
||||
continue;
|
||||
|
||||
@@ -321,7 +304,6 @@ int main (int argc, char **argv)
|
||||
* When done, it skips back to the top of the loop
|
||||
* to try out the next list element.
|
||||
*/
|
||||
|
||||
delete_gr:
|
||||
SYSLOG ((LOG_INFO, "delete group line `%s'",
|
||||
gre->line));
|
||||
@@ -334,13 +316,11 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Group structure is good, start using it.
|
||||
*/
|
||||
|
||||
grp = gre->eptr;
|
||||
|
||||
/*
|
||||
* Make sure this entry has a unique name.
|
||||
*/
|
||||
|
||||
for (tgre = __gr_get_head (); tgre; tgre = tgre->next) {
|
||||
|
||||
const struct group *ent = tgre->eptr;
|
||||
@@ -348,14 +328,12 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Don't check this entry
|
||||
*/
|
||||
|
||||
if (tgre == gre)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't check invalid entries.
|
||||
*/
|
||||
|
||||
if (!ent)
|
||||
continue;
|
||||
|
||||
@@ -366,7 +344,6 @@ int main (int argc, char **argv)
|
||||
* Tell the user this entry is a duplicate of
|
||||
* another and ask them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("duplicate group entry\n"));
|
||||
printf (_("delete line `%s'? "), gre->line);
|
||||
errors++;
|
||||
@@ -374,7 +351,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (yes_or_no ())
|
||||
goto delete_gr;
|
||||
}
|
||||
@@ -392,7 +368,6 @@ int main (int argc, char **argv)
|
||||
* groups with no members are returned as groups with one
|
||||
* member "", causing grpck to fail. --marekm
|
||||
*/
|
||||
|
||||
if (grp->gr_mem[0] && !grp->gr_mem[1]
|
||||
&& *(grp->gr_mem[0]) == '\0')
|
||||
grp->gr_mem[0] = (char *) 0;
|
||||
@@ -400,7 +375,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure each member exists
|
||||
*/
|
||||
|
||||
for (i = 0; grp->gr_mem[i]; i++) {
|
||||
if (getpwnam (grp->gr_mem[i]))
|
||||
continue;
|
||||
@@ -408,7 +382,6 @@ int main (int argc, char **argv)
|
||||
* Can't find this user. Remove them
|
||||
* from the list.
|
||||
*/
|
||||
|
||||
errors++;
|
||||
printf (_("group %s: no user %s\n"),
|
||||
grp->gr_name, grp->gr_mem[i]);
|
||||
@@ -433,7 +406,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Loop through the entire shadow group file.
|
||||
*/
|
||||
|
||||
for (sge = __sgr_get_head (); sge; sge = sge->next) {
|
||||
|
||||
/*
|
||||
@@ -441,14 +413,12 @@ int main (int argc, char **argv)
|
||||
* have no (struct sgrp) entry because they couldn't be
|
||||
* parsed properly.
|
||||
*/
|
||||
|
||||
if (!sge->eptr) {
|
||||
|
||||
/*
|
||||
* Tell the user this entire line is bogus and ask
|
||||
* them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("invalid shadow group file entry\n"));
|
||||
printf (_("delete line `%s'? "), sge->line);
|
||||
errors++;
|
||||
@@ -456,7 +426,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (!yes_or_no ())
|
||||
continue;
|
||||
|
||||
@@ -466,7 +435,6 @@ int main (int argc, char **argv)
|
||||
* linked list. When done, it skips back to the top
|
||||
* of the loop to try out the next list element.
|
||||
*/
|
||||
|
||||
delete_sg:
|
||||
SYSLOG ((LOG_INFO, "delete shadow line `%s'",
|
||||
sge->line));
|
||||
@@ -479,13 +447,11 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Shadow group structure is good, start using it.
|
||||
*/
|
||||
|
||||
sgr = sge->eptr;
|
||||
|
||||
/*
|
||||
* Make sure this entry has a unique name.
|
||||
*/
|
||||
|
||||
for (tsge = __sgr_get_head (); tsge; tsge = tsge->next) {
|
||||
|
||||
const struct sgrp *ent = tsge->eptr;
|
||||
@@ -493,14 +459,12 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Don't check this entry
|
||||
*/
|
||||
|
||||
if (tsge == sge)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't check invalid entries.
|
||||
*/
|
||||
|
||||
if (!ent)
|
||||
continue;
|
||||
|
||||
@@ -511,7 +475,6 @@ int main (int argc, char **argv)
|
||||
* Tell the user this entry is a duplicate of
|
||||
* another and ask them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("duplicate shadow group entry\n"));
|
||||
printf (_("delete line `%s'? "), sge->line);
|
||||
errors++;
|
||||
@@ -519,7 +482,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (yes_or_no ())
|
||||
goto delete_sg;
|
||||
}
|
||||
@@ -527,7 +489,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure this entry exists in the /etc/group file.
|
||||
*/
|
||||
|
||||
if (!gr_locate (sgr->sg_name)) {
|
||||
printf (_("no matching group file entry\n"));
|
||||
printf (_("delete line `%s'? "), sge->line);
|
||||
@@ -539,7 +500,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure each administrator exists
|
||||
*/
|
||||
|
||||
for (i = 0; sgr->sg_adm[i]; i++) {
|
||||
if (getpwnam (sgr->sg_adm[i]))
|
||||
continue;
|
||||
@@ -547,7 +507,6 @@ int main (int argc, char **argv)
|
||||
* Can't find this user. Remove them
|
||||
* from the list.
|
||||
*/
|
||||
|
||||
errors++;
|
||||
printf (_
|
||||
("shadow group %s: no administrative user %s\n"),
|
||||
@@ -570,7 +529,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure each member exists
|
||||
*/
|
||||
|
||||
for (i = 0; sgr->sg_mem[i]; i++) {
|
||||
if (getpwnam (sgr->sg_mem[i]))
|
||||
continue;
|
||||
@@ -578,7 +536,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Can't find this user. Remove them from the list.
|
||||
*/
|
||||
|
||||
errors++;
|
||||
printf (_("shadow group %s: no user %s\n"),
|
||||
sgr->sg_name, sgr->sg_mem[i]);
|
||||
@@ -604,7 +561,6 @@ int main (int argc, char **argv)
|
||||
* All done. If there were no deletions we can just abandon any
|
||||
* changes to the files.
|
||||
*/
|
||||
|
||||
if (deleted) {
|
||||
write_and_bye:
|
||||
if (!gr_close ()) {
|
||||
@@ -624,7 +580,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Don't be anti-social - unlock the files when you're done.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow)
|
||||
sgr_unlock ();
|
||||
@@ -636,7 +591,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Tell the user what we did and exit.
|
||||
*/
|
||||
|
||||
if (errors)
|
||||
printf (deleted ?
|
||||
_("%s: the files have been updated\n") :
|
||||
|
@@ -9,26 +9,23 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#ident "$Id: grpconv.c,v 1.19 2005/08/31 17:25:00 kloczek Exp $"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
|
||||
#include "groupio.h"
|
||||
#include "sgroupio.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: grpconv.c,v 1.17 2005/08/09 15:27:51 kloczek Exp $")
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static int group_locked = 0;
|
||||
static int gshadow_locked = 0;
|
||||
|
||||
|
@@ -10,8 +10,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: grpunconv.c,v 1.15 2005/08/09 15:27:51 kloczek Exp $")
|
||||
#ident "$Id: grpunconv.c,v 1.17 2005/08/31 17:25:00 kloczek Exp $"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -23,6 +23,9 @@ RCSID (PKG_VER "$Id: grpunconv.c,v 1.15 2005/08/09 15:27:51 kloczek Exp $")
|
||||
#ifdef SHADOWGRP
|
||||
#include "groupio.h"
|
||||
#include "sgroupio.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static int group_locked = 0;
|
||||
static int gshadow_locked = 0;
|
||||
|
||||
|
11
src/id.c
11
src/id.c
@@ -37,12 +37,12 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: id.c,v 1.15 2005/06/20 10:17:08 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#ident "$Id: id.c,v 1.18 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
/* local function prototypes */
|
||||
static void usage (void);
|
||||
@@ -154,7 +154,6 @@ static void usage (void)
|
||||
* Print out the concurrent group set if the user has requested it.
|
||||
* The group numbers will be printed followed by their names.
|
||||
*/
|
||||
|
||||
if (aflg && (ngroups = getgroups (sys_ngroups, groups)) != -1) {
|
||||
|
||||
/*
|
||||
@@ -165,7 +164,6 @@ static void usage (void)
|
||||
* where "###" is a numerical value and "aaa" is the
|
||||
* corresponding name for each respective numerical value.
|
||||
*/
|
||||
|
||||
printf (_(" groups="));
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
if (i)
|
||||
@@ -184,7 +182,6 @@ static void usage (void)
|
||||
/*
|
||||
* Finish off the line.
|
||||
*/
|
||||
|
||||
putchar ('\n');
|
||||
exit (0);
|
||||
/* NOT REACHED */
|
||||
|
@@ -29,30 +29,37 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: lastlog.c,v 1.18 2005/04/27 16:55:33 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <lastlog.h>
|
||||
#ident "$Id: lastlog.c,v 1.23 2005/08/31 17:25:00 kloczek Exp $"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <lastlog.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*
|
||||
* Needed for MkLinux DR1/2/2.1 - J.
|
||||
*/
|
||||
#ifndef LASTLOG_FILE
|
||||
#define LASTLOG_FILE "/var/log/lastlog"
|
||||
#endif
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static FILE *lastlogfile; /* lastlog file stream */
|
||||
static off_t user; /* one single user, specified on command line */
|
||||
static int days; /* number of days to consider for print command */
|
||||
static time_t seconds; /* that number of days in seconds */
|
||||
static int inverse_days; /* number of days to consider for print command */
|
||||
static time_t inverse_seconds; /* that number of days in seconds */
|
||||
|
||||
|
||||
static int uflg = 0; /* set if user is a valid user id */
|
||||
static int tflg = 0; /* print is restricted to most recent days */
|
||||
static int bflg = 0; /* print excludes most recent days */
|
||||
static struct lastlog lastlog; /* scratch structure to play with ... */
|
||||
static struct stat statbuf; /* fstat buffer for file size */
|
||||
static struct passwd *pwent;
|
||||
@@ -64,9 +71,10 @@ static void usage (void)
|
||||
fprintf (stdout, _("Usage: lastlog [options]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -u, --user LOGIN print lastlog record for user with specified LOGIN\n"
|
||||
" -b, --before DAYS print only lastlog records older than DAYS\n"
|
||||
" -h, --help display this help message and exit\n"
|
||||
" -t, --time DAYS print only lastlog records more recent than DAYS\n"));
|
||||
" -t, --time DAYS print only lastlog records more recent than DAYS\n"
|
||||
" -u, --user LOGIN print lastlog record for user with specified LOGIN\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
@@ -148,6 +156,9 @@ static void print (void)
|
||||
if (tflg && NOW - lastlog.ll_time > seconds)
|
||||
continue;
|
||||
|
||||
if (bflg && NOW - lastlog.ll_time < inverse_seconds)
|
||||
continue;
|
||||
|
||||
print_one (pwent);
|
||||
}
|
||||
}
|
||||
@@ -164,12 +175,13 @@ int main (int argc, char **argv)
|
||||
static struct option const longopts[] = {
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"time", required_argument, NULL, 't'},
|
||||
{"before", required_argument, NULL, 'b'},
|
||||
{"user", required_argument, NULL, 'u'},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
while ((c =
|
||||
getopt_long (argc, argv, "ht:u:", longopts,
|
||||
getopt_long (argc, argv, "ht:b:u:", longopts,
|
||||
NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
@@ -180,6 +192,11 @@ int main (int argc, char **argv)
|
||||
seconds = days * DAY;
|
||||
tflg++;
|
||||
break;
|
||||
case 'b':
|
||||
inverse_days = atoi (optarg);
|
||||
inverse_seconds = inverse_days * DAY;
|
||||
bflg++;
|
||||
break;
|
||||
case 'u':
|
||||
pwent = getpwnam (optarg);
|
||||
if (!pwent) {
|
||||
|
96
src/login.c
96
src/login.c
@@ -29,24 +29,24 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: login.c,v 1.67 2005/08/11 11:26:11 kloczek Exp $")
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#ident "$Id: login.c,v 1.74 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <signal.h>
|
||||
#include <lastlog.h>
|
||||
#include "faillog.h"
|
||||
#include "failure.h"
|
||||
#include "pwauth.h"
|
||||
#include "getdef.h"
|
||||
#ifdef UT_ADDR
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include "failure.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
static const struct pam_conv conv = {
|
||||
@@ -73,6 +73,9 @@ static pam_handle_t *pamh = NULL;
|
||||
#define LASTLOG_FILE "/var/log/lastlog"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
const char *hostname = "";
|
||||
|
||||
static struct passwd pwent;
|
||||
@@ -150,7 +153,6 @@ static RETSIGTYPE alarm_handler (int);
|
||||
* login -h hostname (for telnetd, etc.)
|
||||
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-p] [name]\n"), Prog);
|
||||
@@ -172,7 +174,6 @@ static void setup_tty (void)
|
||||
/*
|
||||
* Add your favorite terminal modes here ...
|
||||
*/
|
||||
|
||||
termio.c_lflag |= ISIG | ICANON | ECHO | ECHOE;
|
||||
termio.c_iflag |= ICRNL;
|
||||
|
||||
@@ -184,7 +185,6 @@ static void setup_tty (void)
|
||||
* ttymon invocation prefers this, but these settings won't come into
|
||||
* effect after the first username login
|
||||
*/
|
||||
|
||||
STTY (0, &termio);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,6 @@ static void check_nologin (void)
|
||||
* out for root so she knows to remove the file if she's
|
||||
* forgotten about it ...
|
||||
*/
|
||||
|
||||
fname = getdef_str ("NOLOGINS_FILE");
|
||||
if (fname != NULL && access (fname, F_OK) == 0) {
|
||||
FILE *nlfp;
|
||||
@@ -220,7 +219,6 @@ static void check_nologin (void)
|
||||
* Cat the file if it can be opened, otherwise just
|
||||
* print a default message
|
||||
*/
|
||||
|
||||
if ((nlfp = fopen (fname, "r"))) {
|
||||
while ((c = getc (nlfp)) != EOF) {
|
||||
if (c == '\n')
|
||||
@@ -274,26 +272,24 @@ static void init_env (void)
|
||||
* Add the timezone environmental variable so that time functions
|
||||
* work correctly.
|
||||
*/
|
||||
|
||||
if ((tmp = getenv ("TZ"))) {
|
||||
addenv ("TZ", tmp);
|
||||
}
|
||||
}
|
||||
#ifndef USE_PAM
|
||||
else if ((cp = getdef_str ("ENV_TZ")))
|
||||
else if ((cp = getdef_str ("ENV_TZ")))
|
||||
addenv (*cp == '/' ? tz (cp) : cp, NULL);
|
||||
#endif /* !USE_PAM */
|
||||
#endif /* !USE_PAM */
|
||||
/*
|
||||
* Add the clock frequency so that profiling commands work
|
||||
* correctly.
|
||||
*/
|
||||
|
||||
if ((tmp = getenv ("HZ"))) {
|
||||
addenv ("HZ", tmp);
|
||||
}
|
||||
}
|
||||
#ifndef USE_PAM
|
||||
else if ((cp = getdef_str ("ENV_HZ")))
|
||||
else if ((cp = getdef_str ("ENV_HZ")))
|
||||
addenv (cp, NULL);
|
||||
#endif /* !USE_PAM */
|
||||
#endif /* !USE_PAM */
|
||||
}
|
||||
|
||||
|
||||
@@ -321,7 +317,6 @@ static RETSIGTYPE alarm_handler (int sig)
|
||||
* -f - do not perform authentication, user is preauthenticated
|
||||
* -h - the name of the remote host
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char username[32];
|
||||
@@ -434,14 +429,6 @@ int main (int argc, char **argv)
|
||||
if (!isatty (0) || !isatty (1) || !isatty (2))
|
||||
exit (1); /* must be a terminal */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Get the utmp file entry and get the tty name from it. The
|
||||
* current process ID must match the process ID in the utmp
|
||||
* file if there are no additional flags on the command line.
|
||||
*/
|
||||
checkutmp (!rflg && !fflg && !hflg);
|
||||
#else
|
||||
/*
|
||||
* Be picky if run by normal users (possible if installed setuid
|
||||
* root), but not if run by root. This way it still allows logins
|
||||
@@ -450,7 +437,6 @@ int main (int argc, char **argv)
|
||||
* entry (will not overwrite remote hostname). --marekm
|
||||
*/
|
||||
checkutmp (!amroot);
|
||||
#endif
|
||||
STRFCPY (tty, utent.ut_line);
|
||||
is_console = console (tty);
|
||||
|
||||
@@ -517,7 +503,6 @@ int main (int argc, char **argv)
|
||||
* user may have one for themselves, but otherwise,
|
||||
* just take what you get.
|
||||
*/
|
||||
|
||||
long limit = getdef_long ("ULIMIT", -1L);
|
||||
|
||||
if (limit != -1)
|
||||
@@ -529,7 +514,6 @@ int main (int argc, char **argv)
|
||||
* The entire environment will be preserved if the -p flag
|
||||
* is used.
|
||||
*/
|
||||
|
||||
if (pflg)
|
||||
while (*envp) /* add inherited environment, */
|
||||
addenv (*envp++, NULL); /* some variables change later */
|
||||
@@ -593,12 +577,13 @@ int main (int argc, char **argv)
|
||||
retcode = pam_start ("login", username, &conv, &pamh);
|
||||
if (retcode != PAM_SUCCESS) {
|
||||
fprintf (stderr,
|
||||
"login: PAM Failure, aborting: %s\n",
|
||||
_("login: PAM Failure, aborting: %s\n"),
|
||||
pam_strerror (pamh, retcode));
|
||||
SYSLOG ((LOG_ERR, "Couldn't initialize PAM: %s",
|
||||
pam_strerror (pamh, retcode)));
|
||||
pam_strerror (pamh, retcode)));
|
||||
exit (99);
|
||||
}
|
||||
|
||||
/*
|
||||
* hostname & tty are either set to NULL or their correct values,
|
||||
* depending on how much we know. We also set PAM's fail delay to
|
||||
@@ -646,7 +631,6 @@ int main (int argc, char **argv)
|
||||
* pay attention to failure count and get rid of
|
||||
* MAX_LOGIN_TRIES?
|
||||
*/
|
||||
|
||||
retcode = pam_authenticate (pamh, 0);
|
||||
while ((failcount++ < retries) &&
|
||||
((retcode == PAM_AUTH_ERR) ||
|
||||
@@ -656,13 +640,13 @@ int main (int argc, char **argv)
|
||||
pam_get_item (pamh, PAM_USER,
|
||||
(const void **) &pam_user);
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"FAILED LOGIN %d FROM %s FOR %s, %s",
|
||||
failcount, hostname, pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
"FAILED LOGIN %d FROM %s FOR %s, %s",
|
||||
failcount, hostname, pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
#ifdef HAVE_PAM_FAIL_DELAY
|
||||
pam_fail_delay (pamh, 1000000 * delay);
|
||||
#endif
|
||||
fprintf (stderr, "Login incorrect\n\n");
|
||||
fprintf (stderr, _("\nLogin incorrect\n"));
|
||||
pam_set_item (pamh, PAM_USER, NULL);
|
||||
retcode = pam_authenticate (pamh, 0);
|
||||
}
|
||||
@@ -673,15 +657,15 @@ int main (int argc, char **argv)
|
||||
|
||||
if (retcode == PAM_MAXTRIES)
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"TOO MANY LOGIN TRIES (%d) FROM %s FOR %s, %s",
|
||||
failcount, hostname,
|
||||
pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
"TOO MANY LOGIN TRIES (%d) FROM %s FOR %s, %s",
|
||||
failcount, hostname,
|
||||
pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
else
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"FAILED LOGIN SESSION FROM %s FOR %s, %s",
|
||||
hostname, pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
"FAILED LOGIN SESSION FROM %s FOR %s, %s",
|
||||
hostname, pam_user,
|
||||
pam_strerror (pamh, retcode)));
|
||||
|
||||
fprintf (stderr, "\nLogin incorrect\n");
|
||||
pam_end (pamh, retcode);
|
||||
@@ -803,7 +787,6 @@ int main (int argc, char **argv)
|
||||
* If you reach this far, your password has been
|
||||
* authenticated and so on.
|
||||
*/
|
||||
|
||||
if (!failed && pwent.pw_name && pwent.pw_uid == 0
|
||||
&& !is_console) {
|
||||
SYSLOG ((LOG_CRIT, "ILLEGAL ROOT LOGIN %s", fromhost));
|
||||
@@ -867,7 +850,6 @@ int main (int argc, char **argv)
|
||||
if (--retries <= 0)
|
||||
SYSLOG ((LOG_CRIT, "REPEATED login failures%s",
|
||||
fromhost));
|
||||
#if 1
|
||||
/*
|
||||
* If this was a passwordless account and we get here, login
|
||||
* was denied (securetty, faillog, etc.). There was no
|
||||
@@ -875,16 +857,14 @@ int main (int argc, char **argv)
|
||||
* guys won't see that the passwordless account exists at
|
||||
* all). --marekm
|
||||
*/
|
||||
|
||||
if (pwent.pw_passwd[0] == '\0')
|
||||
pw_auth ("!", username, reason, (char *) 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wait a while (a la SVR4 /usr/bin/login) before attempting
|
||||
* to login the user again. If the earlier alarm occurs
|
||||
* before the sleep() below completes, login will exit.
|
||||
*/
|
||||
|
||||
if (delay > 0)
|
||||
sleep (delay);
|
||||
|
||||
@@ -969,8 +949,8 @@ int main (int argc, char **argv)
|
||||
child = fork ();
|
||||
if (child < 0) {
|
||||
/* error in fork() */
|
||||
fprintf (stderr, "login: failure forking: %s",
|
||||
strerror (errno));
|
||||
fprintf (stderr, _("%s: failure forking: %s"),
|
||||
Prog, strerror (errno));
|
||||
PAM_END;
|
||||
exit (0);
|
||||
} else if (child) {
|
||||
|
@@ -22,8 +22,8 @@
|
||||
#endif
|
||||
|
||||
#ifndef USE_PAM
|
||||
#include "rcsid.h"
|
||||
RCSID ("$Id: login_nopam.c,v 1.5 2005/07/02 17:53:06 kloczek Exp $")
|
||||
#ident "$Id: login_nopam.c,v 1.8 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include "prototypes.h"
|
||||
/*
|
||||
* This module implements a simple but effective form of login access
|
||||
@@ -63,13 +63,11 @@ extern int innetgr ();
|
||||
#define TABLE "/etc/login.access"
|
||||
#endif
|
||||
|
||||
/* Delimiters for fields and for lists of users, ttys or hosts. */
|
||||
|
||||
/* Delimiters for fields and for lists of users, ttys or hosts. */
|
||||
static char fs[] = ":"; /* field separator */
|
||||
static char sep[] = ", \t"; /* list-element separator */
|
||||
|
||||
/* Constants to be used in assignments only, not in comparisons... */
|
||||
|
||||
/* Constants to be used in assignments only, not in comparisons... */
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
@@ -79,7 +77,6 @@ static int from_match ();
|
||||
static int string_match ();
|
||||
|
||||
/* login_access - match username/group and host/tty with access control file */
|
||||
|
||||
int login_access (const char *user, const char *from)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -98,14 +95,13 @@ int login_access (const char *user, const char *from)
|
||||
* mandatory. The first field should be a "+" or "-" character. A
|
||||
* non-existing table means no access control.
|
||||
*/
|
||||
|
||||
if ((fp = fopen (TABLE, "r"))) {
|
||||
while (!match && fgets (line, sizeof (line), fp)) {
|
||||
lineno++;
|
||||
if (line[end = strlen (line) - 1] != '\n') {
|
||||
SYSLOG ((LOG_ERR,
|
||||
"%s: line %d: missing newline or line too long",
|
||||
TABLE, lineno));
|
||||
"%s: line %d: missing newline or line too long",
|
||||
TABLE, lineno));
|
||||
continue;
|
||||
}
|
||||
if (line[0] == '#')
|
||||
@@ -120,14 +116,14 @@ int login_access (const char *user, const char *from)
|
||||
|| !(froms = strtok ((char *) 0, fs))
|
||||
|| strtok ((char *) 0, fs)) {
|
||||
SYSLOG ((LOG_ERR,
|
||||
"%s: line %d: bad field count",
|
||||
TABLE, lineno));
|
||||
"%s: line %d: bad field count",
|
||||
TABLE, lineno));
|
||||
continue;
|
||||
}
|
||||
if (perm[0] != '+' && perm[0] != '-') {
|
||||
SYSLOG ((LOG_ERR,
|
||||
"%s: line %d: bad first field",
|
||||
TABLE, lineno));
|
||||
"%s: line %d: bad first field",
|
||||
TABLE, lineno));
|
||||
continue;
|
||||
}
|
||||
match = (list_match (froms, from, from_match)
|
||||
@@ -141,7 +137,6 @@ int login_access (const char *user, const char *from)
|
||||
}
|
||||
|
||||
/* list_match - match an item against a list of tokens with exceptions */
|
||||
|
||||
static int list_match (char *list, const char *item, int (*match_fn) ())
|
||||
{
|
||||
char *tok;
|
||||
@@ -153,15 +148,14 @@ static int list_match (char *list, const char *item, int (*match_fn) ())
|
||||
* 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 != 0; tok = strtok ((char *) 0, sep)) {
|
||||
if (strcasecmp (tok, "EXCEPT") == 0) /* EXCEPT: give up */
|
||||
break;
|
||||
if ((match = (*match_fn) (tok, item))) /* YES */
|
||||
break;
|
||||
}
|
||||
/* Process exceptions to matches. */
|
||||
|
||||
/* Process exceptions to matches. */
|
||||
if (match != NO) {
|
||||
while ((tok = strtok ((char *) 0, sep))
|
||||
&& strcasecmp (tok, "EXCEPT"))
|
||||
@@ -173,7 +167,6 @@ static int list_match (char *list, const char *item, int (*match_fn) ())
|
||||
}
|
||||
|
||||
/* myhostname - figure out local machine name */
|
||||
|
||||
static char *myhostname (void)
|
||||
{
|
||||
static char name[MAXHOSTNAMELEN + 1] = "";
|
||||
@@ -186,7 +179,6 @@ static char *myhostname (void)
|
||||
}
|
||||
|
||||
/* netgroup_match - match group against machine or user */
|
||||
|
||||
static int
|
||||
netgroup_match (const char *group, const char *machine, const char *user)
|
||||
{
|
||||
@@ -203,7 +195,6 @@ netgroup_match (const char *group, const char *machine, const char *user)
|
||||
}
|
||||
|
||||
/* user_match - match a username against one token */
|
||||
|
||||
static int user_match (const char *tok, const char *string)
|
||||
{
|
||||
struct group *group;
|
||||
@@ -219,7 +210,6 @@ static int user_match (const char *tok, const char *string)
|
||||
* Otherwise, return YES if the token fully matches the username, or if
|
||||
* the token is a group that contains the username.
|
||||
*/
|
||||
|
||||
if ((at = strchr (tok + 1, '@')) != 0) { /* split user@host pattern */
|
||||
*at = 0;
|
||||
return (user_match (tok, string)
|
||||
@@ -281,7 +271,6 @@ static int from_match (const char *tok, const char *string)
|
||||
* contain a "." character. If the token is a network number, return YES
|
||||
* if it matches the head of the string.
|
||||
*/
|
||||
|
||||
if (tok[0] == '@') { /* netgroup */
|
||||
return (netgroup_match (tok + 1, string, (char *) 0));
|
||||
} else if (string_match (tok, string)) { /* ALL or exact match */
|
||||
@@ -301,7 +290,6 @@ static int from_match (const char *tok, const char *string)
|
||||
}
|
||||
|
||||
/* string_match - match a string against one token */
|
||||
|
||||
static int string_match (const char *tok, const char *string)
|
||||
{
|
||||
|
||||
@@ -309,7 +297,6 @@ static int string_match (const char *tok, const char *string)
|
||||
* If the token has the magic value "ALL" the match always succeeds.
|
||||
* Otherwise, return YES if the token fully matches the string.
|
||||
*/
|
||||
|
||||
if (strcasecmp (tok, "ALL") == 0) { /* all: always matches */
|
||||
return (YES);
|
||||
} else if (strcasecmp (tok, string) == 0) { /* try exact match */
|
||||
|
@@ -29,19 +29,22 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: logoutd.c,v 1.26 2005/07/05 20:17:51 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#ident "$Id: logoutd.c,v 1.30 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "prototypes.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *Prog;
|
||||
|
||||
#ifndef DEFAULT_HUP_MESG
|
||||
#define DEFAULT_HUP_MESG "login time exceeded\r\n"
|
||||
#define DEFAULT_HUP_MESG _("login time exceeded\n\n")
|
||||
#endif
|
||||
|
||||
#ifndef HUP_MESG_FILE
|
||||
@@ -130,7 +133,6 @@ static void send_mesg_to_tty (int tty_fd)
|
||||
* utmpx/utmp file is periodically scanned and offending users are logged
|
||||
* off from the system.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
@@ -158,7 +160,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Put this process in the background.
|
||||
*/
|
||||
|
||||
pid = fork ();
|
||||
if (pid > 0) {
|
||||
/* parent */
|
||||
@@ -173,7 +174,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Start syslogging everything
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
OPENLOG ("logoutd");
|
||||
@@ -182,14 +182,12 @@ int main (int argc, char **argv)
|
||||
* Scan the utmpx/utmp file once per minute looking for users that
|
||||
* are not supposed to still be logged in.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
|
||||
/*
|
||||
* Attempt to re-open the utmpx/utmp file. The file is only
|
||||
* open while it is being used.
|
||||
*/
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
setutxent ();
|
||||
#else
|
||||
@@ -201,7 +199,6 @@ int main (int argc, char **argv)
|
||||
* for login sessions will be checked to see if the user
|
||||
* is permitted to be signed on at this time.
|
||||
*/
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
while ((ut = getutxent ())) {
|
||||
#else
|
||||
@@ -258,7 +255,6 @@ int main (int argc, char **argv)
|
||||
* vhangup() the line to kill try and kill
|
||||
* whatever is out there using it.
|
||||
*/
|
||||
|
||||
if ((tty_fd =
|
||||
open (tty_name, O_RDONLY | O_NDELAY)) == -1)
|
||||
continue;
|
||||
@@ -277,7 +273,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* This child has done all it can, drop dead.
|
||||
*/
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
@@ -293,7 +288,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Reap any dead babies ...
|
||||
*/
|
||||
|
||||
while (wait (&status) != -1);
|
||||
}
|
||||
return 1;
|
||||
|
57
src/newgrp.c
57
src/newgrp.c
@@ -29,15 +29,18 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: newgrp.c,v 1.35 2005/08/11 11:26:11 kloczek Exp $")
|
||||
#include <stdio.h>
|
||||
#ident "$Id: newgrp.c,v 1.41 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include "prototypes.h"
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
extern char **environ;
|
||||
|
||||
#ifdef HAVE_SETGROUPS
|
||||
@@ -54,7 +57,6 @@ static void usage (void);
|
||||
/*
|
||||
* usage - print command usage message
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
if (is_newgrp)
|
||||
@@ -67,7 +69,6 @@ static void usage (void)
|
||||
* find_matching_group - search all groups of a given group id for
|
||||
* membership of a given username
|
||||
*/
|
||||
|
||||
static struct group *find_matching_group (const char *name, gid_t gid)
|
||||
{
|
||||
struct group *gr;
|
||||
@@ -79,6 +80,7 @@ static struct group *find_matching_group (const char *name, gid_t gid)
|
||||
if (gr->gr_gid != gid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* A group with matching GID was found.
|
||||
* Test for membership of 'name'.
|
||||
@@ -95,7 +97,6 @@ static struct group *find_matching_group (const char *name, gid_t gid)
|
||||
/*
|
||||
* newgrp - change the invokers current real and effective group id
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int initflag = 0;
|
||||
@@ -144,7 +145,6 @@ 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]);
|
||||
is_newgrp = (strcmp (Prog, "newgrp") == 0);
|
||||
OPENLOG (is_newgrp ? "newgrp" : "sg");
|
||||
@@ -180,7 +180,6 @@ int main (int argc, char **argv)
|
||||
* sg [-]
|
||||
* sg [-] groupid [[-c command]
|
||||
*/
|
||||
|
||||
if (argc > 0 && (!strcmp (argv[0], "-") || !strcmp (argv[0], "-l"))) {
|
||||
argc--;
|
||||
argv++;
|
||||
@@ -191,7 +190,6 @@ int main (int argc, char **argv)
|
||||
* Do the command line for everything that is
|
||||
* not "newgrp".
|
||||
*/
|
||||
|
||||
if (argc > 0 && argv[0][0] != '-') {
|
||||
group = argv[0];
|
||||
argc--;
|
||||
@@ -208,7 +206,6 @@ int main (int argc, char **argv)
|
||||
* "sg group -c command" (as in the man page) or
|
||||
* "sg group command" (as in the usage message).
|
||||
*/
|
||||
|
||||
if (argc > 1 && strcmp (argv[0], "-c") == 0)
|
||||
command = argv[1];
|
||||
else
|
||||
@@ -216,19 +213,16 @@ int main (int argc, char **argv)
|
||||
cflag++;
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Do the command line for "newgrp". It's just making sure
|
||||
* there aren't any flags and getting the new group name.
|
||||
*/
|
||||
|
||||
if (argc > 0 && argv[0][0] == '-') {
|
||||
usage ();
|
||||
goto failure;
|
||||
} else if (argv[0] != (char *) 0) {
|
||||
group = argv[0];
|
||||
} else {
|
||||
|
||||
/*
|
||||
* get the group file entry for her login group id.
|
||||
* the entry must exist, simply to be annoying.
|
||||
@@ -236,7 +230,6 @@ int main (int argc, char **argv)
|
||||
* Perhaps in the past, but the default behavior now depends on the
|
||||
* group entry, so it had better exist. -- JWP
|
||||
*/
|
||||
|
||||
if (!(grp = getgrgid (pwd->pw_gid))) {
|
||||
fprintf (stderr, _("unknown GID: %lu\n"),
|
||||
(unsigned long) pwd->pw_gid);
|
||||
@@ -255,7 +248,6 @@ int main (int argc, char **argv)
|
||||
* nasty message but at least your real and effective group id's are
|
||||
* set.
|
||||
*/
|
||||
|
||||
/* don't use getgroups(0, 0) - it doesn't work on some systems */
|
||||
i = 16;
|
||||
for (;;) {
|
||||
@@ -313,7 +305,6 @@ int main (int argc, char **argv)
|
||||
* including the user's name in the member list of the user's login
|
||||
* group. -- JWP
|
||||
*/
|
||||
|
||||
if (!(grp = getgrnam (group))) {
|
||||
fprintf (stderr, _("unknown group: %s\n"), group);
|
||||
goto failure;
|
||||
@@ -348,7 +339,6 @@ int main (int argc, char **argv)
|
||||
* password, she will be denied access anyway.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!is_on_list (grp->gr_mem, name))
|
||||
needspasswd = 1;
|
||||
|
||||
@@ -357,7 +347,6 @@ int main (int argc, char **argv)
|
||||
* password, and the group has a password, she needs to give the
|
||||
* group password.
|
||||
*/
|
||||
|
||||
if ((spwd = getspnam (name)))
|
||||
pwd->pw_passwd = spwd->sp_pwdp;
|
||||
|
||||
@@ -373,14 +362,11 @@ int main (int argc, char **argv)
|
||||
* Note that she now has to provide the password to her own group,
|
||||
* unless she is listed as a member. -- JWP
|
||||
*/
|
||||
|
||||
if (getuid () != 0 && needspasswd) {
|
||||
|
||||
/*
|
||||
* get the password from her, and set the salt for
|
||||
* the decryption from the group file.
|
||||
*/
|
||||
|
||||
if (!(cp = getpass (_("Password: "))))
|
||||
goto failure;
|
||||
|
||||
@@ -389,7 +375,6 @@ int main (int argc, char **argv)
|
||||
* password in the group file. The result of this encryption
|
||||
* must match the previously encrypted value in the file.
|
||||
*/
|
||||
|
||||
cpasswd = pw_encrypt (cp, grp->gr_passwd);
|
||||
strzero (cp);
|
||||
|
||||
@@ -416,7 +401,6 @@ 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 ((LOG_INFO, "user `%s' switched to group `%s'",
|
||||
@@ -467,14 +451,24 @@ int main (int argc, char **argv)
|
||||
child = fork ();
|
||||
if (child < 0) {
|
||||
/* error in fork() */
|
||||
fprintf (stderr, "%s: failure forking: %s",
|
||||
fprintf (stderr, _("%s: failure forking: %s"),
|
||||
is_newgrp ? "newgrp" : "sg", strerror (errno));
|
||||
exit (1);
|
||||
} else if (child) {
|
||||
/* parent - wait for child to finish, then log session close */
|
||||
int cst = 0;
|
||||
|
||||
do {
|
||||
pid = waitpid (child, NULL, 0);
|
||||
} while (pid != child);
|
||||
errno = 0;
|
||||
pid = waitpid (child, &cst, WUNTRACED);
|
||||
if (pid == child && WIFSTOPPED (cst)) {
|
||||
/* stop when child stops */
|
||||
raise (SIGSTOP);
|
||||
/* wake child when resumed */
|
||||
kill (child, SIGCONT);
|
||||
}
|
||||
} while (pid == child && WIFSTOPPED (cst) ||
|
||||
pid != child && errno == EINTR);
|
||||
SYSLOG ((LOG_INFO,
|
||||
"user `%s' (login `%s' on %s) returned to group `%s'",
|
||||
name, loginname, tty,
|
||||
@@ -482,6 +476,7 @@ int main (int argc, char **argv)
|
||||
closelog ();
|
||||
exit (0);
|
||||
}
|
||||
|
||||
/* child - restore signals to their default state */
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGQUIT, SIG_DFL);
|
||||
@@ -502,7 +497,6 @@ int main (int argc, char **argv)
|
||||
* If the group doesn't fit, i'll complain loudly and skip this
|
||||
* part.
|
||||
*/
|
||||
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
if (gid == grouplist[i])
|
||||
break;
|
||||
@@ -524,7 +518,6 @@ int main (int argc, char **argv)
|
||||
* to the real UID. For root, this also sets the real GID to the
|
||||
* new group id.
|
||||
*/
|
||||
|
||||
if (setgid (gid))
|
||||
perror ("setgid");
|
||||
|
||||
@@ -537,7 +530,6 @@ int main (int argc, char **argv)
|
||||
* See if the "-c" flag was used. If it was, i just create a shell
|
||||
* command for her using the argument that followed the "-c" flag.
|
||||
*/
|
||||
|
||||
if (cflag) {
|
||||
closelog ();
|
||||
execl ("/bin/sh", "sh", "-c", command, (char *) 0);
|
||||
@@ -567,7 +559,6 @@ int main (int argc, char **argv)
|
||||
* problem, try using $SHELL as a workaround; also please notify me
|
||||
* at jparmele@wildbear.com -- JWP
|
||||
*/
|
||||
|
||||
if (!initflag && (cp = getenv ("SHELL")))
|
||||
prog = cp;
|
||||
else if (pwd->pw_shell && pwd->pw_shell[0])
|
||||
@@ -579,7 +570,6 @@ int main (int argc, char **argv)
|
||||
* Now i try to find the basename of the login shell. This will
|
||||
* become argv[0] of the spawned command.
|
||||
*/
|
||||
|
||||
cp = Basename ((char *) prog);
|
||||
|
||||
endspent ();
|
||||
@@ -593,7 +583,6 @@ int main (int argc, char **argv)
|
||||
* Switch back to her home directory if i am doing login
|
||||
* initialization.
|
||||
*/
|
||||
|
||||
if (initflag) {
|
||||
if (chdir (pwd->pw_dir))
|
||||
perror ("chdir");
|
||||
@@ -616,7 +605,6 @@ int main (int argc, char **argv)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
shell (prog, initflag ? (char *) 0 : cp);
|
||||
/* NOTREACHED */
|
||||
failure:
|
||||
@@ -631,7 +619,6 @@ int main (int argc, char **argv)
|
||||
* process. The closelog is probably unnecessary, but it does no
|
||||
* harm. -- JWP
|
||||
*/
|
||||
|
||||
closelog ();
|
||||
exit (1);
|
||||
}
|
||||
|
@@ -35,12 +35,10 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: newusers.c,v 1.26 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#ident "$Id: newusers.c,v 1.30 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
@@ -49,13 +47,16 @@ RCSID (PKG_VER "$Id: newusers.c,v 1.26 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#endif /* USE_PAM */
|
||||
static char *Prog;
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "pwio.h"
|
||||
#include "groupio.h"
|
||||
|
||||
#include "shadowio.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *Prog;
|
||||
|
||||
static int is_shadow;
|
||||
|
||||
@@ -69,7 +70,6 @@ static int add_passwd (struct passwd *, const char *);
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [input]\n"), Prog);
|
||||
@@ -79,7 +79,6 @@ static void usage (void)
|
||||
/*
|
||||
* add_group - create a new group or add a user to an existing group
|
||||
*/
|
||||
|
||||
static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
{
|
||||
const struct passwd *pwd;
|
||||
@@ -92,7 +91,6 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
* Start by seeing if the named group already exists. This will be
|
||||
* very easy to deal with if it does.
|
||||
*/
|
||||
|
||||
if ((grp = gr_locate (gid))) {
|
||||
add_member:
|
||||
grent = *grp;
|
||||
@@ -115,7 +113,6 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
* out the GID from the password file. I want the UID and GID to
|
||||
* match, unless the GID is already used.
|
||||
*/
|
||||
|
||||
if (gid[0] == '\0') {
|
||||
i = 100;
|
||||
for (pw_rewind (); (pwd = pw_next ());) {
|
||||
@@ -129,13 +126,11 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
}
|
||||
}
|
||||
} else if (gid[0] >= '0' && gid[0] <= '9') {
|
||||
|
||||
/*
|
||||
* The GID is a number, which means either this is a brand
|
||||
* new group, or an existing group. For existing groups I
|
||||
* just add myself as a member, just like I did earlier.
|
||||
*/
|
||||
|
||||
i = atoi (gid);
|
||||
for (gr_rewind (); (grp = gr_next ());)
|
||||
if (grp->gr_gid == i)
|
||||
@@ -147,13 +142,11 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
* figure out what group ID that group name is going to
|
||||
* have.
|
||||
*/
|
||||
|
||||
i = -1;
|
||||
|
||||
/*
|
||||
* If I don't have a group ID by now, I'll go get the next one.
|
||||
*/
|
||||
|
||||
if (i == -1) {
|
||||
for (i = 100, gr_rewind (); (grp = gr_next ());)
|
||||
if (grp->gr_gid >= i)
|
||||
@@ -163,7 +156,6 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
/*
|
||||
* Now I have all of the fields required to create the new group.
|
||||
*/
|
||||
|
||||
if (gid[0] && (gid[0] <= '0' || gid[0] >= '9'))
|
||||
grent.gr_name = xstrdup (gid);
|
||||
else
|
||||
@@ -182,7 +174,6 @@ static int add_group (const char *name, const char *gid, gid_t * ngid)
|
||||
/*
|
||||
* add_user - create a new user ID
|
||||
*/
|
||||
|
||||
static int add_user (const char *name, const char *uid, uid_t * nuid, gid_t gid)
|
||||
{
|
||||
const struct passwd *pwd;
|
||||
@@ -193,7 +184,6 @@ static int add_user (const char *name, const char *uid, uid_t * nuid, gid_t gid)
|
||||
* The first guess for the UID is either the numerical UID that the
|
||||
* caller provided, or the next available UID.
|
||||
*/
|
||||
|
||||
if (uid[0] >= '0' && uid[0] <= '9') {
|
||||
i = atoi (uid);
|
||||
} else if (uid[0] && (pwd = pw_locate (uid))) {
|
||||
@@ -210,7 +200,6 @@ static int add_user (const char *name, const char *uid, uid_t * nuid, gid_t gid)
|
||||
* JUST YET, since there is still more data to be added. So, I fill
|
||||
* in the parts that I have.
|
||||
*/
|
||||
|
||||
pwent.pw_name = xstrdup (name);
|
||||
pwent.pw_passwd = "x"; /* XXX warning: const */
|
||||
pwent.pw_uid = i;
|
||||
@@ -231,7 +220,6 @@ static void update_passwd (struct passwd *pwd, const char *passwd)
|
||||
/*
|
||||
* add_passwd - add or update the encrypted password
|
||||
*/
|
||||
|
||||
static int add_passwd (struct passwd *pwd, const char *passwd)
|
||||
{
|
||||
const struct spwd *sp;
|
||||
@@ -242,16 +230,15 @@ static int add_passwd (struct passwd *pwd, const char *passwd)
|
||||
* points to the entry in the password file. Shadow files are
|
||||
* harder since there are zillions of things to do ...
|
||||
*/
|
||||
|
||||
if (!is_shadow) {
|
||||
update_passwd (pwd, passwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the first and easiest shadow file case. The user already
|
||||
* exists in the shadow password file.
|
||||
*/
|
||||
|
||||
if ((sp = spw_locate (pwd->pw_name))) {
|
||||
spent = *sp;
|
||||
spent.sp_pwdp = pw_encrypt (passwd, crypt_make_salt ());
|
||||
@@ -264,7 +251,6 @@ static int add_passwd (struct passwd *pwd, const char *passwd)
|
||||
* when the entry was created, so this user would have to have had
|
||||
* the password set someplace else.
|
||||
*/
|
||||
|
||||
if (strcmp (pwd->pw_passwd, "x") != 0) {
|
||||
update_passwd (pwd, passwd);
|
||||
return 0;
|
||||
@@ -274,7 +260,6 @@ static int add_passwd (struct passwd *pwd, const char *passwd)
|
||||
* Now the really hard case - I need to create an entirely new
|
||||
* shadow password file entry.
|
||||
*/
|
||||
|
||||
spent.sp_namp = pwd->pw_name;
|
||||
spent.sp_pwdp = pw_encrypt (passwd, crypt_make_salt ());
|
||||
spent.sp_lstchg = time ((time_t *) 0) / SCALE;
|
||||
@@ -370,7 +355,6 @@ int main (int argc, char **argv)
|
||||
* modified, or new entries added. The password file is the key - if
|
||||
* it gets locked, assume the others can be locked right away.
|
||||
*/
|
||||
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr, _("%s: can't lock /etc/passwd.\n"), Prog);
|
||||
exit (1);
|
||||
@@ -404,7 +388,6 @@ int main (int argc, char **argv)
|
||||
* over 100 is allocated. The pw_gid field will be updated with that
|
||||
* value.
|
||||
*/
|
||||
|
||||
while (fgets (buf, sizeof buf, stdin) != (char *) 0) {
|
||||
line++;
|
||||
if ((cp = strrchr (buf, '\n'))) {
|
||||
@@ -421,7 +404,6 @@ int main (int argc, char **argv)
|
||||
* There MUST be 7 colon separated fields, although the
|
||||
* values aren't that particular.
|
||||
*/
|
||||
|
||||
for (cp = buf, nfields = 0; nfields < 7; nfields++) {
|
||||
fields[nfields] = cp;
|
||||
if ((cp = strchr (cp, ':')))
|
||||
@@ -445,7 +427,6 @@ int main (int argc, char **argv)
|
||||
* new group, if that group ID exists, a whole new group ID
|
||||
* will be made up.
|
||||
*/
|
||||
|
||||
if (!(pw = pw_locate (fields[0])) &&
|
||||
add_group (fields[0], fields[3], &gid)) {
|
||||
fprintf (stderr,
|
||||
@@ -462,7 +443,6 @@ int main (int argc, char **argv)
|
||||
* available user ID is computed and used. After this there
|
||||
* will at least be a (struct passwd) for the user.
|
||||
*/
|
||||
|
||||
if (!pw && add_user (fields[0], fields[2], &uid, gid)) {
|
||||
fprintf (stderr,
|
||||
_("%s: line %d: can't create UID\n"),
|
||||
@@ -475,7 +455,6 @@ int main (int argc, char **argv)
|
||||
* The password, gecos field, directory, and shell fields
|
||||
* all come next.
|
||||
*/
|
||||
|
||||
if (!(pw = pw_locate (fields[0]))) {
|
||||
fprintf (stderr,
|
||||
_("%s: line %d: cannot find user %s\n"),
|
||||
@@ -517,7 +496,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Update the password entry with the new changes made.
|
||||
*/
|
||||
|
||||
if (!pw_update (&newpw)) {
|
||||
fprintf (stderr,
|
||||
_("%s: line %d: can't update entry\n"),
|
||||
@@ -534,7 +512,6 @@ int main (int argc, char **argv)
|
||||
* changes to be written out all at once, and then unlocked
|
||||
* afterwards.
|
||||
*/
|
||||
|
||||
if (errors) {
|
||||
fprintf (stderr,
|
||||
_("%s: error detected, changes ignored\n"), Prog);
|
||||
@@ -562,18 +539,6 @@ int main (int argc, char **argv)
|
||||
(void) pw_unlock ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
294
src/passwd.c
294
src/passwd.c
@@ -29,16 +29,27 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: passwd.c,v 1.44 2005/08/03 16:00:46 kloczek Exp $")
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#ident "$Id: passwd.c,v 1.52 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef WITH_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/av_permissions.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#ifndef GPASSWD_PROGRAM
|
||||
#define GPASSWD_PROGRAM "gpasswd"
|
||||
#endif
|
||||
@@ -48,16 +59,6 @@ RCSID (PKG_VER "$Id: passwd.c,v 1.44 2005/08/03 16:00:46 kloczek Exp $")
|
||||
#ifndef CHSH_PROGRAM
|
||||
#define CHSH_PROGRAM "chsh"
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include "pwauth.h"
|
||||
#include "shadowio.h"
|
||||
#include "pwio.h"
|
||||
#include "nscd.h"
|
||||
#include "getdef.h"
|
||||
#ifdef WITH_SELINUX
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/av_permissions.h>
|
||||
#endif
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
@@ -77,18 +78,18 @@ static char *Prog; /* Program name */
|
||||
static int amroot; /* The real UID was 0 */
|
||||
|
||||
static int
|
||||
eflg = 0, /* -e - force password change */
|
||||
aflg = 0, /* -a - show status for all users */
|
||||
dflg = 0, /* -d - delete password */
|
||||
eflg = 0, /* -e - force password change */
|
||||
iflg = 0, /* -i - set inactive days */
|
||||
kflg = 0, /* -k - change only if expired */
|
||||
nflg = 0, /* -n - set minimum days */
|
||||
wflg = 0, /* -w - set warning days */
|
||||
xflg = 0, /* -x - set maximum days */
|
||||
aflg = 0, /* -a - show status for all users */
|
||||
dflg = 0, /* -d - delete password */
|
||||
lflg = 0, /* -l - lock account */
|
||||
nflg = 0, /* -n - set minimum days */
|
||||
qflg = 0, /* -q - quiet mode */
|
||||
Sflg = 0, /* -S - show password status */
|
||||
uflg = 0; /* -u - unlock account */
|
||||
uflg = 0, /* -u - unlock account */
|
||||
wflg = 0, /* -w - set warning days */
|
||||
xflg = 0; /* -x - set maximum days */
|
||||
|
||||
/*
|
||||
* set to 1 if there are any flags which require root privileges,
|
||||
@@ -136,17 +137,28 @@ static long getnumber (const char *);
|
||||
/*
|
||||
* usage - print command usage and exit
|
||||
*/
|
||||
|
||||
static void usage (int status)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-f|-s] [name]\n"), Prog);
|
||||
if (amroot) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
(" %s [-x max] [-n min] [-w warn] [-i inact] name\n"),
|
||||
Prog);
|
||||
fprintf (stderr, _(" %s {-l|-u|-d|-S|-e} name\n"), Prog);
|
||||
}
|
||||
fprintf (stderr, _("Usage: passwd [options] [login]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -a, --all report password status on all accounts\n"
|
||||
" -d, --delete delete the password for the named account\n"
|
||||
" -e, --expire force expire the password for the named account\n"
|
||||
" -h, --help display this help message and exit\n"
|
||||
" -k, --keep-tokens change password only if expired\n"
|
||||
" -i, --inactive INACTIVE set password inactive after expiration\n"
|
||||
" to INACTIVE\n"
|
||||
" -l, --lock lock the named account\n"
|
||||
" -n, --mindays MIN_DAYS set minimum number of days before password\n"
|
||||
" change to MIN_DAYS\n"
|
||||
" -q, --quiet quiet mode\n"
|
||||
" -r, --repository REPOSITORY change password in REPOSITORY repository\n"
|
||||
" -S, --status report password status on the named account\n"
|
||||
" -u, --unlock unlock the named account\n"
|
||||
" -w, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"
|
||||
" -x, --maxdays MAX_DAYS set maximim number of days before password\n"
|
||||
" change to MAX_DAYS\n"));
|
||||
exit (status);
|
||||
}
|
||||
|
||||
@@ -177,8 +189,7 @@ static int reuse (const char *pass, const struct passwd *pw)
|
||||
* new_password - validate old password and replace with new (both old and
|
||||
* new in global "char crypt_passwd[128]")
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/ static int new_password (const struct passwd *pw)
|
||||
static int new_password (const struct passwd *pw)
|
||||
{
|
||||
char *clear; /* Pointer to clear text */
|
||||
char *cipher; /* Pointer to cipher text */
|
||||
@@ -204,11 +215,11 @@ static int reuse (const char *pass, const struct passwd *pw)
|
||||
|
||||
cipher = pw_encrypt (clear, crypt_passwd);
|
||||
if (strcmp (cipher, crypt_passwd) != 0) {
|
||||
SYSLOG ((LOG_WARN, "incorrect password for `%s'",
|
||||
SYSLOG ((LOG_WARN, "incorrect password for %s",
|
||||
pw->pw_name));
|
||||
sleep (1);
|
||||
fprintf (stderr,
|
||||
_("Incorrect password for `%s'\n"),
|
||||
_("Incorrect password for %s.\n"),
|
||||
pw->pw_name);
|
||||
return -1;
|
||||
}
|
||||
@@ -225,7 +236,6 @@ static int reuse (const char *pass, const struct passwd *pw)
|
||||
* for strength, unless it is the root user. This provides an escape
|
||||
* for initial login passwords.
|
||||
*/
|
||||
|
||||
if (getdef_bool ("MD5_CRYPT_ENAB"))
|
||||
pass_max_len = 127;
|
||||
else
|
||||
@@ -251,6 +261,7 @@ Please use a combination of upper and lower case letters and numbers.\n"), getde
|
||||
printf (_("Try again.\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If enabled, warn about weak passwords even if you are
|
||||
* root (enter this password again to use it anyway).
|
||||
@@ -284,7 +295,6 @@ Please use a combination of upper and lower case letters and numbers.\n"), getde
|
||||
/*
|
||||
* Encrypt the password, then wipe the cleartext password.
|
||||
*/
|
||||
|
||||
cp = pw_encrypt (pass, crypt_make_salt ());
|
||||
memzero (pass, sizeof pass);
|
||||
|
||||
@@ -301,7 +311,6 @@ Please use a combination of upper and lower case letters and numbers.\n"), getde
|
||||
* check_password() sees if the invoker has permission to change the
|
||||
* password for the given user.
|
||||
*/
|
||||
|
||||
static void check_password (const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
time_t now, last, ok;
|
||||
@@ -319,7 +328,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
|
||||
/*
|
||||
* Root can change any password any time.
|
||||
*/
|
||||
|
||||
if (amroot)
|
||||
return;
|
||||
|
||||
@@ -331,7 +339,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
|
||||
* changed. Passwords which have been inactive too long cannot be
|
||||
* changed.
|
||||
*/
|
||||
|
||||
if (sp->sp_pwdp[0] == '!' || exp_status > 1 ||
|
||||
(sp->sp_max >= 0 && sp->sp_min > sp->sp_max)) {
|
||||
fprintf (stderr,
|
||||
@@ -345,7 +352,6 @@ static void check_password (const struct passwd *pw, const struct spwd *sp)
|
||||
/*
|
||||
* Passwords may only be changed after sp_min time is up.
|
||||
*/
|
||||
|
||||
last = sp->sp_lstchg * SCALE;
|
||||
ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0);
|
||||
|
||||
@@ -397,7 +403,6 @@ static const char *pw_status (const char *pass)
|
||||
/*
|
||||
* print_status - print current password status
|
||||
*/
|
||||
|
||||
static void print_status (const struct passwd *pw)
|
||||
{
|
||||
struct spwd *sp;
|
||||
@@ -534,6 +539,7 @@ static void update_shadow (void)
|
||||
nsp->sp_inact = (inact * DAY) / SCALE;
|
||||
if (do_update_age)
|
||||
nsp->sp_lstchg = time ((time_t *) 0) / SCALE;
|
||||
|
||||
/*
|
||||
* Force change on next login, like SunOS 4.x passwd -e or Solaris
|
||||
* 2.x passwd -f. Solaris 2.x seems to do the same thing (set
|
||||
@@ -574,19 +580,20 @@ static long getnumber (const char *str)
|
||||
*
|
||||
* The valid options are
|
||||
*
|
||||
* -l lock the named account (*)
|
||||
* -u unlock the named account (*)
|
||||
* -d delete the password for the named account (*)
|
||||
* -e expire the password for the named account (*)
|
||||
* -x # set sp_max to # days (*)
|
||||
* -n # set sp_min to # days (*)
|
||||
* -w # set sp_warn to # days (*)
|
||||
* -i # set sp_inact to # days (*)
|
||||
* -S show password status of named account
|
||||
* -g execute gpasswd command to interpret flags
|
||||
* -f execute chfn command to interpret flags
|
||||
* -s execute chsh 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 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 named account (*)
|
||||
* -w # set sp_warn to # days (*)
|
||||
* -x # set sp_max to # days (*)
|
||||
*
|
||||
* (*) requires root permission to execute.
|
||||
*
|
||||
@@ -594,7 +601,6 @@ static long getnumber (const char *str)
|
||||
* appropriate internal format. For finer resolute the chage
|
||||
* command must be used.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int flag; /* Current option to process */
|
||||
@@ -634,7 +640,6 @@ int main (int argc, char **argv)
|
||||
* These flags are deprecated, may change in a future release.
|
||||
* Please run these programs directly. --marekm
|
||||
*/
|
||||
|
||||
if (argc > 1 && argv[1][0] == '-' && strchr ("gfs", argv[1][1])) {
|
||||
char buf[200];
|
||||
|
||||
@@ -661,81 +666,99 @@ int main (int argc, char **argv)
|
||||
exit (E_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* The remaining arguments will be processed one by one and executed
|
||||
* by this command. The name is the last argument if it does not
|
||||
* begin with a "-", otherwise the name is determined from the
|
||||
* environment and must agree with the real UID. Also, the UID will
|
||||
* be checked for any commands which are restricted to root only.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Parse the command line options.
|
||||
*/
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"all", no_argument, NULL, 'a'},
|
||||
{"delete", no_argument, NULL, 'd'},
|
||||
{"expire", no_argument, NULL, 'e'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"inactive", required_argument, NULL, 'i'},
|
||||
{"keep-tokens", no_argument, NULL, 'k'},
|
||||
{"lock", no_argument, NULL, 'l'},
|
||||
{"mindays", required_argument, NULL, 'n'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"repository", required_argument, NULL, 'r'},
|
||||
{"status", no_argument, NULL, 'S'},
|
||||
{"unlock", no_argument, NULL, 'u'},
|
||||
{"warning", required_argument, NULL, 'w'},
|
||||
{"maxdays", required_argument, NULL, 'x'},
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
|
||||
while ((flag = getopt (argc, argv, "adei:kln:qr:Suw:x:")) != EOF) {
|
||||
switch (flag) {
|
||||
case 'a':
|
||||
aflg++;
|
||||
break;
|
||||
case 'd':
|
||||
dflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'e':
|
||||
eflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'i':
|
||||
inact = getnumber (optarg);
|
||||
if (inact >= -1)
|
||||
iflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'k':
|
||||
/* change only if expired, like Linux-PAM passwd -k. */
|
||||
kflg++; /* ok for users */
|
||||
break;
|
||||
case 'l':
|
||||
lflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'n':
|
||||
age_min = getnumber (optarg);
|
||||
nflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'q':
|
||||
qflg++; /* ok for users */
|
||||
break;
|
||||
case 'S':
|
||||
Sflg++; /* ok for users */
|
||||
break;
|
||||
case 'u':
|
||||
uflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'w':
|
||||
warn = getnumber (optarg);
|
||||
if (warn >= -1)
|
||||
wflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'r':
|
||||
/* -r repository (files|nis|nisplus) */
|
||||
/* only "files" supported for now */
|
||||
if (strcmp (optarg, "files") != 0) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: repository %s not supported\n"),
|
||||
Prog, optarg);
|
||||
exit (E_BAD_ARG);
|
||||
while ((c =
|
||||
getopt_long (argc, argv, "adei:kln:qr:Suw:x:",
|
||||
long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
aflg++;
|
||||
break;
|
||||
case 'd':
|
||||
dflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'e':
|
||||
eflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'i':
|
||||
inact = getnumber (optarg);
|
||||
if (inact >= -1)
|
||||
iflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'k':
|
||||
/* change only if expired, like Linux-PAM passwd -k. */
|
||||
kflg++; /* ok for users */
|
||||
break;
|
||||
case 'l':
|
||||
lflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'n':
|
||||
age_min = getnumber (optarg);
|
||||
nflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'q':
|
||||
qflg++; /* ok for users */
|
||||
break;
|
||||
case 'r':
|
||||
/* -r repository (files|nis|nisplus) */
|
||||
/* only "files" supported for now */
|
||||
if (strcmp (optarg, "files") != 0) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: repository %s not supported\n"),
|
||||
Prog, optarg);
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
Sflg++; /* ok for users */
|
||||
break;
|
||||
case 'u':
|
||||
uflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'w':
|
||||
warn = getnumber (optarg);
|
||||
if (warn >= -1)
|
||||
wflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
case 'x':
|
||||
age_max = getnumber (optarg);
|
||||
xflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage (E_BAD_ARG);
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
age_max = getnumber (optarg);
|
||||
xflg++;
|
||||
anyflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage (E_BAD_ARG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,7 +767,6 @@ int main (int argc, char **argv)
|
||||
* command line if possible. Otherwise it is figured out from the
|
||||
* environment.
|
||||
*/
|
||||
|
||||
pw = get_my_pwent ();
|
||||
if (!pw) {
|
||||
fprintf (stderr,
|
||||
@@ -761,7 +783,6 @@ int main (int argc, char **argv)
|
||||
* The -a flag requires -S, no other flags, no username, and
|
||||
* you must be root. --marekm
|
||||
*/
|
||||
|
||||
if (aflg) {
|
||||
if (anyflag || !Sflg || (optind < argc))
|
||||
usage (E_USAGE);
|
||||
@@ -794,7 +815,6 @@ int main (int argc, char **argv)
|
||||
* -S now ok for normal users (check status of my own account), and
|
||||
* doesn't require username. --marekm
|
||||
*/
|
||||
|
||||
if (anyflag && optind >= argc)
|
||||
usage (E_USAGE);
|
||||
|
||||
@@ -817,7 +837,7 @@ int main (int argc, char **argv)
|
||||
* check if the change is allowed by SELinux policy.
|
||||
*/
|
||||
if ((pw->pw_uid != getuid ())
|
||||
&& (checkPasswdAccess (PASSWD__PASSWD) != 0)) {
|
||||
&& (selinux_check_passwd_access (PASSWD__PASSWD) != 0)) {
|
||||
#else
|
||||
/*
|
||||
* If the UID of the user does not match the current real UID,
|
||||
@@ -844,7 +864,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* The user name is valid, so let's get the shadow file entry.
|
||||
*/
|
||||
|
||||
sp = getspnam (name);
|
||||
if (!sp)
|
||||
sp = pwd_to_spwd (pw);
|
||||
@@ -854,7 +873,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* If there are no other flags, just change the password.
|
||||
*/
|
||||
|
||||
if (!anyflag) {
|
||||
STRFCPY (crypt_passwd, cp);
|
||||
|
||||
@@ -862,7 +880,6 @@ int main (int argc, char **argv)
|
||||
* See if the user is permitted to change the password.
|
||||
* Otherwise, go ahead and set a new password.
|
||||
*/
|
||||
|
||||
check_password (pw, sp);
|
||||
|
||||
/*
|
||||
@@ -888,13 +905,12 @@ int main (int argc, char **argv)
|
||||
* against unexpected signals. Any keyboard signals are set to be
|
||||
* ignored.
|
||||
*/
|
||||
|
||||
pwd_init ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
/*
|
||||
* Don't set the real UID for PAM...
|
||||
*/
|
||||
#ifdef USE_PAM
|
||||
if (!anyflag) {
|
||||
do_pam_passwd (name, qflg, kflg);
|
||||
exit (E_SUCCESS);
|
||||
|
66
src/pwck.c
66
src/pwck.c
@@ -29,21 +29,21 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: pwck.c,v 1.29 2005/08/09 15:27:02 kloczek Exp $")
|
||||
#include <stdio.h>
|
||||
#ident "$Id: pwck.c,v 1.32 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include "chkname.h"
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
extern void __pw_del_entry (const struct commonio_entry *);
|
||||
extern struct commonio_entry *__pw_get_head (void);
|
||||
|
||||
#include "shadowio.h"
|
||||
extern void __spw_del_entry (const struct commonio_entry *);
|
||||
extern struct commonio_entry *__spw_get_head (void);
|
||||
|
||||
@@ -59,7 +59,7 @@ extern struct commonio_entry *__spw_get_head (void);
|
||||
#define E_CANTUPDATE 5
|
||||
|
||||
/*
|
||||
* Local variables
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
static char *Prog;
|
||||
@@ -76,7 +76,6 @@ static int yes_or_no (void);
|
||||
/*
|
||||
* usage - print syntax message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-q] [-r] [-s] [passwd [shadow]]\n"),
|
||||
@@ -87,7 +86,6 @@ static void usage (void)
|
||||
/*
|
||||
* yes_or_no - get answer to question from the user
|
||||
*/
|
||||
|
||||
static int yes_or_no (void)
|
||||
{
|
||||
char buf[80];
|
||||
@@ -104,7 +102,6 @@ static int yes_or_no (void)
|
||||
/*
|
||||
* Get a line and see what the first character is.
|
||||
*/
|
||||
|
||||
if (fgets (buf, sizeof buf, stdin))
|
||||
return buf[0] == 'y' || buf[0] == 'Y';
|
||||
|
||||
@@ -114,7 +111,6 @@ static int yes_or_no (void)
|
||||
/*
|
||||
* pwck - verify password file integrity
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int arg;
|
||||
@@ -131,7 +127,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -143,7 +138,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Parse the command line arguments
|
||||
*/
|
||||
|
||||
while ((arg = getopt (argc, argv, "eqrs")) != EOF) {
|
||||
switch (arg) {
|
||||
case 'e': /* added for Debian shadow-961025-2 compatibility */
|
||||
@@ -169,7 +163,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make certain we have the right number of arguments
|
||||
*/
|
||||
|
||||
if (optind != argc && optind + 1 != argc && optind + 2 != argc)
|
||||
usage ();
|
||||
|
||||
@@ -177,7 +170,6 @@ int main (int argc, char **argv)
|
||||
* If there are two left over filenames, use those as the password
|
||||
* and shadow password filenames.
|
||||
*/
|
||||
|
||||
if (optind != argc) {
|
||||
pwd_file = argv[optind];
|
||||
pw_name (pwd_file);
|
||||
@@ -192,7 +184,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Lock the files if we aren't in "read-only" mode
|
||||
*/
|
||||
|
||||
if (!read_only) {
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr, _("%s: cannot lock file %s\n"),
|
||||
@@ -216,7 +207,6 @@ int main (int argc, char **argv)
|
||||
* Open the files. Use O_RDONLY if we are in read_only mode, O_RDWR
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
if (!pw_open (read_only ? O_RDONLY : O_RDWR)) {
|
||||
fprintf (stderr, _("%s: cannot open file %s\n"),
|
||||
Prog, pwd_file);
|
||||
@@ -244,13 +234,11 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Loop through the entire password file.
|
||||
*/
|
||||
|
||||
for (pfe = __pw_get_head (); pfe; pfe = pfe->next) {
|
||||
/*
|
||||
* If this is a NIS line, skip it. You can't "know" what NIS
|
||||
* is going to do without directly asking NIS ...
|
||||
*/
|
||||
|
||||
if (pfe->line[0] == '+' || pfe->line[0] == '-')
|
||||
continue;
|
||||
|
||||
@@ -259,14 +247,11 @@ int main (int argc, char **argv)
|
||||
* have no (struct passwd) entry because they couldn't be
|
||||
* parsed properly.
|
||||
*/
|
||||
|
||||
if (!pfe->eptr) {
|
||||
|
||||
/*
|
||||
* Tell the user this entire line is bogus and ask
|
||||
* them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("invalid password file entry\n"));
|
||||
printf (_("delete line `%s'? "), pfe->line);
|
||||
errors++;
|
||||
@@ -274,7 +259,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (!yes_or_no ())
|
||||
continue;
|
||||
|
||||
@@ -284,7 +268,6 @@ int main (int argc, char **argv)
|
||||
* list. When done, it skips back to the top of the
|
||||
* loop to try out the next list element.
|
||||
*/
|
||||
|
||||
delete_pw:
|
||||
SYSLOG ((LOG_INFO, "delete passwd line `%s'",
|
||||
pfe->line));
|
||||
@@ -297,27 +280,23 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Password structure is good, start using it.
|
||||
*/
|
||||
|
||||
pwd = pfe->eptr;
|
||||
|
||||
/*
|
||||
* Make sure this entry has a unique name.
|
||||
*/
|
||||
|
||||
for (tpfe = __pw_get_head (); tpfe; tpfe = tpfe->next) {
|
||||
const struct passwd *ent = tpfe->eptr;
|
||||
|
||||
/*
|
||||
* Don't check this entry
|
||||
*/
|
||||
|
||||
if (tpfe == pfe)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't check invalid entries.
|
||||
*/
|
||||
|
||||
if (!ent)
|
||||
continue;
|
||||
|
||||
@@ -328,7 +307,6 @@ int main (int argc, char **argv)
|
||||
* Tell the user this entry is a duplicate of
|
||||
* another and ask them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("duplicate password entry\n"));
|
||||
printf (_("delete line `%s'? "), pfe->line);
|
||||
errors++;
|
||||
@@ -336,7 +314,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (yes_or_no ())
|
||||
goto delete_pw;
|
||||
}
|
||||
@@ -352,7 +329,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure the primary group exists
|
||||
*/
|
||||
|
||||
if (!quiet && !getgrgid (pwd->pw_gid)) {
|
||||
|
||||
/*
|
||||
@@ -367,13 +343,10 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure the home directory exists
|
||||
*/
|
||||
|
||||
if (!quiet && access (pwd->pw_dir, F_OK)) {
|
||||
|
||||
/*
|
||||
* Home directory doesn't exist, give a warning
|
||||
*/
|
||||
|
||||
printf (_
|
||||
("user %s: directory %s does not exist\n"),
|
||||
pwd->pw_name, pwd->pw_dir);
|
||||
@@ -383,14 +356,12 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Make sure the login shell is executable
|
||||
*/
|
||||
|
||||
if (!quiet && pwd->pw_shell[0]
|
||||
&& access (pwd->pw_shell, F_OK)) {
|
||||
|
||||
/*
|
||||
* Login shell doesn't exist, give a warning
|
||||
*/
|
||||
|
||||
printf (_("user %s: program %s does not exist\n"),
|
||||
pwd->pw_name, pwd->pw_shell);
|
||||
errors++;
|
||||
@@ -403,13 +374,11 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Loop through the entire shadow password file.
|
||||
*/
|
||||
|
||||
for (spe = __spw_get_head (); spe; spe = spe->next) {
|
||||
/*
|
||||
* If this is a NIS line, skip it. You can't "know" what NIS
|
||||
* is going to do without directly asking NIS ...
|
||||
*/
|
||||
|
||||
if (spe->line[0] == '+' || spe->line[0] == '-')
|
||||
continue;
|
||||
|
||||
@@ -418,14 +387,11 @@ int main (int argc, char **argv)
|
||||
* have no (struct spwd) entry because they couldn't be
|
||||
* parsed properly.
|
||||
*/
|
||||
|
||||
if (!spe->eptr) {
|
||||
|
||||
/*
|
||||
* Tell the user this entire line is bogus and ask
|
||||
* them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("invalid shadow password file entry\n"));
|
||||
printf (_("delete line `%s'? "), spe->line);
|
||||
errors++;
|
||||
@@ -433,7 +399,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (!yes_or_no ())
|
||||
continue;
|
||||
|
||||
@@ -443,7 +408,6 @@ int main (int argc, char **argv)
|
||||
* When done, it skips back to the top of the loop
|
||||
* to try out the next list element.
|
||||
*/
|
||||
|
||||
delete_spw:
|
||||
SYSLOG ((LOG_INFO, "delete shadow line `%s'",
|
||||
spe->line));
|
||||
@@ -456,27 +420,23 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Shadow password structure is good, start using it.
|
||||
*/
|
||||
|
||||
spw = spe->eptr;
|
||||
|
||||
/*
|
||||
* Make sure this entry has a unique name.
|
||||
*/
|
||||
|
||||
for (tspe = __spw_get_head (); tspe; tspe = tspe->next) {
|
||||
const struct spwd *ent = tspe->eptr;
|
||||
|
||||
/*
|
||||
* Don't check this entry
|
||||
*/
|
||||
|
||||
if (tspe == spe)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't check invalid entries.
|
||||
*/
|
||||
|
||||
if (!ent)
|
||||
continue;
|
||||
|
||||
@@ -487,7 +447,6 @@ int main (int argc, char **argv)
|
||||
* Tell the user this entry is a duplicate of
|
||||
* another and ask them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("duplicate shadow password entry\n"));
|
||||
printf (_("delete line `%s'? "), spe->line);
|
||||
errors++;
|
||||
@@ -495,7 +454,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (yes_or_no ())
|
||||
goto delete_spw;
|
||||
}
|
||||
@@ -504,14 +462,11 @@ int main (int argc, char **argv)
|
||||
* Make sure this entry exists in the /etc/passwd
|
||||
* file.
|
||||
*/
|
||||
|
||||
if (!pw_locate (spw->sp_namp)) {
|
||||
|
||||
/*
|
||||
* Tell the user this entry has no matching
|
||||
* /etc/passwd entry and ask them to delete it.
|
||||
*/
|
||||
|
||||
printf (_("no matching password file entry\n"));
|
||||
printf (_("delete line `%s'? "), spe->line);
|
||||
errors++;
|
||||
@@ -519,7 +474,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* prompt the user to delete the entry or not
|
||||
*/
|
||||
|
||||
if (yes_or_no ())
|
||||
goto delete_spw;
|
||||
}
|
||||
@@ -527,7 +481,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Warn if last password change in the future. --marekm
|
||||
*/
|
||||
|
||||
if (!quiet && spw->sp_lstchg > time ((time_t *) 0) / SCALE) {
|
||||
printf (_
|
||||
("user %s: last password change in the future\n"),
|
||||
@@ -542,7 +495,6 @@ int main (int argc, char **argv)
|
||||
* All done. If there were no deletions we can just abandon any
|
||||
* changes to the files.
|
||||
*/
|
||||
|
||||
if (deleted) {
|
||||
write_and_bye:
|
||||
if (!pw_close ()) {
|
||||
@@ -564,7 +516,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Don't be anti-social - unlock the files when you're done.
|
||||
*/
|
||||
|
||||
if (is_shadow)
|
||||
spw_unlock ();
|
||||
(void) pw_unlock ();
|
||||
@@ -574,7 +525,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Tell the user what we did and exit.
|
||||
*/
|
||||
|
||||
if (errors)
|
||||
printf (deleted ?
|
||||
_("%s: the files have been updated\n") :
|
||||
|
18
src/pwconv.c
18
src/pwconv.c
@@ -28,21 +28,21 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: pwconv.c,v 1.18 2005/08/09 15:27:02 kloczek Exp $")
|
||||
#ident "$Id: pwconv.c,v 1.21 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "getdef.h"
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
@@ -53,6 +53,9 @@ RCSID (PKG_VER "$Id: pwconv.c,v 1.18 2005/08/09 15:27:02 kloczek Exp $")
|
||||
#define E_MISSING 4 /* unexpected failure, passwd file missing */
|
||||
#define E_PWDBUSY 5 /* passwd file(s) busy */
|
||||
#define E_BADENTRY 6 /* bad shadow entry */
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static int
|
||||
shadow_locked = 0, passwd_locked = 0;
|
||||
|
||||
@@ -153,6 +156,7 @@ int main (int argc, char **argv)
|
||||
Prog, spent.sp_namp);
|
||||
fail_exit (E_FAILURE);
|
||||
}
|
||||
|
||||
/* remove password from /etc/passwd */
|
||||
pwent = *pw;
|
||||
pwent.pw_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
|
||||
|
@@ -29,22 +29,25 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: pwunconv.c,v 1.18 2005/08/03 16:00:46 kloczek Exp $")
|
||||
#include "defines.h"
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#ident "$Id: pwunconv.c,v 1.21 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "defines.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "nscd.h"
|
||||
char *l64a ();
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static int shadow_locked = 0, passwd_locked = 0;
|
||||
|
||||
char *l64a ();
|
||||
|
||||
/* local function prototypes */
|
||||
static void fail_exit (int);
|
||||
|
||||
@@ -117,7 +120,6 @@ int main (int argc, char **argv)
|
||||
* put into the new file. Otherwise, the days are converted
|
||||
* to weeks and so on.
|
||||
*/
|
||||
|
||||
if (!pw_update (&pwent)) {
|
||||
fprintf (stderr,
|
||||
_("%s: can't update entry for user %s\n"),
|
||||
|
38
src/su.c
38
src/su.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: su.c,v 1.41 2005/08/04 19:13:43 kloczek Exp $")
|
||||
#ident "$Id: su.c,v 1.45 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
@@ -88,7 +88,6 @@ static int iswheel (const char *);
|
||||
* with die() as the signal handler. If signal later calls die() with a
|
||||
* signal number, the terminal modes are then reset.
|
||||
*/
|
||||
|
||||
static RETSIGTYPE die (int killed)
|
||||
{
|
||||
static TERMIO sgtty;
|
||||
@@ -216,7 +215,7 @@ static void run_shell (const char *shellstr, char *args[], int doshell)
|
||||
if (ret != PAM_SUCCESS) {
|
||||
SYSLOG ((LOG_ERR, "pam_close_session: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog, pam_strerror (pamh, ret));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
exit (1);
|
||||
}
|
||||
@@ -247,7 +246,6 @@ static void run_shell (const char *shellstr, char *args[], int doshell)
|
||||
* particular, the argument "-c" will cause the next argument to be
|
||||
* interpreted as a command by the common shell programs.
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char *cp;
|
||||
@@ -283,7 +281,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]);
|
||||
|
||||
OPENLOG ("su");
|
||||
@@ -297,7 +294,6 @@ int main (int argc, char **argv)
|
||||
* Get the tty name. Entries will be logged indicating that the user
|
||||
* tried to change to the named new user from the current terminal.
|
||||
*/
|
||||
|
||||
if (isatty (0) && (cp = ttyname (0))) {
|
||||
if (strncmp (cp, "/dev/", 5) == 0)
|
||||
tty = cp + 5;
|
||||
@@ -321,7 +317,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Process the command line arguments.
|
||||
*/
|
||||
|
||||
argc--;
|
||||
argv++; /* shift out command name */
|
||||
|
||||
@@ -335,7 +330,6 @@ int main (int argc, char **argv)
|
||||
* If a new login is being set up, the old environment will be
|
||||
* ignored and a new one created later on.
|
||||
*/
|
||||
|
||||
if (fakelogin) {
|
||||
/*
|
||||
* The terminal type will be left alone if it is present in
|
||||
@@ -346,11 +340,13 @@ int main (int argc, char **argv)
|
||||
#ifndef USE_PAM
|
||||
if ((cp = getdef_str ("ENV_TZ")))
|
||||
addenv (*cp == '/' ? tz (cp) : cp, NULL);
|
||||
|
||||
/*
|
||||
* The clock frequency will be reset to the login value if required
|
||||
*/
|
||||
if ((cp = getdef_str ("ENV_HZ")))
|
||||
addenv (cp, NULL); /* set the default $HZ, if one */
|
||||
|
||||
/*
|
||||
* Also leave DISPLAY and XAUTHORITY if present, else
|
||||
* pam_xauth will not work.
|
||||
@@ -371,7 +367,6 @@ int main (int argc, char **argv)
|
||||
* doesn't start with a "-" unless you specify the new user name.
|
||||
* Any remaining arguments will be passed to the user's login shell.
|
||||
*/
|
||||
|
||||
if (argc > 0 && argv[0][0] != '-') {
|
||||
STRFCPY (name, argv[0]); /* use this login id */
|
||||
argc--;
|
||||
@@ -386,7 +381,6 @@ int main (int argc, char **argv)
|
||||
* Get the user's real name. The current UID is used to determine
|
||||
* who has executed su. That user ID must exist.
|
||||
*/
|
||||
|
||||
pw = get_my_pwent ();
|
||||
if (!pw) {
|
||||
SYSLOG ((LOG_CRIT, "Unknown UID: %u", my_uid));
|
||||
@@ -420,7 +414,7 @@ int main (int argc, char **argv)
|
||||
if (ret != PAM_SUCCESS) {
|
||||
SYSLOG ((LOG_ERR, "pam_set_item: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog, pam_strerror (pamh, ret));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
exit (1);
|
||||
}
|
||||
@@ -435,7 +429,6 @@ int main (int argc, char **argv)
|
||||
* The password file entries for the user is gotten and the account
|
||||
* validated.
|
||||
*/
|
||||
|
||||
if (!(pw = getpwnam (name))) {
|
||||
(void) fprintf (stderr, _("Unknown id: %s\n"), name);
|
||||
closelog ();
|
||||
@@ -498,7 +491,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Set the default shell.
|
||||
*/
|
||||
|
||||
if (pwent.pw_shell[0] == '\0')
|
||||
pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
|
||||
|
||||
@@ -509,7 +501,7 @@ int main (int argc, char **argv)
|
||||
if (ret != PAM_SUCCESS) {
|
||||
SYSLOG ((LOG_ERR, "pam_authenticate: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog, pam_strerror (pamh, ret));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
su_failure (tty);
|
||||
}
|
||||
@@ -522,7 +514,7 @@ int main (int argc, char **argv)
|
||||
} else {
|
||||
SYSLOG ((LOG_ERR, "pam_acct_mgmt: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog,
|
||||
fprintf (stderr, _("%s: %s\n"), Prog,
|
||||
pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
su_failure (tty);
|
||||
@@ -532,7 +524,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Set up a signal handler in case the user types QUIT.
|
||||
*/
|
||||
|
||||
die (0);
|
||||
oldsig = signal (SIGQUIT, die);
|
||||
|
||||
@@ -541,7 +532,6 @@ int main (int argc, char **argv)
|
||||
* The first character of an administrator defined method is an '@'
|
||||
* character.
|
||||
*/
|
||||
|
||||
if (!amroot && pw_auth (pwent.pw_passwd, name, PW_SU, (char *) 0)) {
|
||||
SYSLOG ((pwent.pw_uid ? LOG_NOTICE : LOG_WARN,
|
||||
"Authentication failed for %s", name));
|
||||
@@ -554,7 +544,6 @@ int main (int argc, char **argv)
|
||||
* expired accounts, but normal users can't become a user with an
|
||||
* expired password.
|
||||
*/
|
||||
|
||||
if (!amroot) {
|
||||
if (!spwd)
|
||||
spwd = pwd_to_spwd (&pwent);
|
||||
@@ -572,7 +561,6 @@ int main (int argc, char **argv)
|
||||
* there is a "SU" entry in the /etc/porttime file denying access to
|
||||
* the account.
|
||||
*/
|
||||
|
||||
if (!amroot) {
|
||||
if (!isttytime (pwent.pw_name, "SU", time ((time_t *) 0))) {
|
||||
SYSLOG ((pwent.pw_uid ? LOG_WARN : LOG_CRIT,
|
||||
@@ -595,7 +583,10 @@ int main (int argc, char **argv)
|
||||
addenv ("PATH", cp);
|
||||
}
|
||||
|
||||
#ifndef USE_PAM
|
||||
/* setup the environment for PAM later on, else we run into auth problems */
|
||||
environ = newenvp; /* make new environment active */
|
||||
#endif
|
||||
|
||||
if (getenv ("IFS")) /* don't export user IFS ... */
|
||||
addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
|
||||
@@ -631,7 +622,7 @@ int main (int argc, char **argv)
|
||||
ret = pam_setcred (pamh, PAM_ESTABLISH_CRED);
|
||||
if (ret != PAM_SUCCESS) {
|
||||
SYSLOG ((LOG_ERR, "pam_setcred: %s", pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog, pam_strerror (pamh, ret));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
exit (1);
|
||||
}
|
||||
@@ -640,7 +631,7 @@ int main (int argc, char **argv)
|
||||
if (ret != PAM_SUCCESS) {
|
||||
SYSLOG ((LOG_ERR, "pam_open_session: %s",
|
||||
pam_strerror (pamh, ret)));
|
||||
fprintf (stderr, "%s: %s\n", Prog, pam_strerror (pamh, ret));
|
||||
fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
|
||||
pam_end (pamh, ret);
|
||||
exit (1);
|
||||
}
|
||||
@@ -694,7 +685,6 @@ int main (int argc, char **argv)
|
||||
* See if the user has extra arguments on the command line. In that
|
||||
* case they will be provided to the new user's shell as arguments.
|
||||
*/
|
||||
|
||||
if (fakelogin) {
|
||||
char *arg0;
|
||||
|
||||
@@ -710,12 +700,10 @@ int main (int argc, char **argv)
|
||||
cp = Basename (pwent.pw_shell);
|
||||
|
||||
if (!doshell) {
|
||||
|
||||
/*
|
||||
* Use new user's shell from /etc/passwd and create an argv
|
||||
* with the rest of the command line included.
|
||||
*/
|
||||
|
||||
argv[-1] = pwent.pw_shell;
|
||||
#ifndef USE_PAM
|
||||
(void) execv (pwent.pw_shell, &argv[-1]);
|
||||
|
15
src/suauth.c
15
src/suauth.c
@@ -1,12 +1,11 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include "prototypes.h"
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#ifndef SUAUTHFILE
|
||||
#define SUAUTHFILE "/etc/suauth"
|
||||
@@ -17,6 +16,9 @@
|
||||
#define DENY -1
|
||||
#define OWNPWORD 2
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
struct passwd pwent;
|
||||
|
||||
#ifdef SU_ACCESS
|
||||
@@ -24,7 +26,6 @@ struct passwd pwent;
|
||||
/* Really, I could do with a few const char's here defining all the
|
||||
* strings output to the user or the syslog. -- chris
|
||||
*/
|
||||
|
||||
static int applies (const char *, char *);
|
||||
|
||||
int check_su_auth (const char *, const char *);
|
||||
|
@@ -29,16 +29,19 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: sulogin.c,v 1.20 2005/07/06 11:33:06 kloczek Exp $")
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#ident "$Id: sulogin.c,v 1.23 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char name[BUFSIZ];
|
||||
static char pass[BUFSIZ];
|
||||
|
||||
@@ -156,11 +159,9 @@ static RETSIGTYPE catch (int sig)
|
||||
while (1) { /* repeatedly get login/password pairs */
|
||||
pw_entry (name, &pwent); /* get entry from password file */
|
||||
if (pwent.pw_name == (char *) 0) {
|
||||
|
||||
/*
|
||||
* Fail secure
|
||||
*/
|
||||
|
||||
printf (_("No password entry for 'root'\n"));
|
||||
#ifdef USE_SYSLOG
|
||||
SYSLOG (LOG_WARN, "No password entry for 'root'\n");
|
||||
|
177
src/useradd.c
177
src/useradd.c
@@ -29,8 +29,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: useradd.c,v 1.75 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#ident "$Id: useradd.c,v 1.84 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -46,12 +46,20 @@ RCSID (PKG_VER "$Id: useradd.c,v 1.75 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
#include "pwauth.h"
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include "getdef.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
#include "pwio.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
#include "shadowio.h"
|
||||
|
||||
#ifndef SKEL_DIR
|
||||
#define SKEL_DIR "/etc/skel"
|
||||
#endif
|
||||
@@ -65,6 +73,9 @@ RCSID (PKG_VER "$Id: useradd.c,v 1.75 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#ifndef LASTLOG_FILE
|
||||
#define LASTLOG_FILE "/var/log/lastlog"
|
||||
#endif
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
/*
|
||||
* These defaults are used if there is no defaults file.
|
||||
*/
|
||||
@@ -124,16 +135,6 @@ extern int optind;
|
||||
|
||||
static int home_added;
|
||||
|
||||
#include "groupio.h"
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
@@ -185,17 +186,19 @@ static void create_mail (void);
|
||||
/*
|
||||
* fail_exit - undo as much as possible
|
||||
*/
|
||||
|
||||
static void fail_exit (int code)
|
||||
{
|
||||
if (home_added)
|
||||
rmdir (user_home);
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user", user_name, -1,
|
||||
0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "failed adding user `%s', data deleted", user_name));
|
||||
exit (code);
|
||||
}
|
||||
|
||||
|
||||
static struct group *getgr_nam_gid (const char *name)
|
||||
{
|
||||
gid_t gid;
|
||||
@@ -208,7 +211,6 @@ static struct group *getgr_nam_gid (const char *name)
|
||||
return getgrnam (name);
|
||||
}
|
||||
|
||||
|
||||
static long get_number (const char *cp)
|
||||
{
|
||||
long val;
|
||||
@@ -244,7 +246,6 @@ static uid_t get_uid (const char *cp)
|
||||
* various values from the file, or uses built-in default values if the
|
||||
* file does not exist.
|
||||
*/
|
||||
|
||||
static void get_defaults (void)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -263,7 +264,6 @@ static void get_defaults (void)
|
||||
* Read the file a line at a time. Only the lines that have relevant
|
||||
* values are used, everything else can be ignored.
|
||||
*/
|
||||
|
||||
while (fgets (buf, sizeof buf, fp)) {
|
||||
if ((cp = strrchr (buf, '\n')))
|
||||
*cp = '\0';
|
||||
@@ -276,7 +276,6 @@ static void get_defaults (void)
|
||||
/*
|
||||
* Primary GROUP identifier
|
||||
*/
|
||||
|
||||
if (MATCH (buf, DGROUP)) {
|
||||
unsigned int val = (unsigned int) strtoul (cp, &ep, 10);
|
||||
|
||||
@@ -353,14 +352,12 @@ static void get_defaults (void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* show_defaults - show the contents of the defaults file
|
||||
*
|
||||
* show_defaults() displays the values that are used from the default
|
||||
* file and the built-in values.
|
||||
*/
|
||||
|
||||
static void show_defaults (void)
|
||||
{
|
||||
printf ("GROUP=%u\n", (unsigned int) def_group);
|
||||
@@ -379,7 +376,6 @@ static void show_defaults (void)
|
||||
* are currently set. Duplicated lines are pruned, missing lines are
|
||||
* added, and unrecognized lines are copied as is.
|
||||
*/
|
||||
|
||||
static int set_defaults (void)
|
||||
{
|
||||
FILE *ifp;
|
||||
@@ -399,7 +395,6 @@ static int set_defaults (void)
|
||||
/*
|
||||
* Create a temporary file to copy the new output to.
|
||||
*/
|
||||
|
||||
if ((ofd = mkstemp (new_file)) == -1) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot create new defaults file\n"), Prog);
|
||||
@@ -417,7 +412,6 @@ static int set_defaults (void)
|
||||
* temporary file, using any new values. Each line is checked
|
||||
* to insure that it is not output more than once.
|
||||
*/
|
||||
|
||||
if (!(ifp = fopen (def_file, "r"))) {
|
||||
fprintf (ofp, "# useradd defaults file\n");
|
||||
goto skip;
|
||||
@@ -461,7 +455,6 @@ static int set_defaults (void)
|
||||
* causes new values to be added to a file which did not previously
|
||||
* have an entry for that value.
|
||||
*/
|
||||
|
||||
if (!out_group)
|
||||
fprintf (ofp, DGROUP "%u\n", (unsigned int) def_group);
|
||||
if (!out_home)
|
||||
@@ -482,7 +475,6 @@ static int set_defaults (void)
|
||||
* Flush and close the file. Check for errors to make certain
|
||||
* the new file is intact.
|
||||
*/
|
||||
|
||||
fflush (ofp);
|
||||
if (ferror (ofp) || fclose (ofp)) {
|
||||
unlink (new_file);
|
||||
@@ -492,7 +484,6 @@ static int set_defaults (void)
|
||||
/*
|
||||
* Rename the current default file to its backup name.
|
||||
*/
|
||||
|
||||
snprintf (buf, sizeof buf, "%s-", def_file);
|
||||
if (rename (def_file, buf) && errno != ENOENT) {
|
||||
snprintf (buf, sizeof buf, _("%s: rename: %s"), Prog, def_file);
|
||||
@@ -504,12 +495,15 @@ static int set_defaults (void)
|
||||
/*
|
||||
* Rename the new default file to its correct name.
|
||||
*/
|
||||
|
||||
if (rename (new_file, def_file)) {
|
||||
snprintf (buf, sizeof buf, _("%s: rename: %s"), Prog, new_file);
|
||||
perror (buf);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing user defaults",
|
||||
NULL, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"useradd defaults: GROUP=%u, HOME=%s, SHELL=%s, INACTIVE=%ld, "
|
||||
"EXPIRE=%s, SKEL=%s, CREATE_MAIL_SPOOL=%s",
|
||||
@@ -526,7 +520,6 @@ static int set_defaults (void)
|
||||
* converts it to a NULL-terminated array. Any unknown group
|
||||
* names are reported as errors.
|
||||
*/
|
||||
|
||||
static int get_groups (char *list)
|
||||
{
|
||||
char *cp;
|
||||
@@ -537,7 +530,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* Initialize the list to be empty
|
||||
*/
|
||||
|
||||
user_groups[0] = (char *) 0;
|
||||
|
||||
if (!*list)
|
||||
@@ -548,12 +540,10 @@ static int get_groups (char *list)
|
||||
* each name and look it up. A mix of numerical and string
|
||||
* values for group identifiers is permitted.
|
||||
*/
|
||||
|
||||
do {
|
||||
/*
|
||||
* Strip off a single name from the list
|
||||
*/
|
||||
|
||||
if ((cp = strchr (list, ',')))
|
||||
*cp++ = '\0';
|
||||
|
||||
@@ -561,14 +551,12 @@ static int get_groups (char *list)
|
||||
* Names starting with digits are treated as numerical
|
||||
* GID values, otherwise the string is looked up as is.
|
||||
*/
|
||||
|
||||
grp = getgr_nam_gid (list);
|
||||
|
||||
/*
|
||||
* There must be a match, either by GID value or by
|
||||
* string name.
|
||||
*/
|
||||
|
||||
if (!grp) {
|
||||
fprintf (stderr, _("%s: unknown group %s\n"),
|
||||
Prog, list);
|
||||
@@ -588,7 +576,6 @@ static int get_groups (char *list)
|
||||
* 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"),
|
||||
@@ -617,7 +604,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* Any errors in finding group names are fatal
|
||||
*/
|
||||
|
||||
if (errors)
|
||||
return -1;
|
||||
|
||||
@@ -627,7 +613,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: useradd [options] LOGIN\n"
|
||||
@@ -665,7 +650,6 @@ static void usage (void)
|
||||
* new_pwent() takes all of the values that have been entered and
|
||||
* fills in a (struct passwd) with them.
|
||||
*/
|
||||
|
||||
static void new_pwent (struct passwd *pwent)
|
||||
{
|
||||
memzero (pwent, sizeof *pwent);
|
||||
@@ -696,7 +680,6 @@ static long scale_age (long x)
|
||||
* new_spent() takes all of the values that have been entered and
|
||||
* fills in a (struct spwd) with them.
|
||||
*/
|
||||
|
||||
static void new_spent (struct spwd *spent)
|
||||
{
|
||||
memzero (spent, sizeof *spent);
|
||||
@@ -717,7 +700,6 @@ static void new_spent (struct spwd *spent)
|
||||
* grp_update() takes the secondary group set given in user_groups
|
||||
* and adds the user to each group given by that set.
|
||||
*/
|
||||
|
||||
static void grp_update (void)
|
||||
{
|
||||
const struct group *grp;
|
||||
@@ -732,7 +714,6 @@ static void grp_update (void)
|
||||
* Lock and open the group file. This will load all of the group
|
||||
* entries.
|
||||
*/
|
||||
|
||||
if (!gr_lock ()) {
|
||||
fprintf (stderr, _("%s: error locking group file\n"), Prog);
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
@@ -758,14 +739,12 @@ static void grp_update (void)
|
||||
* Scan through the entire group file looking for the groups that
|
||||
* the user is a member of.
|
||||
*/
|
||||
|
||||
for (gr_rewind (), grp = gr_next (); grp; grp = gr_next ()) {
|
||||
|
||||
/*
|
||||
* See if the user specified this group as one of their
|
||||
* concurrent groups.
|
||||
*/
|
||||
|
||||
if (!is_on_list (user_groups, grp->gr_name))
|
||||
continue;
|
||||
|
||||
@@ -773,7 +752,6 @@ static void grp_update (void)
|
||||
* Make a copy - gr_update() will free() everything
|
||||
* from the old entry, and we need it later.
|
||||
*/
|
||||
|
||||
ngrp = __gr_dup (grp);
|
||||
if (!ngrp) {
|
||||
fail_exit (E_GRP_UPDATE); /* XXX */
|
||||
@@ -783,13 +761,16 @@ static void grp_update (void)
|
||||
* Add the username to the list of group members and
|
||||
* update the group entry to reflect the change.
|
||||
*/
|
||||
|
||||
ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
|
||||
if (!gr_update (ngrp)) {
|
||||
fprintf (stderr,
|
||||
"%s: error adding new group entry\n", Prog);
|
||||
_("%s: error adding new group entry\n"), Prog);
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding user to group", user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
|
||||
user_name, ngrp->gr_name));
|
||||
}
|
||||
@@ -803,14 +784,12 @@ static void grp_update (void)
|
||||
* that the user is a member of. The administrative list isn't
|
||||
* modified.
|
||||
*/
|
||||
|
||||
for (sgr_rewind (), sgrp = sgr_next (); sgrp; sgrp = sgr_next ()) {
|
||||
|
||||
/*
|
||||
* See if the user specified this group as one of their
|
||||
* concurrent groups.
|
||||
*/
|
||||
|
||||
if (!gr_locate (sgrp->sg_name))
|
||||
continue;
|
||||
|
||||
@@ -821,7 +800,6 @@ static void grp_update (void)
|
||||
* Make a copy - sgr_update() will free() everything
|
||||
* from the old entry, and we need it later.
|
||||
*/
|
||||
|
||||
nsgrp = __sgr_dup (sgrp);
|
||||
if (!nsgrp) {
|
||||
fail_exit (E_GRP_UPDATE); /* XXX */
|
||||
@@ -831,13 +809,16 @@ static void grp_update (void)
|
||||
* Add the username to the list of group members and
|
||||
* update the group entry to reflect the change.
|
||||
*/
|
||||
|
||||
nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
|
||||
if (!sgr_update (nsgrp)) {
|
||||
fprintf (stderr,
|
||||
_("%s: error adding new group entry\n"), Prog);
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding user to shadow group", user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "add `%s' to shadow group `%s'",
|
||||
user_name, nsgrp->sg_name));
|
||||
}
|
||||
@@ -851,20 +832,18 @@ static void grp_update (void)
|
||||
* file, or checks the given user ID against the existing ones for
|
||||
* uniqueness.
|
||||
*/
|
||||
|
||||
static void find_new_uid (void)
|
||||
{
|
||||
const struct passwd *pwd;
|
||||
uid_t uid_min, uid_max;
|
||||
|
||||
uid_min = getdef_unum ("UID_MIN", 100);
|
||||
uid_min = getdef_unum ("UID_MIN", 1000);
|
||||
uid_max = getdef_unum ("UID_MAX", 60000);
|
||||
|
||||
/*
|
||||
* Start with some UID value if the user didn't provide us with
|
||||
* one already.
|
||||
*/
|
||||
|
||||
if (!uflg)
|
||||
user_id = uid_min;
|
||||
|
||||
@@ -873,7 +852,6 @@ static void find_new_uid (void)
|
||||
* UID (if the user specified one with -u) or looking for the
|
||||
* largest unused value.
|
||||
*/
|
||||
|
||||
#ifdef NO_GETPWENT
|
||||
pw_rewind ();
|
||||
while ((pwd = pw_next ())) {
|
||||
@@ -884,11 +862,19 @@ static void find_new_uid (void)
|
||||
if (strcmp (user_name, pwd->pw_name) == 0) {
|
||||
fprintf (stderr, _("%s: name %s is not unique\n"),
|
||||
Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
||||
user_name, user_id, 0);
|
||||
#endif
|
||||
exit (E_NAME_IN_USE);
|
||||
}
|
||||
if (uflg && user_id == pwd->pw_uid) {
|
||||
fprintf (stderr, _("%s: UID %u is not unique\n"),
|
||||
Prog, (unsigned int) user_id);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
||||
user_name, user_id, 0);
|
||||
#endif
|
||||
exit (E_UID_IN_USE);
|
||||
}
|
||||
if (!uflg && pwd->pw_uid >= user_id) {
|
||||
@@ -897,6 +883,7 @@ static void find_new_uid (void)
|
||||
user_id = pwd->pw_uid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If a user with UID equal to UID_MAX exists, the above algorithm
|
||||
* will give us UID_MAX+1 even if not unique. Search for the first
|
||||
@@ -930,7 +917,6 @@ static void find_new_uid (void)
|
||||
* the values that the user will be created with accordingly. The
|
||||
* values are checked for sanity.
|
||||
*/
|
||||
|
||||
static void process_flags (int argc, char **argv)
|
||||
{
|
||||
const struct group *grp;
|
||||
@@ -1140,6 +1126,7 @@ static void process_flags (int argc, char **argv)
|
||||
anyflag++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Certain options are only valid in combination with others.
|
||||
* Check it here so that they can be specified in any order.
|
||||
@@ -1167,6 +1154,10 @@ static void process_flags (int argc, char **argv)
|
||||
_
|
||||
("%s: invalid user name '%s'\n"),
|
||||
Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
||||
user_name, -1, 0);
|
||||
#endif
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
if (!dflg) {
|
||||
@@ -1195,7 +1186,6 @@ static void process_flags (int argc, char **argv)
|
||||
* close_files() closes all of the files that were opened for this
|
||||
* new user. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!pw_close ()) {
|
||||
@@ -1236,27 +1226,44 @@ static void close_files (void)
|
||||
*
|
||||
* open_files() opens the two password files.
|
||||
*/
|
||||
|
||||
static void open_files (void)
|
||||
{
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking password file", user_name, user_id, 0);
|
||||
#endif
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
if (!pw_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening password file", user_name, user_id, 0);
|
||||
#endif
|
||||
pw_unlock ();
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
if (is_shadow_pwd && !spw_lock ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot lock shadow password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking shadow password file", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
pw_unlock ();
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
if (is_shadow_pwd && !spw_open (O_RDWR)) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open shadow password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening shadow password file", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
spw_unlock ();
|
||||
pw_unlock ();
|
||||
exit (E_PW_UPDATE);
|
||||
@@ -1298,7 +1305,6 @@ static void lastlog_reset (uid_t uid)
|
||||
* usr_update() creates the password file entries for this user
|
||||
* and will update the group entries if required.
|
||||
*/
|
||||
|
||||
static void usr_update (void)
|
||||
{
|
||||
struct passwd pwent;
|
||||
@@ -1311,7 +1317,6 @@ static void usr_update (void)
|
||||
* Fill in the password structure with any new fields, making
|
||||
* copies of strings.
|
||||
*/
|
||||
|
||||
new_pwent (&pwent);
|
||||
new_spent (&spent);
|
||||
|
||||
@@ -1319,7 +1324,6 @@ static void usr_update (void)
|
||||
* Create a syslog entry. We need to do this now in case anything
|
||||
* happens so we know what we were trying to accomplish.
|
||||
*/
|
||||
|
||||
SYSLOG ((LOG_INFO,
|
||||
"new user: name=%s, UID=%u, GID=%u, home=%s, shell=%s",
|
||||
user_name, (unsigned int) user_id,
|
||||
@@ -1331,7 +1335,6 @@ static void usr_update (void)
|
||||
* no user with this UID exists yet (entries for shared UIDs
|
||||
* are left unchanged). --marekm
|
||||
*/
|
||||
|
||||
if (!getpwuid (user_id)) {
|
||||
faillog_reset (user_id);
|
||||
lastlog_reset (user_id);
|
||||
@@ -1340,7 +1343,6 @@ static void usr_update (void)
|
||||
/*
|
||||
* Put the new (struct passwd) in the table.
|
||||
*/
|
||||
|
||||
if (!pw_update (&pwent)) {
|
||||
fprintf (stderr,
|
||||
_("%s: error adding new password entry\n"), Prog);
|
||||
@@ -1350,19 +1352,25 @@ static void usr_update (void)
|
||||
/*
|
||||
* Put the new (struct spwd) in the table.
|
||||
*/
|
||||
|
||||
if (is_shadow_pwd && !spw_update (&spent)) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: error adding new shadow password entry\n"),
|
||||
Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding shadow password", user_name, user_id, 0);
|
||||
#endif
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user", user_name,
|
||||
user_id, 1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do any group file updates for this user.
|
||||
*/
|
||||
|
||||
if (do_grp_update)
|
||||
grp_update ();
|
||||
}
|
||||
@@ -1374,7 +1382,6 @@ static void usr_update (void)
|
||||
* already exist. It will be created mode 755 owned by the user
|
||||
* with the user's default group.
|
||||
*/
|
||||
|
||||
static void create_home (void)
|
||||
{
|
||||
if (access (user_home, F_OK)) {
|
||||
@@ -1389,6 +1396,10 @@ static void create_home (void)
|
||||
chown (user_home, user_id, user_gid);
|
||||
chmod (user_home, 0777 & ~getdef_num ("UMASK", 022));
|
||||
home_added++;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding home directory", user_name, user_id, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1454,7 +1465,6 @@ static struct pam_conv conv = {
|
||||
/*
|
||||
* main - useradd command
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
#ifdef USE_PAM
|
||||
@@ -1463,10 +1473,13 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
@@ -1523,7 +1536,6 @@ int main (int argc, char **argv)
|
||||
* See if we are messing with the defaults file, or creating
|
||||
* a new user.
|
||||
*/
|
||||
|
||||
if (Dflg) {
|
||||
if (gflg || bflg || fflg || eflg || sflg)
|
||||
exit (set_defaults ()? 1 : 0);
|
||||
@@ -1535,9 +1547,12 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Start with a quick check to see if the user exists.
|
||||
*/
|
||||
|
||||
if (getpwnam (user_name)) {
|
||||
fprintf (stderr, _("%s: user %s exists\n"), Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
|
||||
user_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NAME_IN_USE);
|
||||
}
|
||||
|
||||
@@ -1553,6 +1568,10 @@ int main (int argc, char **argv)
|
||||
_
|
||||
("%s: group %s exists - if you want to add this user to that group, use -g.\n"),
|
||||
Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding group", user_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NAME_IN_USE);
|
||||
}
|
||||
}
|
||||
@@ -1566,7 +1585,6 @@ int main (int argc, char **argv)
|
||||
* - flush nscd caches for passwd and group services,
|
||||
* - then close and update the files.
|
||||
*/
|
||||
|
||||
open_files ();
|
||||
|
||||
usr_update ();
|
||||
@@ -1579,7 +1597,8 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: warning: the home directory already exists.\n"
|
||||
"Not copying any file from skel directory into it.\n"), Prog);
|
||||
"Not copying any file from skel directory into it.\n"),
|
||||
Prog);
|
||||
|
||||
} else if (getdef_str ("CREATE_HOME")) {
|
||||
/*
|
||||
@@ -1608,18 +1627,6 @@ int main (int argc, char **argv)
|
||||
close_files ();
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
205
src/userdel.c
205
src/userdel.c
@@ -29,24 +29,31 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: userdel.c,v 1.45 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#ident "$Id: userdel.c,v 1.52 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#endif /* USE_PAM */
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "pwauth.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
@@ -64,14 +71,6 @@ static char *user_home;
|
||||
static char *Prog;
|
||||
static int fflg = 0, rflg = 0;
|
||||
|
||||
#include "groupio.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
|
||||
static int is_shadow_pwd;
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
@@ -97,7 +96,6 @@ static void remove_mailbox (void);
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr, _("Usage: %s [-r] name\n"), Prog);
|
||||
@@ -114,11 +112,11 @@ static void usage (void)
|
||||
* name is their user name) and delete them too (only if USERGROUPS_ENAB
|
||||
* is enabled).
|
||||
*/
|
||||
|
||||
static void update_groups (void)
|
||||
{
|
||||
const struct group *grp;
|
||||
struct group *ngrp;
|
||||
struct passwd *pwd;
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
int deleted_user_group = 0;
|
||||
@@ -130,14 +128,12 @@ static void update_groups (void)
|
||||
* Scan through the entire group file looking for the groups that
|
||||
* the user is a member of.
|
||||
*/
|
||||
|
||||
for (gr_rewind (), grp = gr_next (); grp; grp = gr_next ()) {
|
||||
|
||||
/*
|
||||
* See if the user specified this group as one of their
|
||||
* concurrent groups.
|
||||
*/
|
||||
|
||||
if (!is_on_list (grp->gr_mem, user_name))
|
||||
continue;
|
||||
|
||||
@@ -145,7 +141,6 @@ static void update_groups (void)
|
||||
* Delete the username from the list of group members and
|
||||
* update the group entry to reflect the change.
|
||||
*/
|
||||
|
||||
ngrp = __gr_dup (grp);
|
||||
if (!ngrp) {
|
||||
exit (13); /* XXX */
|
||||
@@ -158,28 +153,61 @@ static void update_groups (void)
|
||||
/*
|
||||
* Update the DBM group file with the new entry as well.
|
||||
*/
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting user from group", user_name, user_id,
|
||||
0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "delete `%s' from group `%s'\n",
|
||||
user_name, ngrp->gr_name));
|
||||
}
|
||||
|
||||
/*
|
||||
* we've removed their name from all the groups above, so
|
||||
* now if they have a group with the same name as their
|
||||
* user name, with no members, we delete it.
|
||||
*/
|
||||
|
||||
grp = getgrnam (user_name);
|
||||
if (grp && getdef_bool ("USERGROUPS_ENAB")
|
||||
&& (grp->gr_mem[0] == NULL)) {
|
||||
|
||||
gr_remove (grp->gr_name);
|
||||
/*
|
||||
* Scan the passwd file to check if this group is still
|
||||
* used as a primary group.
|
||||
*/
|
||||
setpwent ();
|
||||
while ((pwd = getpwent ())) {
|
||||
if (strcmp (pwd->pw_name, user_name) == 0)
|
||||
continue;
|
||||
if (pwd->pw_gid == grp->gr_gid) {
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: Cannot remove group %s which is a primary group for another user.\n"),
|
||||
Prog, grp->gr_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
endpwent ();
|
||||
|
||||
if (pwd == NULL) {
|
||||
/*
|
||||
* We can remove this group, it is not the primary
|
||||
* group of any remaining user.
|
||||
*/
|
||||
gr_remove (grp->gr_name);
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
deleted_user_group = 1;
|
||||
deleted_user_group = 1;
|
||||
#endif
|
||||
|
||||
SYSLOG ((LOG_INFO, "removed group `%s' owned by `%s'\n",
|
||||
grp->gr_name, user_name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting group", user_name, user_id, 0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"removed group `%s' owned by `%s'\n",
|
||||
grp->gr_name, user_name));
|
||||
}
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (!is_shadow_grp)
|
||||
@@ -190,7 +218,6 @@ static void update_groups (void)
|
||||
* that the user is a member of. Both the administrative list and
|
||||
* the ordinary membership list is checked.
|
||||
*/
|
||||
|
||||
for (sgr_rewind (), sgrp = sgr_next (); sgrp; sgrp = sgr_next ()) {
|
||||
int was_member, was_admin;
|
||||
|
||||
@@ -198,7 +225,6 @@ static void update_groups (void)
|
||||
* See if the user specified this group as one of their
|
||||
* concurrent groups.
|
||||
*/
|
||||
|
||||
was_member = is_on_list (sgrp->sg_mem, user_name);
|
||||
was_admin = is_on_list (sgrp->sg_adm, user_name);
|
||||
|
||||
@@ -219,6 +245,11 @@ static void update_groups (void)
|
||||
if (!sgr_update (nsgrp))
|
||||
fprintf (stderr,
|
||||
_("%s: error updating group entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting user from shadow group", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "delete `%s' from shadow group `%s'\n",
|
||||
user_name, nsgrp->sg_name));
|
||||
}
|
||||
@@ -234,7 +265,6 @@ static void update_groups (void)
|
||||
* close_files() closes all of the files that were opened for this
|
||||
* new user. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!pw_close ())
|
||||
@@ -262,7 +292,6 @@ static void close_files (void)
|
||||
/*
|
||||
* fail_exit - exit with a failure code after unlocking the files
|
||||
*/
|
||||
|
||||
static void fail_exit (int code)
|
||||
{
|
||||
(void) pw_unlock ();
|
||||
@@ -272,6 +301,10 @@ static void fail_exit (int code)
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp)
|
||||
sgr_unlock ();
|
||||
#endif
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting user", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
exit (code);
|
||||
}
|
||||
@@ -286,39 +319,76 @@ static void open_files (void)
|
||||
{
|
||||
if (!pw_lock ()) {
|
||||
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking password file", user_name, user_id, 1,
|
||||
0);
|
||||
#endif
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
if (!pw_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening password file", user_name, user_id, 0);
|
||||
#endif
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
if (is_shadow_pwd && !spw_lock ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot lock shadow password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking shadow password file", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
if (is_shadow_pwd && !spw_open (O_RDWR)) {
|
||||
fprintf (stderr,
|
||||
_("%s: cannot open shadow password file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening shadow password file", user_name,
|
||||
user_id, 0);
|
||||
#endif
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
if (!gr_lock ()) {
|
||||
fprintf (stderr, _("%s: unable to lock group file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "locking group file",
|
||||
user_name, user_id, 0);
|
||||
#endif
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
if (!gr_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: cannot open group file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "opening group file",
|
||||
user_name, user_id, 0);
|
||||
#endif
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp && !sgr_lock ()) {
|
||||
fprintf (stderr,
|
||||
_("%s: unable to lock shadow group file\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"locking shadow group file", user_name, user_id,
|
||||
0);
|
||||
#endif
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
if (is_shadow_grp && !sgr_open (O_RDWR)) {
|
||||
fprintf (stderr, _("%s: cannot open shadow group file\n"),
|
||||
Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"opening shadow group file", user_name, user_id,
|
||||
0);
|
||||
#endif
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
#endif
|
||||
@@ -330,7 +400,6 @@ static void open_files (void)
|
||||
* update_user() deletes the password file entries for this user
|
||||
* and will update the group entries as required.
|
||||
*/
|
||||
|
||||
static void update_user (void)
|
||||
{
|
||||
if (!pw_remove (user_name))
|
||||
@@ -339,6 +408,10 @@ static void update_user (void)
|
||||
if (is_shadow_pwd && !spw_remove (user_name))
|
||||
fprintf (stderr,
|
||||
_("%s: error deleting shadow password entry\n"), Prog);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting user entries",
|
||||
user_name, user_id, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "delete user `%s'\n", user_name));
|
||||
}
|
||||
|
||||
@@ -349,7 +422,6 @@ static void update_user (void)
|
||||
* by this user. Also, I think this check should be in usermod
|
||||
* as well (at least when changing username or UID). --marekm
|
||||
*/
|
||||
|
||||
static void user_busy (const char *name, uid_t uid)
|
||||
{
|
||||
|
||||
@@ -379,7 +451,13 @@ static void user_busy (const char *name, uid_t uid)
|
||||
continue;
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently logged in\n"), Prog, name);
|
||||
exit (E_USER_BUSY);
|
||||
if (!fflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting user logged in", name, -1, 0);
|
||||
#endif
|
||||
exit (E_USER_BUSY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,7 +498,6 @@ lprm $1
|
||||
exit 0
|
||||
==========
|
||||
*/
|
||||
|
||||
static void user_cancel (const char *user)
|
||||
{
|
||||
char *cmd;
|
||||
@@ -480,6 +557,10 @@ static void remove_mailbox (void)
|
||||
snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
|
||||
if (fflg) {
|
||||
unlink (mailfile); /* always remove, ignore errors */
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
|
||||
user_name, user_id, 1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
i = is_owner (user_id, mailfile);
|
||||
@@ -488,6 +569,10 @@ static void remove_mailbox (void)
|
||||
_
|
||||
("%s: %s not owned by %s, not removing\n"),
|
||||
Prog, mailfile, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
|
||||
user_name, user_id, 0);
|
||||
#endif
|
||||
return;
|
||||
} else if (i == -1)
|
||||
return; /* mailbox doesn't exist */
|
||||
@@ -495,6 +580,12 @@ static void remove_mailbox (void)
|
||||
fprintf (stderr, _("%s: warning: can't remove "), Prog);
|
||||
perror (mailfile);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
else {
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
|
||||
user_name, user_id, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
@@ -502,6 +593,7 @@ static struct pam_conv conv = {
|
||||
misc_conv, NULL
|
||||
};
|
||||
#endif /* USE_PAM */
|
||||
|
||||
/*
|
||||
* main - userdel command
|
||||
*/
|
||||
@@ -516,6 +608,11 @@ int main (int argc, char **argv)
|
||||
struct passwd *pampw;
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
@@ -582,6 +679,10 @@ int main (int argc, char **argv)
|
||||
if (!(pwd = getpwnam (user_name))) {
|
||||
fprintf (stderr, _("%s: user %s does not exist\n"),
|
||||
Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting user not found", user_name, -1, 0);
|
||||
#endif
|
||||
exit (E_NOTFOUND);
|
||||
}
|
||||
#ifdef USE_NIS
|
||||
@@ -589,7 +690,6 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Now make sure it isn't an NIS user.
|
||||
*/
|
||||
|
||||
if (__ispwNIS ()) {
|
||||
char *nis_domain;
|
||||
char *nis_master;
|
||||
@@ -611,6 +711,7 @@ int main (int argc, char **argv)
|
||||
* Check to make certain the user isn't logged in.
|
||||
*/
|
||||
user_busy (user_name, user_id);
|
||||
|
||||
/*
|
||||
* Do the hard stuff - open the files, create the user entries,
|
||||
* create the home directory, then close and update the files.
|
||||
@@ -631,9 +732,8 @@ int main (int argc, char **argv)
|
||||
rflg = 0;
|
||||
errors++;
|
||||
}
|
||||
|
||||
/* This may be slow, the above should be good enough. */
|
||||
#ifdef EXTRA_CHECK_HOME_DIR
|
||||
/* This may be slow, the above should be good enough. */
|
||||
if (rflg && !fflg) {
|
||||
/*
|
||||
* For safety, refuse to remove the home directory if it
|
||||
@@ -656,6 +756,7 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
endpwent ();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -665,32 +766,34 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_("%s: error removing directory %s\n"),
|
||||
Prog, user_home);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting home directory", user_name,
|
||||
user_id, 1);
|
||||
#endif
|
||||
errors++;
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting home directory", user_name, user_id, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel any crontabs or at jobs. Have to do this before we remove
|
||||
* the entry from /etc/passwd.
|
||||
*/
|
||||
|
||||
user_cancel (user_name);
|
||||
close_files ();
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS)
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM chauthtok failed\n"), Prog);
|
||||
exit (E_PW_UPDATE);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
#ifdef WITH_AUDIT
|
||||
if (errors)
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"deleting home directory", user_name, -1, 0);
|
||||
#endif
|
||||
exit (errors ? E_HOMEDIR : E_SUCCESS);
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
323
src/usermod.c
323
src/usermod.c
@@ -29,30 +29,30 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: usermod.c,v 1.51 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#ident "$Id: usermod.c,v 1.58 2005/10/04 21:05:12 kloczek Exp $"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <grp.h>
|
||||
#include <lastlog.h>
|
||||
#include <pwd.h>
|
||||
#ifdef USE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
#endif /* USE_PAM */
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include "chkname.h"
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include <lastlog.h>
|
||||
#include "pwauth.h"
|
||||
#include "getdef.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwauth.h"
|
||||
#include "pwio.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "sgroupio.h"
|
||||
@@ -68,14 +68,17 @@ RCSID (PKG_VER "$Id: usermod.c,v 1.51 2005/08/11 16:23:34 kloczek Exp $")
|
||||
#define E_USAGE 2 /* invalid command syntax */
|
||||
#define E_BAD_ARG 3 /* invalid argument to option */
|
||||
#define E_UID_IN_USE 4 /* UID already in use (and no -o) */
|
||||
/* #define E_BAD_PWFILE 5 *//* passwd file contains errors */
|
||||
/* #define E_BAD_PWFILE 5 *//* passwd file contains errors */
|
||||
#define E_NOTFOUND 6 /* specified user/group doesn't exist */
|
||||
#define E_USER_BUSY 8 /* user to modify is logged in */
|
||||
#define E_NAME_IN_USE 9 /* username already in use */
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
/* #define E_NOSPACE 11 *//* insufficient space to move home dir */
|
||||
/* #define E_NOSPACE 11 *//* insufficient space to move home dir */
|
||||
#define E_HOMEDIR 12 /* unable to complete home dir move */
|
||||
#define VALID(s) (strcspn (s, ":\n") == strlen (s))
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static char *user_name;
|
||||
static char *user_newname;
|
||||
static char *user_pass;
|
||||
@@ -84,12 +87,16 @@ static uid_t user_newid;
|
||||
static gid_t user_gid;
|
||||
static gid_t user_newgid;
|
||||
static char *user_comment;
|
||||
static char *user_newcomment; /* Audit */
|
||||
static char *user_home;
|
||||
static char *user_newhome;
|
||||
static char *user_shell;
|
||||
static char *user_newshell; /* Audit */
|
||||
|
||||
static long user_expire;
|
||||
static long user_newexpire; /* Audit */
|
||||
static long user_inactive;
|
||||
static long user_newinactive; /* Audit */
|
||||
static long sys_ngroups;
|
||||
static char **user_groups; /* NULL-terminated list */
|
||||
|
||||
@@ -163,7 +170,6 @@ static struct group *getgr_nam_gid (const char *name)
|
||||
return getgrnam (name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_groups - convert a list of group names to an array of group IDs
|
||||
*
|
||||
@@ -171,7 +177,6 @@ static struct group *getgr_nam_gid (const char *name)
|
||||
* converts it to a NULL-terminated array. Any unknown group names are
|
||||
* reported as errors.
|
||||
*/
|
||||
|
||||
static int get_groups (char *list)
|
||||
{
|
||||
char *cp;
|
||||
@@ -182,7 +187,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* Initialize the list to be empty
|
||||
*/
|
||||
|
||||
user_groups[0] = (char *) 0;
|
||||
|
||||
if (!*list)
|
||||
@@ -193,7 +197,6 @@ static int get_groups (char *list)
|
||||
* name and look it up. A mix of numerical and string values for
|
||||
* group identifiers is permitted.
|
||||
*/
|
||||
|
||||
do {
|
||||
/*
|
||||
* Strip off a single name from the list
|
||||
@@ -230,7 +233,6 @@ static int get_groups (char *list)
|
||||
* 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"),
|
||||
@@ -250,7 +252,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* Add the group name to the user's list of groups.
|
||||
*/
|
||||
|
||||
user_groups[ngroups++] = xstrdup (grp->gr_name);
|
||||
} while (list);
|
||||
|
||||
@@ -259,7 +260,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* Any errors in finding group names are fatal
|
||||
*/
|
||||
|
||||
if (errors)
|
||||
return -1;
|
||||
|
||||
@@ -269,7 +269,6 @@ static int get_groups (char *list)
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
|
||||
static void usage (void)
|
||||
{
|
||||
fprintf (stderr,
|
||||
@@ -289,12 +288,15 @@ static void usage (void)
|
||||
* update encrypted password string (for both shadow and non-shadow
|
||||
* passwords)
|
||||
*/
|
||||
|
||||
static char *new_pw_passwd (char *pw_pass, const char *pw_name)
|
||||
{
|
||||
if (Lflg && pw_pass[0] != '!') {
|
||||
char *buf = xmalloc (strlen (pw_pass) + 2);
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "updating passwd",
|
||||
user_newname, user_newid, 0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "lock user `%s' password", pw_name));
|
||||
strcpy (buf, "!");
|
||||
strcat (buf, pw_pass);
|
||||
@@ -302,6 +304,10 @@ static char *new_pw_passwd (char *pw_pass, const char *pw_name)
|
||||
} else if (Uflg && pw_pass[0] == '!') {
|
||||
char *s;
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "updating password",
|
||||
user_newname, user_newid, 0);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "unlock user `%s' password", pw_name));
|
||||
s = pw_pass;
|
||||
while (*s) {
|
||||
@@ -309,6 +315,10 @@ static char *new_pw_passwd (char *pw_pass, const char *pw_name)
|
||||
s++;
|
||||
}
|
||||
} else if (pflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password",
|
||||
user_newname, user_newid, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "change user `%s' password", pw_name));
|
||||
pw_pass = xstrdup (user_pass);
|
||||
}
|
||||
@@ -321,10 +331,13 @@ static char *new_pw_passwd (char *pw_pass, const char *pw_name)
|
||||
* new_pwent() takes all of the values that have been entered and fills
|
||||
* in a (struct passwd) with them.
|
||||
*/
|
||||
|
||||
static void new_pwent (struct passwd *pwent)
|
||||
{
|
||||
if (lflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing name",
|
||||
user_newname, user_newid, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "change user name `%s' to `%s'",
|
||||
pwent->pw_name, user_newname));
|
||||
pwent->pw_name = xstrdup (user_newname);
|
||||
@@ -334,31 +347,60 @@ static void new_pwent (struct passwd *pwent)
|
||||
new_pw_passwd (pwent->pw_passwd, pwent->pw_name);
|
||||
|
||||
if (uflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing uid",
|
||||
user_newname, user_newid, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' UID from `%d' to `%d'",
|
||||
pwent->pw_name, pwent->pw_uid, user_newid));
|
||||
pwent->pw_uid = user_newid;
|
||||
}
|
||||
if (gflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing primary group", user_newname,
|
||||
user_newid, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' GID from `%d' to `%d'",
|
||||
pwent->pw_name, pwent->pw_gid, user_newgid));
|
||||
pwent->pw_gid = user_newgid;
|
||||
}
|
||||
if (cflg)
|
||||
if (cflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing comment",
|
||||
user_newname, user_newid, 1);
|
||||
pwent->pw_gecos = user_newcomment;
|
||||
#else
|
||||
pwent->pw_gecos = user_comment;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (dflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing home directory", user_newname,
|
||||
user_newid, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' home from `%s' to `%s'",
|
||||
pwent->pw_name, pwent->pw_dir, user_newhome));
|
||||
pwent->pw_dir = user_newhome;
|
||||
}
|
||||
if (sflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing user shell",
|
||||
user_newname, user_newid, 1);
|
||||
SYSLOG ((LOG_INFO, "change user `%s' shell from `%s' to `%s'",
|
||||
pwent->pw_name, pwent->pw_shell, user_newshell));
|
||||
pwent->pw_shell = user_newshell;
|
||||
#else
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' shell from `%s' to `%s'",
|
||||
pwent->pw_name, pwent->pw_shell, user_shell));
|
||||
pwent->pw_shell = user_shell;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,24 +410,84 @@ static void new_pwent (struct passwd *pwent)
|
||||
* new_spent() takes all of the values that have been entered and fills
|
||||
* in a (struct spwd) with them.
|
||||
*/
|
||||
|
||||
static void new_spent (struct spwd *spent)
|
||||
{
|
||||
if (lflg)
|
||||
spent->sp_namp = xstrdup (user_newname);
|
||||
|
||||
if (fflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing inactive days", user_newname,
|
||||
user_newid, 1);
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' inactive from `%ld' to `%ld'",
|
||||
spent->sp_namp, spent->sp_inact, user_newinactive));
|
||||
spent->sp_inact = user_newinactive;
|
||||
#else
|
||||
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' inactive from `%ld' to `%ld'",
|
||||
spent->sp_namp, spent->sp_inact, user_inactive));
|
||||
spent->sp_inact = user_inactive;
|
||||
#endif
|
||||
}
|
||||
if (eflg) {
|
||||
/* XXX - dates might be better than numbers of days. --marekm */
|
||||
#ifdef WITH_AUDIT
|
||||
if (audit_fd >= 0) {
|
||||
time_t exp_t;
|
||||
struct tm *exp_tm;
|
||||
char new_exp[16], old_exp[16];
|
||||
|
||||
if (user_newexpire == -1)
|
||||
new_exp[0] = '\0';
|
||||
else {
|
||||
exp_t = user_newexpire * DAY;
|
||||
exp_tm = gmtime (&exp_t);
|
||||
#ifdef HAVE_STRFTIME
|
||||
strftime (new_exp, sizeof (new_exp), "%Y-%m-%d",
|
||||
exp_tm);
|
||||
#else
|
||||
memset (new_exp, 0, sizeof (new_exp));
|
||||
snprintf (new_exp, sizeof (new_exp) - 1,
|
||||
"%04i-%02i-%02i",
|
||||
exp_tm->tm_year + 1900,
|
||||
exp_tm->tm_mon + 1, exp_tm->tm_mday);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (user_expire == -1)
|
||||
old_exp[0] = '\0';
|
||||
else {
|
||||
exp_t = user_expire * DAY;
|
||||
exp_tm = gmtime (&exp_t);
|
||||
#ifdef HAVE_STRFTIME
|
||||
strftime (old_exp, sizeof (old_exp), "%Y-%m-%d",
|
||||
exp_tm);
|
||||
#else
|
||||
memset (old_exp, 0, sizeof (old_exp));
|
||||
snprintf (old_exp, sizeof (old_exp) - 1,
|
||||
"%04i-%02i-%02i",
|
||||
exp_tm->tm_year + 1900,
|
||||
exp_tm->tm_mon + 1, exp_tm->tm_mday);
|
||||
#endif
|
||||
}
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing expiration date", user_newname,
|
||||
user_newid, 1);
|
||||
}
|
||||
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' expiration from `%ld' to `%ld'",
|
||||
spent->sp_namp, spent->sp_expire, user_newexpire));
|
||||
spent->sp_expire = user_newexpire;
|
||||
#else
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change user `%s' expiration from `%ld' to `%ld'",
|
||||
spent->sp_namp, spent->sp_expire, user_expire));
|
||||
spent->sp_expire = user_expire;
|
||||
#endif
|
||||
}
|
||||
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp, spent->sp_namp);
|
||||
if (pflg)
|
||||
@@ -395,7 +497,6 @@ static void new_spent (struct spwd *spent)
|
||||
/*
|
||||
* fail_exit - exit with an error code after unlocking files
|
||||
*/
|
||||
|
||||
static void fail_exit (int code)
|
||||
{
|
||||
(void) gr_unlock ();
|
||||
@@ -406,6 +507,10 @@ static void fail_exit (int code)
|
||||
if (is_shadow_pwd)
|
||||
spw_unlock ();
|
||||
(void) pw_unlock ();
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying account",
|
||||
user_name, -1, 0);
|
||||
#endif
|
||||
exit (code);
|
||||
}
|
||||
|
||||
@@ -441,7 +546,6 @@ static int update_group (void)
|
||||
* the user is a member of.
|
||||
*/
|
||||
while ((grp = gr_next ())) {
|
||||
|
||||
/*
|
||||
* See if the user specified this group as one of their
|
||||
* concurrent groups.
|
||||
@@ -468,6 +572,11 @@ static int update_group (void)
|
||||
ngrp->gr_mem = add_list (ngrp->gr_mem,
|
||||
user_newname);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing group member",
|
||||
user_newname, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change `%s' to `%s' in group `%s'",
|
||||
user_name, user_newname,
|
||||
@@ -476,6 +585,11 @@ static int update_group (void)
|
||||
} else if (was_member && !aflg && Gflg && !is_member) {
|
||||
ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"removing group member", user_name, -1,
|
||||
1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "delete `%s' from group `%s'",
|
||||
user_name, ngrp->gr_name));
|
||||
} else if (!was_member && Gflg && is_member) {
|
||||
@@ -483,6 +597,10 @@ static int update_group (void)
|
||||
lflg ? user_newname :
|
||||
user_name);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding user to group", user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "add `%s' to group `%s'",
|
||||
lflg ? user_newname : user_name,
|
||||
ngrp->gr_name));
|
||||
@@ -574,6 +692,11 @@ static int update_gshadow (void)
|
||||
nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
|
||||
nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing admin name in shadow group",
|
||||
user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change admin `%s' to `%s' in shadow group `%s'",
|
||||
user_name, user_newname, nsgrp->sg_name));
|
||||
@@ -585,6 +708,11 @@ static int update_gshadow (void)
|
||||
nsgrp->sg_mem = add_list (nsgrp->sg_mem,
|
||||
user_newname);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing member in shadow group",
|
||||
user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"change `%s' to `%s' in shadow group `%s'",
|
||||
user_name, user_newname,
|
||||
@@ -593,6 +721,11 @@ static int update_gshadow (void)
|
||||
} else if (was_member && !aflg && Gflg && !is_member) {
|
||||
nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"removing user from shadow group",
|
||||
user_name, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO,
|
||||
"delete `%s' from shadow group `%s'",
|
||||
user_name, nsgrp->sg_name));
|
||||
@@ -601,6 +734,11 @@ static int update_gshadow (void)
|
||||
lflg ? user_newname :
|
||||
user_name);
|
||||
changed = 1;
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"adding user to shadow group",
|
||||
user_newname, -1, 1);
|
||||
#endif
|
||||
SYSLOG ((LOG_INFO, "add `%s' to shadow group `%s'",
|
||||
lflg ? user_newname : user_name,
|
||||
nsgrp->sg_name));
|
||||
@@ -639,7 +777,6 @@ static int update_gshadow (void)
|
||||
* grp_update() takes the secondary group set given in user_groups and
|
||||
* adds the user to each group given by that set.
|
||||
*/
|
||||
|
||||
static int grp_update (void)
|
||||
{
|
||||
int ret;
|
||||
@@ -685,7 +822,6 @@ static uid_t get_id (const char *cp)
|
||||
* values that the user will be created with accordingly. The values
|
||||
* are checked for sanity.
|
||||
*/
|
||||
|
||||
static void process_flags (int argc, char **argv)
|
||||
{
|
||||
const struct group *grp;
|
||||
@@ -703,14 +839,26 @@ static void process_flags (int argc, char **argv)
|
||||
Prog, argv[argc - 1]);
|
||||
exit (E_NOTFOUND);
|
||||
}
|
||||
|
||||
user_name = argv[argc - 1];
|
||||
user_id = pwd->pw_uid;
|
||||
user_gid = pwd->pw_gid;
|
||||
user_comment = xstrdup (pwd->pw_gecos);
|
||||
user_home = xstrdup (pwd->pw_dir);
|
||||
user_shell = xstrdup (pwd->pw_shell);
|
||||
#ifdef WITH_AUDIT
|
||||
user_newname = user_name;
|
||||
user_newid = user_id;
|
||||
user_newgid = user_gid;
|
||||
user_newcomment = user_comment;
|
||||
user_newhome = user_home;
|
||||
user_newshell = user_shell;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NIS
|
||||
|
||||
/*
|
||||
* Now make sure it isn't an NIS user.
|
||||
*/
|
||||
|
||||
if (__ispwNIS ()) {
|
||||
char *nis_domain;
|
||||
char *nis_master;
|
||||
@@ -726,15 +874,14 @@ static void process_flags (int argc, char **argv)
|
||||
exit (E_NOTFOUND);
|
||||
}
|
||||
#endif
|
||||
user_id = pwd->pw_uid;
|
||||
user_gid = pwd->pw_gid;
|
||||
user_comment = xstrdup (pwd->pw_gecos);
|
||||
user_home = xstrdup (pwd->pw_dir);
|
||||
user_shell = xstrdup (pwd->pw_shell);
|
||||
|
||||
if (is_shadow_pwd && (spwd = getspnam (user_name))) {
|
||||
user_expire = spwd->sp_expire;
|
||||
user_inactive = spwd->sp_inact;
|
||||
#ifdef WITH_AUDIT
|
||||
user_newexpire = user_expire;
|
||||
user_newinactive = user_inactive;
|
||||
#endif
|
||||
}
|
||||
|
||||
while ((arg = getopt (argc, argv, "ac:d:e:f:g:G:l:Lmop:s:u:U")) != EOF) {
|
||||
@@ -749,7 +896,11 @@ static void process_flags (int argc, char **argv)
|
||||
Prog, optarg);
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
user_newcomment = optarg;
|
||||
#else
|
||||
user_comment = optarg;
|
||||
#endif
|
||||
cflg++;
|
||||
break;
|
||||
case 'd':
|
||||
@@ -764,21 +915,38 @@ static void process_flags (int argc, char **argv)
|
||||
break;
|
||||
case 'e':
|
||||
if (*optarg) {
|
||||
#ifdef WITH_AUDIT
|
||||
user_newexpire = strtoday (optarg);
|
||||
if (user_newexpire == -1) {
|
||||
#else
|
||||
user_expire = strtoday (optarg);
|
||||
if (user_expire == -1) {
|
||||
#endif
|
||||
fprintf (stderr,
|
||||
_
|
||||
("%s: invalid date `%s'\n"),
|
||||
Prog, optarg);
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
user_newexpire *= DAY / SCALE;
|
||||
#else
|
||||
user_expire *= DAY / SCALE;
|
||||
#endif
|
||||
} else
|
||||
#ifdef WITH_AUDIT
|
||||
user_newexpire = -1;
|
||||
#else
|
||||
user_expire = -1;
|
||||
#endif
|
||||
eflg++;
|
||||
break;
|
||||
case 'f':
|
||||
#ifdef WITH_AUDIT
|
||||
user_newinactive = get_number (optarg);
|
||||
#else
|
||||
user_inactive = get_number (optarg);
|
||||
#endif
|
||||
fflg++;
|
||||
break;
|
||||
case 'g':
|
||||
@@ -810,7 +978,6 @@ static void process_flags (int argc, char **argv)
|
||||
* set the flag as this will cause rather serious
|
||||
* problems later!
|
||||
*/
|
||||
|
||||
if (strcmp (user_name, optarg))
|
||||
lflg++;
|
||||
|
||||
@@ -848,7 +1015,11 @@ static void process_flags (int argc, char **argv)
|
||||
Prog, optarg);
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
user_newshell = optarg;
|
||||
#else
|
||||
user_shell = optarg;
|
||||
#endif
|
||||
sflg++;
|
||||
break;
|
||||
case 'u':
|
||||
@@ -913,7 +1084,6 @@ static void process_flags (int argc, char **argv)
|
||||
* close_files() closes all of the files that were opened for this new
|
||||
* user. This causes any modified entries to be written out.
|
||||
*/
|
||||
|
||||
static void close_files (void)
|
||||
{
|
||||
if (!pw_close ()) {
|
||||
@@ -932,7 +1102,6 @@ static void close_files (void)
|
||||
/*
|
||||
* Close the DBM and/or flat files
|
||||
*/
|
||||
|
||||
endpwent ();
|
||||
endspent ();
|
||||
endgrent ();
|
||||
@@ -946,7 +1115,6 @@ static void close_files (void)
|
||||
*
|
||||
* open_files() opens the two password files.
|
||||
*/
|
||||
|
||||
static void open_files (void)
|
||||
{
|
||||
if (!pw_lock ()) {
|
||||
@@ -975,7 +1143,6 @@ static void open_files (void)
|
||||
* usr_update() creates the password file entries for this user and
|
||||
* will update the group entries if required.
|
||||
*/
|
||||
|
||||
static void usr_update (void)
|
||||
{
|
||||
struct passwd pwent;
|
||||
@@ -987,7 +1154,6 @@ static void usr_update (void)
|
||||
/*
|
||||
* Locate the entry in /etc/passwd, which MUST exist.
|
||||
*/
|
||||
|
||||
pwd = pw_locate (user_name);
|
||||
if (!pwd) {
|
||||
fprintf (stderr, _("%s: %s not found in /etc/passwd\n"),
|
||||
@@ -1002,7 +1168,6 @@ static void usr_update (void)
|
||||
* Locate the entry in /etc/shadow. It doesn't have to exist, and
|
||||
* won't be created if it doesn't.
|
||||
*/
|
||||
|
||||
if (is_shadow_pwd && (spwd = spw_locate (user_name))) {
|
||||
spent = *spwd;
|
||||
new_spent (&spent);
|
||||
@@ -1047,7 +1212,6 @@ static void usr_update (void)
|
||||
* move_home() moves the user's home directory to a new location. The
|
||||
* files will be copied if the directory cannot simply be renamed.
|
||||
*/
|
||||
|
||||
static void move_home (void)
|
||||
{
|
||||
struct stat sb;
|
||||
@@ -1088,6 +1252,13 @@ static void move_home (void)
|
||||
_
|
||||
("%s: warning: failed to completely remove old home directory %s"),
|
||||
Prog, user_home);
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK,
|
||||
Prog,
|
||||
"moving home directory",
|
||||
user_newname, user_newid,
|
||||
1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1100,17 +1271,27 @@ static void move_home (void)
|
||||
Prog, user_home, user_newhome);
|
||||
fail_exit (E_HOMEDIR);
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"moving home directory", user_newname, user_newid,
|
||||
1);
|
||||
#endif
|
||||
}
|
||||
if (uflg || gflg)
|
||||
if (uflg || gflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing home directory owner", user_newname,
|
||||
user_newid, 1);
|
||||
#endif
|
||||
chown (dflg ? user_newhome : user_home,
|
||||
uflg ? user_newid : user_id,
|
||||
gflg ? user_newgid : user_gid);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* update_files - update the lastlog and faillog files
|
||||
*/
|
||||
|
||||
static void update_files (void)
|
||||
{
|
||||
struct lastlog ll;
|
||||
@@ -1122,7 +1303,6 @@ static void update_files (void)
|
||||
* left alone in case the UID was shared. It doesn't hurt anything
|
||||
* to just leave it be.
|
||||
*/
|
||||
|
||||
if ((fd = open (LASTLOG_FILE, O_RDWR)) != -1) {
|
||||
lseek (fd, (off_t) user_id * sizeof ll, SEEK_SET);
|
||||
if (read (fd, (char *) &ll, sizeof ll) == sizeof ll) {
|
||||
@@ -1135,7 +1315,6 @@ static void update_files (void)
|
||||
/*
|
||||
* Relocate the "faillog" entries in the same manner.
|
||||
*/
|
||||
|
||||
if ((fd = open (FAILLOG_FILE, O_RDWR)) != -1) {
|
||||
lseek (fd, (off_t) user_id * sizeof fl, SEEK_SET);
|
||||
if (read (fd, (char *) &fl, sizeof fl) == sizeof fl) {
|
||||
@@ -1175,7 +1354,6 @@ static void move_mailbox (void)
|
||||
* replacing /var/spool/mail/luser with a hard link to /etc/passwd
|
||||
* between stat and chown). --marekm
|
||||
*/
|
||||
|
||||
snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
|
||||
fd = open (mailfile, O_RDONLY | O_NONBLOCK, 0);
|
||||
if (fd < 0) {
|
||||
@@ -1196,16 +1374,34 @@ static void move_mailbox (void)
|
||||
close (fd);
|
||||
return;
|
||||
}
|
||||
if (uflg && fchown (fd, user_newid, (gid_t) - 1) < 0)
|
||||
perror (_("failed to change mailbox owner"));
|
||||
if (uflg) {
|
||||
if (fchown (fd, user_newid, (gid_t) - 1) < 0) {
|
||||
perror (_("failed to change mailbox owner"));
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
else {
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing mail file owner", user_newname,
|
||||
user_newid, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
if (lflg) {
|
||||
snprintf (newmailfile, sizeof newmailfile, "%s/%s",
|
||||
maildir, user_newname);
|
||||
if (link (mailfile, newmailfile) || unlink (mailfile))
|
||||
if (link (mailfile, newmailfile) || unlink (mailfile)) {
|
||||
perror (_("failed to rename mailbox"));
|
||||
}
|
||||
#ifdef WITH_AUDIT
|
||||
else {
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
"changing mail file name", user_newname,
|
||||
user_newid, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1220,7 +1416,6 @@ static struct pam_conv conv = {
|
||||
/*
|
||||
* main - usermod command
|
||||
*/
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int grp_err = 0;
|
||||
@@ -1231,6 +1426,10 @@ int main (int argc, char **argv)
|
||||
int retval;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_help_open ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
@@ -1289,7 +1488,6 @@ int main (int argc, char **argv)
|
||||
* Do the hard stuff - open the files, change the user entries,
|
||||
* change the home directory, then close and update the files.
|
||||
*/
|
||||
|
||||
open_files ();
|
||||
|
||||
usr_update ();
|
||||
@@ -1316,7 +1514,6 @@ int main (int argc, char **argv)
|
||||
* Change the UID on all of the files owned by `user_id' to
|
||||
* `user_newid' in the user's home directory.
|
||||
*/
|
||||
|
||||
chown_tree (dflg ? user_newhome : user_home,
|
||||
user_id, user_newid,
|
||||
user_gid, gflg ? user_newgid : user_gid);
|
||||
@@ -1326,18 +1523,6 @@ int main (int argc, char **argv)
|
||||
exit (E_GRP_UPDATE);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (retval == PAM_SUCCESS) {
|
||||
retval = pam_chauthtok (pamh, 0);
|
||||
if (retval != PAM_SUCCESS) {
|
||||
pam_end (pamh, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval != PAM_SUCCESS) {
|
||||
fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS)
|
||||
pam_end (pamh, PAM_SUCCESS);
|
||||
#endif /* USE_PAM */
|
||||
|
23
src/vipw.c
23
src/vipw.c
@@ -22,23 +22,26 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID (PKG_VER "$Id: vipw.c,v 1.14 2005/08/03 16:00:46 kloczek Exp $")
|
||||
#include "defines.h"
|
||||
#ident "$Id: vipw.c,v 1.17 2005/09/07 15:00:45 kloczek Exp $"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include "defines.h"
|
||||
#include "groupio.h"
|
||||
#include "nscd.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "groupio.h"
|
||||
#include "sgroupio.h"
|
||||
#include "nscd.h"
|
||||
#include "shadowio.h"
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static const char *progname, *filename, *fileeditname;
|
||||
static int filelocked = 0, createedit = 0;
|
||||
static int (*unlock) (void);
|
||||
@@ -186,7 +189,6 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
||||
* ask the user what to do (edit again, save changes anyway, or quit
|
||||
* without saving). Use pwck or grpck to do the check. --marekm
|
||||
*/
|
||||
|
||||
createedit = 0;
|
||||
unlink (filebackup);
|
||||
link (file, filebackup);
|
||||
@@ -201,7 +203,6 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
||||
(*file_unlock) ();
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int flag;
|
||||
|
Reference in New Issue
Block a user