[svn-upgrade] Integrating new upstream version, shadow (4.0.13)

This commit is contained in:
nekral-guest
2007-10-07 11:47:01 +00:00
parent e89f3546f2
commit 8451bed8b0
279 changed files with 12461 additions and 8086 deletions

View File

@@ -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

View File

@@ -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 \

View File

@@ -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 ();

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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 */
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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") :

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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") :

View File

@@ -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 */

View File

@@ -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"),

View File

@@ -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]);

View File

@@ -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 *);

View File

@@ -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");

View File

@@ -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 */

View File

@@ -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 */
}

View File

@@ -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 */

View File

@@ -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;