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

This commit is contained in:
nekral-guest
2007-10-07 11:47:11 +00:00
parent 8451bed8b0
commit 24178ad677
502 changed files with 27080 additions and 14708 deletions

View File

@@ -32,6 +32,7 @@ usbin_PROGRAMS = \
grpunconv \
logoutd \
newusers \
nologin \
pwck \
pwconv \
pwunconv \
@@ -52,9 +53,6 @@ AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
chage_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
chfn_LDADD = $(LDADD) $(LIBPAM)
chsh_SOURCES = \
chsh.c \
chsh_chkshell.c
chsh_LDADD = $(LDADD) $(LIBPAM)
chpasswd_LDADD = $(LDADD) $(LIBPAM)
gpasswd_LDADD = $(LDADD) $(LIBAUDIT)
@@ -64,8 +62,10 @@ groupmod_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
login_SOURCES = \
login.c \
login_nopam.c
login_LDADD = $(LDADD) $(LIBPAM)
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
newgrp_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
newusers_LDADD = $(LDADD) $(LIBPAM)
nologin_LDADD =
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT)
su_SOURCES = \
su.c \

View File

@@ -43,9 +43,9 @@ ubin_PROGRAMS = faillog$(EXEEXT) lastlog$(EXEEXT) chage$(EXEEXT) \
usbin_PROGRAMS = chpasswd$(EXEEXT) groupadd$(EXEEXT) groupdel$(EXEEXT) \
groupmod$(EXEEXT) grpck$(EXEEXT) grpconv$(EXEEXT) \
grpunconv$(EXEEXT) logoutd$(EXEEXT) newusers$(EXEEXT) \
pwck$(EXEEXT) pwconv$(EXEEXT) pwunconv$(EXEEXT) \
useradd$(EXEEXT) userdel$(EXEEXT) usermod$(EXEEXT) \
vipw$(EXEEXT)
nologin$(EXEEXT) pwck$(EXEEXT) pwconv$(EXEEXT) \
pwunconv$(EXEEXT) useradd$(EXEEXT) userdel$(EXEEXT) \
usermod$(EXEEXT) vipw$(EXEEXT)
noinst_PROGRAMS = id$(EXEEXT) sulogin$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
@@ -77,8 +77,8 @@ chfn_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
chpasswd_SOURCES = chpasswd.c
chpasswd_OBJECTS = chpasswd.$(OBJEXT)
chpasswd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
am_chsh_OBJECTS = chsh.$(OBJEXT) chsh_chkshell.$(OBJEXT)
chsh_OBJECTS = $(am_chsh_OBJECTS)
chsh_SOURCES = chsh.c
chsh_OBJECTS = chsh.$(OBJEXT)
chsh_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
expiry_SOURCES = expiry.c
expiry_OBJECTS = expiry.$(OBJEXT)
@@ -137,7 +137,8 @@ lastlog_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/lib/libshadow.la
am_login_OBJECTS = login.$(OBJEXT) login_nopam.$(OBJEXT)
login_OBJECTS = $(am_login_OBJECTS)
login_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
login_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_2)
logoutd_SOURCES = logoutd.c
logoutd_OBJECTS = logoutd.$(OBJEXT)
logoutd_LDADD = $(LDADD)
@@ -145,12 +146,14 @@ logoutd_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/lib/libshadow.la
newgrp_SOURCES = newgrp.c
newgrp_OBJECTS = newgrp.$(OBJEXT)
newgrp_LDADD = $(LDADD)
newgrp_DEPENDENCIES = $(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/lib/libshadow.la
newgrp_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_2)
newusers_SOURCES = newusers.c
newusers_OBJECTS = newusers.$(OBJEXT)
newusers_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
nologin_SOURCES = nologin.c
nologin_OBJECTS = nologin.$(OBJEXT)
nologin_DEPENDENCIES =
passwd_SOURCES = passwd.c
passwd_OBJECTS = passwd.$(OBJEXT)
passwd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
@@ -206,18 +209,18 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = chage.c chfn.c chpasswd.c $(chsh_SOURCES) expiry.c faillog.c \
SOURCES = chage.c chfn.c chpasswd.c chsh.c expiry.c faillog.c \
gpasswd.c groupadd.c groupdel.c groupmod.c groups.c grpck.c \
grpconv.c grpunconv.c id.c lastlog.c $(login_SOURCES) \
logoutd.c newgrp.c newusers.c passwd.c pwck.c pwconv.c \
pwunconv.c $(su_SOURCES) sulogin.c useradd.c userdel.c \
usermod.c vipw.c
DIST_SOURCES = chage.c chfn.c chpasswd.c $(chsh_SOURCES) expiry.c \
faillog.c gpasswd.c groupadd.c groupdel.c groupmod.c groups.c \
grpck.c grpconv.c grpunconv.c id.c lastlog.c $(login_SOURCES) \
logoutd.c newgrp.c newusers.c passwd.c pwck.c pwconv.c \
pwunconv.c $(su_SOURCES) sulogin.c useradd.c userdel.c \
usermod.c vipw.c
logoutd.c newgrp.c newusers.c nologin.c passwd.c pwck.c \
pwconv.c pwunconv.c $(su_SOURCES) sulogin.c useradd.c \
userdel.c usermod.c vipw.c
DIST_SOURCES = chage.c chfn.c chpasswd.c chsh.c expiry.c faillog.c \
gpasswd.c groupadd.c groupdel.c groupmod.c groups.c grpck.c \
grpconv.c grpunconv.c id.c lastlog.c $(login_SOURCES) \
logoutd.c newgrp.c newusers.c nologin.c passwd.c pwck.c \
pwconv.c pwunconv.c $(su_SOURCES) sulogin.c useradd.c \
userdel.c usermod.c vipw.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -364,10 +367,6 @@ LDADD = $(top_builddir)/libmisc/libmisc.a \
AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
chage_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
chfn_LDADD = $(LDADD) $(LIBPAM)
chsh_SOURCES = \
chsh.c \
chsh_chkshell.c
chsh_LDADD = $(LDADD) $(LIBPAM)
chpasswd_LDADD = $(LDADD) $(LIBPAM)
gpasswd_LDADD = $(LDADD) $(LIBAUDIT)
@@ -378,8 +377,10 @@ login_SOURCES = \
login.c \
login_nopam.c
login_LDADD = $(LDADD) $(LIBPAM)
login_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
newgrp_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT)
newusers_LDADD = $(LDADD) $(LIBPAM)
nologin_LDADD =
passwd_LDADD = $(LDADD) $(LIBPAM) $(LIBCRACK) $(LIBAUDIT)
su_SOURCES = \
su.c \
@@ -573,6 +574,9 @@ newgrp$(EXEEXT): $(newgrp_OBJECTS) $(newgrp_DEPENDENCIES)
newusers$(EXEEXT): $(newusers_OBJECTS) $(newusers_DEPENDENCIES)
@rm -f newusers$(EXEEXT)
$(LINK) $(newusers_LDFLAGS) $(newusers_OBJECTS) $(newusers_LDADD) $(LIBS)
nologin$(EXEEXT): $(nologin_OBJECTS) $(nologin_DEPENDENCIES)
@rm -f nologin$(EXEEXT)
$(LINK) $(nologin_LDFLAGS) $(nologin_OBJECTS) $(nologin_LDADD) $(LIBS)
passwd$(EXEEXT): $(passwd_OBJECTS) $(passwd_DEPENDENCIES)
@rm -f passwd$(EXEEXT)
$(LINK) $(passwd_LDFLAGS) $(passwd_OBJECTS) $(passwd_LDADD) $(LIBS)
@@ -614,7 +618,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chfn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chpasswd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chsh.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chsh_chkshell.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expiry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/faillog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpasswd.Po@am__quote@
@@ -632,6 +635,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logoutd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newgrp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newusers.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nologin.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passwd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwck.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwconv.Po@am__quote@

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: chage.c,v 1.66 2005/10/04 20:26:41 kloczek Exp $"
#ident "$Id: chage.c,v 1.68 2005/12/02 19:42:25 kloczek Exp $"
#include <ctype.h>
#include <fcntl.h>
@@ -40,8 +40,7 @@
#include <sys/types.h>
#include <time.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include <pwd.h>
#ifdef WITH_SELINUX
@@ -233,8 +232,10 @@ static void list_fields (void)
* 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) {
if (lastday < 0) {
printf (_("never\n"));
} else if (lastday == 0) {
printf (_("password must be changed"));
} else {
changed = lastday * SCALE;
print_date (changed);
@@ -295,13 +296,6 @@ static void list_fields (void)
warndays);
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* cleanup - unlock any locked password files
*/

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: chfn.c,v 1.37 2005/10/04 20:25:55 kloczek Exp $"
#ident "$Id: chfn.c,v 1.38 2005/10/19 15:21:07 kloczek Exp $"
#include <fcntl.h>
#include <pwd.h>
@@ -196,13 +196,6 @@ 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
*

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: chpasswd.c,v 1.33 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: chpasswd.c,v 1.34 2005/10/19 15:21:07 kloczek Exp $"
#include <fcntl.h>
#include <getopt.h>
@@ -37,8 +37,7 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include "defines.h"
#include "nscd.h"
@@ -72,13 +71,6 @@ static void usage (void)
exit (1);
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
int main (int argc, char **argv)
{
char buf[BUFSIZ];

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: chsh.c,v 1.35 2005/10/04 21:02:22 kloczek Exp $"
#ident "$Id: chsh.c,v 1.37 2006/01/02 23:31:59 kloczek Exp $"
#include <fcntl.h>
#include <pwd.h>
@@ -107,12 +107,58 @@ 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 */
/*
* check_shell - see if the user's login shell is listed in /etc/shells
*
* The /etc/shells file is read for valid names of login shells. If the
* /etc/shells file does not exist the user cannot set any shell unless
* they are root.
*
* If getusershell() is available (Linux, *BSD, possibly others), use it
* instead of re-implementing it.
*/
int check_shell (const char *sh)
{
char *cp;
int found = 0;
#ifndef HAVE_GETUSERSHELL
char buf[BUFSIZ];
FILE *fp;
#endif
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((cp = getusershell ())) {
if (*cp == '#')
continue;
if (strcmp (cp, sh) == 0) {
found = 1;
break;
}
}
endusershell ();
#else
if ((fp = fopen (SHELLS_FILE, "r")) == (FILE *) 0)
return 0;
while (fgets (buf, sizeof (buf), fp)) {
if ((cp = strrchr (buf, '\n')))
*cp = '\0';
if (buf[0] == '#')
continue;
if (strcmp (buf, sh) == 0) {
found = 1;
break;
}
}
fclose (fp);
#endif
return found;
}
/*
* chsh - this command controls changes to the user's shell

View File

@@ -1,93 +0,0 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: chsh_chkshell.c,v 1.3 2005/08/31 17:25:00 kloczek Exp $"
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include "defines.h"
#include "prototypes.h"
#ifndef SHELLS_FILE
#define SHELLS_FILE "/etc/shells"
#endif
/*
* check_shell - see if the user's login shell is listed in /etc/shells
*
* The /etc/shells file is read for valid names of login shells. If the
* /etc/shells file does not exist the user cannot set any shell unless
* they are root.
*
* If getusershell() is available (Linux, *BSD, possibly others), use it
* instead of re-implementing it.
*/
int check_shell (const char *sh)
{
char *cp;
int found = 0;
#ifndef HAVE_GETUSERSHELL
char buf[BUFSIZ];
FILE *fp;
#endif
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((cp = getusershell ())) {
if (*cp == '#')
continue;
if (strcmp (cp, sh) == 0) {
found = 1;
break;
}
}
endusershell ();
#else
if ((fp = fopen (SHELLS_FILE, "r")) == (FILE *) 0)
return 0;
while (fgets (buf, sizeof (buf), fp)) {
if ((cp = strrchr (buf, '\n')))
*cp = '\0';
if (buf[0] == '#')
continue;
if (strcmp (buf, sh) == 0) {
found = 1;
break;
}
}
fclose (fp);
#endif
return found;
}

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: groupadd.c,v 1.48 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: groupadd.c,v 1.50 2005/12/06 20:24:03 kloczek Exp $"
#include <ctype.h>
#include <fcntl.h>
@@ -38,8 +38,7 @@
#include <stdio.h>
#include <sys/types.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#include <pwd.h>
#endif /* USE_PAM */
#include "chkname.h"
@@ -99,7 +98,7 @@ static void usage (void)
fprintf (stderr, _("Usage: groupadd [options] group\n"
"\n"
"Options:\n"
" -f, --force force exit with success status if the specified\n"
" -f, --force force exit with success status if the specified\n"
" group already exists\n"
" -g, --gid GID use GID for the new group\n"
" -h, --help display this help message and exit\n"
@@ -370,13 +369,6 @@ static void fail_exit (int code)
exit (code);
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* main - groupadd command
*/

View File

@@ -29,15 +29,14 @@
#include <config.h>
#ident "$Id: groupdel.c,v 1.29 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: groupdel.c,v 1.30 2005/10/19 15:21:07 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>
#include "pam_defs.h"
#endif /* USE_PAM */
#include <stdio.h>
#include <sys/types.h>
@@ -202,13 +201,6 @@ static void group_busy (gid_t gid)
exit (E_GROUP_BUSY);
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* main - groupdel command
*

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: groupmod.c,v 1.36 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: groupmod.c,v 1.37 2005/10/19 15:21:07 kloczek Exp $"
#include <ctype.h>
#include <fcntl.h>
@@ -37,8 +37,7 @@
#include <stdio.h>
#include <sys/types.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#include <pwd.h>
#endif /* USE_PAM */
#include "chkname.h"
@@ -412,13 +411,6 @@ static void open_files (void)
#endif /* SHADOWGRP */
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* main - groupmod command
*

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: login.c,v 1.74 2005/09/07 15:00:45 kloczek Exp $"
#ident "$Id: login.c,v 1.77 2005/12/13 14:04:54 kloczek Exp $"
#include <errno.h>
#include <grp.h>
@@ -49,10 +49,6 @@
#include "pwauth.h"
#ifdef USE_PAM
#include "pam_defs.h"
static const struct pam_conv conv = {
misc_conv,
NULL
};
static pam_handle_t *pamh = NULL;
@@ -646,6 +642,32 @@ int main (int argc, char **argv)
#ifdef HAVE_PAM_FAIL_DELAY
pam_fail_delay (pamh, 1000000 * delay);
#endif
#ifdef WITH_AUDIT
{
struct passwd *pw;
char buf[64];
audit_fd = audit_open ();
pw = getpwnam (username);
if (pw) {
snprintf (buf, sizeof (buf),
"uid=%d", pw->pw_uid);
audit_log_user_message
(audit_fd, AUDIT_USER_LOGIN,
buf, hostname, NULL,
tty, 0);
} else {
snprintf (buf, sizeof (buf),
"acct=%s", username);
audit_log_user_message
(audit_fd, AUDIT_USER_LOGIN,
buf, hostname, NULL,
tty, 0);
}
close (audit_fd);
}
#endif /* WITH_AUDIT */
fprintf (stderr, _("\nLogin incorrect\n"));
pam_set_item (pamh, PAM_USER, NULL);
retcode = pam_authenticate (pamh, 0);
@@ -667,6 +689,33 @@ int main (int argc, char **argv)
hostname, pam_user,
pam_strerror (pamh, retcode)));
#ifdef WITH_AUDIT
{
struct passwd *pw;
char buf[64];
audit_fd = audit_open ();
pw = getpwnam (username);
if (pw) {
snprintf (buf, sizeof (buf),
"uid=%d", pw->pw_uid);
audit_log_user_message
(audit_fd, AUDIT_USER_LOGIN,
buf, hostname, NULL,
tty, 0);
} else {
snprintf (buf, sizeof (buf),
"acct=%s", username);
audit_log_user_message
(audit_fd, AUDIT_USER_LOGIN,
buf, hostname, NULL,
tty, 0);
}
close (audit_fd);
}
#endif /* WITH_AUDIT */
fprintf (stderr, "\nLogin incorrect\n");
pam_end (pamh, retcode);
exit (0);
@@ -916,6 +965,19 @@ int main (int argc, char **argv)
#endif
goto top; /* go do all this all over again */
}
#ifdef WITH_AUDIT
{
char buf[32];
audit_fd = audit_open ();
snprintf (buf, sizeof (buf), "uid=%d", pwd->pw_uid);
audit_log_user_message (audit_fd, AUDIT_USER_LOGIN,
buf, hostname, NULL, tty, 1);
close (audit_fd);
}
#endif /* WITH_AUDIT */
#ifndef USE_PAM /* pam_lastlog handles this */
if (getdef_bool ("LASTLOG_ENAB")) /* give last login and log this one */
dolastlog (&lastlog, &pwent, utent.ut_line, hostname);

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: newgrp.c,v 1.41 2005/09/07 15:00:45 kloczek Exp $"
#ident "$Id: newgrp.c,v 1.42 2005/11/10 16:01:27 kloczek Exp $"
#include <errno.h>
#include <grp.h>
@@ -118,6 +118,9 @@ int main (int argc, char **argv)
struct sgrp *sgrp;
#endif
#ifdef WITH_AUDIT
audit_help_open ();
#endif
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -157,6 +160,10 @@ int main (int argc, char **argv)
pwd = get_my_pwent ();
if (!pwd) {
fprintf (stderr, _("unknown UID: %u\n"), getuid ());
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing", NULL,
getuid (), 0);
#endif
SYSLOG ((LOG_WARN, "unknown UID %u", getuid ()));
closelog ();
exit (1);
@@ -261,6 +268,10 @@ int main (int argc, char **argv)
}
if (ngroups < 0) {
perror ("getgroups");
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog,
"changing", NULL, getuid (), 0);
#endif
exit (1);
}
#endif /* HAVE_SETGROUPS */
@@ -453,6 +464,10 @@ int main (int argc, char **argv)
/* error in fork() */
fprintf (stderr, _("%s: failure forking: %s"),
is_newgrp ? "newgrp" : "sg", strerror (errno));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing",
NULL, getuid (), 0);
#endif
exit (1);
} else if (child) {
/* parent - wait for child to finish, then log session close */
@@ -523,6 +538,10 @@ int main (int argc, char **argv)
if (setuid (getuid ())) {
perror ("setuid");
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing",
NULL, getuid (), 0);
#endif
exit (1);
}
@@ -533,6 +552,10 @@ int main (int argc, char **argv)
if (cflag) {
closelog ();
execl ("/bin/sh", "sh", "-c", command, (char *) 0);
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing",
NULL, getuid (), 0);
#endif
if (errno == ENOENT) {
perror ("/bin/sh");
exit (127);
@@ -601,6 +624,9 @@ int main (int argc, char **argv)
addenv (*envp++, NULL);
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing", NULL, getuid (), 1);
#endif
/*
* Exec the login shell and go away. We are trying to get back to
* the previous environment which should be the user's login shell.
@@ -620,5 +646,8 @@ int main (int argc, char **argv)
* harm. -- JWP
*/
closelog ();
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_START, Prog, "changing", NULL, getuid (), 0);
#endif
exit (1);
}

View File

@@ -35,7 +35,7 @@
#include <config.h>
#ident "$Id: newusers.c,v 1.30 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: newusers.c,v 1.31 2005/10/19 15:21:07 kloczek Exp $"
#include <sys/types.h>
#include <sys/stat.h>
@@ -44,8 +44,7 @@
#include <grp.h>
#include <fcntl.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include "prototypes.h"
#include "defines.h"
@@ -274,13 +273,6 @@ static int add_passwd (struct passwd *pwd, const char *passwd)
return !spw_update (&spent);
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
int main (int argc, char **argv)
{
char buf[BUFSIZ];

47
src/nologin.c Normal file
View File

@@ -0,0 +1,47 @@
/*-
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: nologin.c,v 1.1 2005/11/25 03:27:06 kloczek Exp $"
#include <stdio.h>
#include <syslog.h>
#include <unistd.h>
#include "exitcodes.h"
int main (int argc, char **argv)
{
const char *user, *tty;
if ((tty = ttyname (0)) == NULL)
tty = "UNKNOWN";
if ((user = getlogin ()) == NULL)
user = "UNKNOWN";
openlog ("nologin", LOG_CONS, LOG_AUTH);
syslog (LOG_CRIT, "Attempted login by %s on %s", user, tty);
closelog ();
printf ("%s", "This account is currently not available.\n");
return E_NOPERM;
}

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: passwd.c,v 1.52 2005/09/07 15:00:45 kloczek Exp $"
#ident "$Id: passwd.c,v 1.55 2005/12/06 20:19:52 kloczek Exp $"
#include <errno.h>
#include <fcntl.h>
@@ -142,8 +142,8 @@ static void usage (int status)
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"
" -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"
@@ -632,40 +632,6 @@ int main (int argc, char **argv)
OPENLOG ("passwd");
/*
* Start with the flags which cause another command to be executed.
* The effective UID will be set back to the real UID and the new
* command executed with the flags
*
* 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];
setuid (getuid ());
switch (argv[1][1]) {
case 'g':
argv[1] = GPASSWD_PROGRAM; /* XXX warning: const */
break;
case 'f':
argv[1] = CHFN_PROGRAM; /* XXX warning: const */
break;
case 's':
argv[1] = CHSH_PROGRAM; /* XXX warning: const */
break;
default:
usage (E_BAD_ARG);
}
snprintf (buf, sizeof buf, _("%s: Cannot execute %s"),
Prog, argv[1]);
execvp (argv[1], &argv[1]);
perror (buf);
SYSLOG ((LOG_ERR, "cannot execute %s", argv[1]));
closelog ();
exit (E_FAILURE);
}
{
/*
* Parse the command line options.

322
src/su.c
View File

@@ -29,8 +29,9 @@
#include <config.h>
#ident "$Id: su.c,v 1.45 2005/09/07 15:00:45 kloczek Exp $"
#ident "$Id: su.c,v 1.61 2006/01/02 22:37:47 kloczek Exp $"
#include <getopt.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
@@ -38,6 +39,7 @@
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
#include "exitcodes.h"
#include "pwauth.h"
#include "getdef.h"
#ifdef USE_PAM
@@ -53,12 +55,10 @@
static char name[BUFSIZ];
static char oldname[BUFSIZ];
#ifdef USE_PAM
static const struct pam_conv conv = {
misc_conv,
NULL
};
/* If nonzero, change some environment vars to indicate the user su'd to. */
static int change_environment;
#ifdef USE_PAM
static pam_handle_t *pamh = NULL;
static int caught = 0;
#endif
@@ -114,6 +114,21 @@ static int iswheel (const char *username)
}
#endif /* !USE_PAM */
/* borrowed from GNU sh-utils' "su.c" */
static int restricted_shell (const char *shellstr)
{
char *line;
setusershell ();
while ((line = getusershell ()) != NULL) {
if (*line != '#' && strcmp (line, shellstr) == 0) {
endusershell ();
return 0;
}
}
endusershell ();
return 1;
}
static void su_failure (const char *tty)
{
@@ -163,7 +178,7 @@ static void run_shell (const char *shellstr, char *args[], int doshell)
}
} else if (child == -1) {
(void) fprintf (stderr, "%s: Cannot fork user shell\n", Prog);
SYSLOG ((LOG_WARN, "Cannot execute %s", pwent.pw_shell));
SYSLOG ((LOG_WARN, "Cannot execute %s", shellstr));
closelog ();
exit (1);
}
@@ -233,15 +248,29 @@ static void run_shell (const char *shellstr, char *args[], int doshell)
}
#endif
/*
* usage - print command line syntax and exit
*/
static void usage (void)
{
fprintf (stderr, _("Usage: su [options] [login]\n"
"\n"
"Options:\n"
" -h, --help display this help message and exit\n"
" -, -l, --login make the shell a login shell\n"
" -m, -p,\n"
" --preserve-environment do not reset environment variables, and keep\n"
" the same shell\n"
" -s, --shell SHELL use SHELL instead of the default in passwd\n"));
exit (E_USAGE);
}
/*
* su - switch user id
*
* su changes the user's ids to the values for the specified user. if
* no new user name is specified, "root" is used by default.
*
* The only valid option is a "-" character, which is interpreted as
* requiring a new login session to be simulated.
*
* Any additional arguments are passed to the user's shell. In
* particular, the argument "-c" will cause the next argument to be
* interpreted as a command by the common shell programs.
@@ -257,6 +286,7 @@ int main (int argc, char **argv)
uid_t my_uid;
struct passwd *pw = 0;
char **envp = environ;
char *shellstr = 0;
#ifdef USE_PAM
int ret;
@@ -277,6 +307,8 @@ int main (int argc, char **argv)
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
change_environment = 1;
/*
* Get the program name. The program name is used as a prefix to
* most error messages.
@@ -285,6 +317,68 @@ int main (int argc, char **argv)
OPENLOG ("su");
/*
* Process the command line arguments.
*/
{
/*
* Parse the command line options.
*/
int option_index = 0;
int c;
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"login", no_argument, NULL, 'l'},
{"preserve-environment", no_argument, NULL, 'p'},
{"shell", required_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}
};
while ((c =
getopt_long (argc, argv, "-hlmps:", long_options,
&option_index)) != -1) {
switch (c) {
case 1:
/* this is not an su option */
/* The next arguments are either '-', the
* target name, or arguments to be passed
* to the shell.
*/
/* rewind the (not yet handled) option */
optind--;
goto end_su_options;
break; /* NOT REACHED */
case 'h':
usage ();
break;
case 'l':
fakelogin = 1;
break;
case 'm':
case 'p':
/* This will only have an effect if the target
* user do not have a restricted shell, or if
* su is called by root.
*/
change_environment = 0;
break;
case 's':
shellstr = optarg;
break;
default:
usage (); /* NOT REACHED */
}
}
end_su_options:
if (optind < argc && !strcmp (argv[optind], "-")) {
fakelogin = 1;
optind++;
if (optind < argc && !strcmp (argv[optind], "--"))
optind++;
}
}
initenv ();
my_uid = getuid ();
@@ -314,68 +408,21 @@ int main (int argc, char **argv)
tty = "???";
}
/*
* Process the command line arguments.
*/
argc--;
argv++; /* shift out command name */
if (argc > 0 && strcmp (argv[0], "-") == 0) {
fakelogin = 1;
argc--;
argv++; /* shift ... */
}
/*
* 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
* the environment already.
*/
if ((cp = getenv ("TERM")))
addenv ("TERM", cp);
#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.
*/
if ((cp = getenv ("DISPLAY")))
addenv ("DISPLAY", cp);
if ((cp = getenv ("XAUTHORITY")))
addenv ("XAUTHORITY", cp);
#endif /* !USE_PAM */
} else {
while (*envp)
addenv (*envp++, NULL);
}
/*
* The next argument must be either a user ID, or some flag to a
* subshell. Pretty sticky since you can't have an argument which
* 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--;
argv++; /* shift ... */
if (optind < argc && argv[optind][0] != '-') {
STRFCPY (name, argv[optind++]); /* use this login id */
if (optind < argc && !strcmp (argv[optind], "--"))
optind++;
}
if (!name[0]) /* use default user ID */
(void) strcpy (name, "root");
doshell = argc == 0; /* any arguments remaining? */
doshell = argc == optind; /* any arguments remaining? */
/*
* Get the user's real name. The current UID is used to determine
@@ -442,6 +489,48 @@ int main (int argc, char **argv)
#endif /* !USE_PAM */
pwent = *pw;
/* If su is not called by root, and the target user has a restricted
* shell, the environment must be changed.
*/
change_environment |= (restricted_shell (pwent.pw_shell) && !amroot);
/*
* If a new login is being set up, the old environment will be
* ignored and a new one created later on.
* (note: in the case of a subsystem, the shell will be restricted,
* and this won't be executed on the first pass)
*/
if (fakelogin && change_environment) {
/*
* The terminal type will be left alone if it is present in
* the environment already.
*/
if ((cp = getenv ("TERM")))
addenv ("TERM", cp);
#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.
*/
if ((cp = getenv ("DISPLAY")))
addenv ("DISPLAY", cp);
if ((cp = getenv ("XAUTHORITY")))
addenv ("XAUTHORITY", cp);
#endif /* !USE_PAM */
} else {
while (*envp)
addenv (*envp++, NULL);
}
#ifndef USE_PAM
/*
* BSD systems only allow "wheel" to SU to root. USG systems don't,
@@ -476,7 +565,7 @@ int main (int argc, char **argv)
pwent.pw_passwd = ""; /* XXX warning: const */
break;
case 2: /* require own password */
puts (_("(Enter your own password.)"));
puts (_("(Enter your own password)"));
pwent.pw_passwd = oldpass;
break;
default: /* access denied (-1) or unexpected value */
@@ -488,11 +577,28 @@ int main (int argc, char **argv)
}
#endif /* !USE_PAM */
/* If the user do not want to change the environment,
* use the current SHELL.
* (unless another shell is required by the command line)
*/
if (shellstr == NULL && change_environment == 0)
shellstr = getenv ("SHELL");
/* For users with non null UID, if this user has a restricted
* shell, the shell must be the one specified in /etc/passwd
*/
if (shellstr != NULL && !amroot && restricted_shell (pwent.pw_shell))
shellstr = NULL;
/* If the shell is not set at this time, use the shell specified
* in /etc/passwd.
*/
if (shellstr == NULL)
shellstr = (char *) strdup (pwent.pw_shell);
/*
* Set the default shell.
*/
if (pwent.pw_shell[0] == '\0')
pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
if (shellstr == NULL || shellstr[0] == '\0')
shellstr = "/bin/sh";
signal (SIGINT, SIG_IGN);
signal (SIGQUIT, SIG_IGN);
@@ -511,6 +617,16 @@ int main (int argc, char **argv)
if (amroot) {
fprintf (stderr, _("%s: %s\n(Ignored)\n"), Prog,
pam_strerror (pamh, ret));
} else if (ret == PAM_NEW_AUTHTOK_REQD) {
ret = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (ret != PAM_SUCCESS) {
SYSLOG ((LOG_ERR, "pam_chauthtok: %s",
pam_strerror (pamh, ret)));
fprintf (stderr, _("%s: %s\n"), Prog,
pam_strerror (pamh, ret));
pam_end (pamh, ret);
su_failure (tty);
}
} else {
SYSLOG ((LOG_ERR, "pam_acct_mgmt: %s",
pam_strerror (pamh, ret)));
@@ -548,10 +664,12 @@ int main (int argc, char **argv)
if (!spwd)
spwd = pwd_to_spwd (&pwent);
if (isexpired (&pwent, spwd)) {
SYSLOG ((pwent.pw_uid ? LOG_WARN : LOG_CRIT,
"Expired account %s", name));
su_failure (tty);
if (expire (&pwent, spwd)) {
struct passwd *pwd = getpwnam (name);
spwd = getspnam (name);
if (pwd)
pwent = *pwd;
}
}
@@ -591,6 +709,11 @@ int main (int argc, char **argv)
if (getenv ("IFS")) /* don't export user IFS ... */
addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
/*
* Even if --shell is specified, the subsystem login test is based on
* the shell specified in /etc/passwd (not the one specified with
* --shell, which will be the one executed in the chroot later).
*/
if (pwent.pw_shell[0] == '*') { /* subsystem root required */
pwent.pw_shell++; /* skip the '*' */
subsystem (&pwent); /* figure out what to execute */
@@ -636,18 +759,20 @@ int main (int argc, char **argv)
exit (1);
}
/* we need to setup the environment *after* pam_open_session(),
* else the UID is changed before stuff like pam_xauth could
* run, and we cannot access /etc/shadow and co
*/
environ = newenvp; /* make new environment active */
if (change_environment) {
/* we need to setup the environment *after* pam_open_session(),
* else the UID is changed before stuff like pam_xauth could
* run, and we cannot access /etc/shadow and co
*/
environ = newenvp; /* make new environment active */
/* update environment with all pam set variables */
envcp = pam_getenvlist (pamh);
if (envcp) {
while (*envcp) {
addenv (*envcp, NULL);
envcp++;
/* update environment with all pam set variables */
envcp = pam_getenvlist (pamh);
if (envcp) {
while (*envcp) {
addenv (*envcp, NULL);
envcp++;
}
}
}
@@ -665,12 +790,17 @@ int main (int argc, char **argv)
exit (1);
#endif /* !USE_PAM */
if (fakelogin)
setup_env (&pwent);
#if 1 /* Suggested by Joey Hess. XXX - is this right? */
else
addenv ("HOME", pwent.pw_dir);
#endif
if (change_environment) {
if (fakelogin) {
pwent.pw_shell = shellstr;
setup_env (&pwent);
} else {
addenv ("HOME", pwent.pw_dir);
addenv ("USER", pwent.pw_name);
addenv ("LOGNAME", pwent.pw_name);
addenv ("SHELL", shellstr);
}
}
/*
* This is a workaround for Linux libc bug/feature (?) - the
@@ -690,35 +820,37 @@ int main (int argc, char **argv)
cp = getdef_str ("SU_NAME");
if (!cp)
cp = Basename (pwent.pw_shell);
cp = Basename (shellstr);
arg0 = xmalloc (strlen (cp) + 2);
arg0[0] = '-';
strcpy (arg0 + 1, cp);
cp = arg0;
} else
cp = Basename (pwent.pw_shell);
cp = Basename (shellstr);
if (!doshell) {
/* Position argv to the remaining arguments */
argv += optind;
/*
* Use new user's shell from /etc/passwd and create an argv
* Use the shell and create an argv
* with the rest of the command line included.
*/
argv[-1] = pwent.pw_shell;
argv[-1] = shellstr;
#ifndef USE_PAM
(void) execv (pwent.pw_shell, &argv[-1]);
(void) execv (shellstr, &argv[-1]);
#else
run_shell (pwent.pw_shell, &argv[-1], 0);
run_shell (shellstr, &argv[-1], 0);
#endif
(void) fprintf (stderr, _("No shell\n"));
SYSLOG ((LOG_WARN, "Cannot execute %s", pwent.pw_shell));
SYSLOG ((LOG_WARN, "Cannot execute %s", shellstr));
closelog ();
exit (1);
}
#ifndef USE_PAM
shell (pwent.pw_shell, cp);
shell (shellstr, cp);
#else
run_shell (pwent.pw_shell, &cp, 1);
run_shell (shellstr, &cp, 1);
#endif
/* NOT REACHED */
exit (1);

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: useradd.c,v 1.84 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: useradd.c,v 1.89 2005/12/15 15:06:28 kloczek Exp $"
#include <ctype.h>
#include <errno.h>
@@ -39,8 +39,7 @@
#include <lastlog.h>
#include <pwd.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include <stdio.h>
#include <sys/stat.h>
@@ -527,11 +526,6 @@ static int get_groups (char *list)
int errors = 0;
int ngroups = 0;
/*
* Initialize the list to be empty
*/
user_groups[0] = (char *) 0;
if (!*list)
return 0;
@@ -595,7 +589,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);
@@ -631,7 +624,7 @@ static void usage (void)
" -G, --groups GROUPS list of supplementary groups for the new\n"
" user account\n"
" -h, --help display this help message and exit\n"
" -k, --skel SKEL_DIR specify an alternative skel directory\n"
" -k, --skel SKEL_DIR specify an alternative skel directory\n"
" -K, --key KEY=VALUE overrides /etc/login.defs defaults\n"
" -m, --create-home create home directory for the new user\n"
" account\n"
@@ -711,29 +704,30 @@ static void grp_update (void)
#endif
/*
* Lock and open the group file. This will load all of the group
* entries.
* Test for unique entries of user_groups in /etc/group
* pvrabec@redhat.com
*/
if (!gr_lock ()) {
fprintf (stderr, _("%s: error locking group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
char **user_groups_tmp = user_groups;
while (*user_groups_tmp) {
int count = 0;
for (gr_rewind (), grp = gr_next (); grp && count < 2;
grp = gr_next ()) {
if (strcmp (*user_groups_tmp, grp->gr_name) == 0) {
count++;
}
}
if (count > 1) {
fprintf (stderr,
"%s: error not unique group names in group file\n",
Prog);
fail_exit (E_GRP_UPDATE);
}
user_groups_tmp++;
}
if (!gr_open (O_RDWR)) {
fprintf (stderr, _("%s: error opening group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp && !sgr_lock ()) {
fprintf (stderr,
_("%s: error locking shadow group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
if (is_shadow_grp && !sgr_open (O_RDWR)) {
fprintf (stderr,
_("%s: error opening shadow group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#endif
/* Locking and opening of the group files moved to open_files() --gafton */
/*
* Scan through the entire group file looking for the groups that
@@ -910,6 +904,80 @@ static void find_new_uid (void)
}
}
/*
* find_new_gid - find the next available GID
*
* find_new_gid() locates the next highest unused GID in the group
* file, or checks the given group ID against the existing ones for
* uniqueness.
*/
static void find_new_gid ()
{
const struct group *grp;
gid_t gid_min, gid_max;
gid_min = getdef_num ("GID_MIN", 500);
gid_max = getdef_num ("GID_MAX", 60000);
/*
* Start with some GID value if the user didn't provide us with
* one already.
*/
user_gid = gid_min;
/*
* Search the entire group file, either looking for this
* GID (if the user specified one with -g) or looking for the
* largest unused value.
*/
#ifdef NO_GETGRENT
gr_rewind ();
while ((grp = gr_next ()))
#else
setgrent ();
while ((grp = getgrent ()))
#endif
{
if (strcmp (user_name, grp->gr_name) == 0) {
user_gid = grp->gr_gid;
return;
}
if (grp->gr_gid >= user_gid) {
if (grp->gr_gid > gid_max)
continue;
user_gid = grp->gr_gid + 1;
}
}
#ifndef NO_GETGRENT /* glibc does have this, so ... */
/* A quick test gets here: if the UID is available
* as a GID, go ahead and use it */
if (!getgrgid (user_id)) {
user_gid = user_id;
return;
}
#endif
if (user_gid == gid_max + 1) {
for (user_gid = gid_min; user_gid < gid_max; user_gid++) {
#ifdef NO_GETGRENT
gr_rewind ();
while ((grp = gr_next ()) && grp->gr_gid != user_gid);
if (!grp)
break;
#else
if (!getgrgid (user_gid))
break;
#endif
}
if (user_gid == gid_max) {
fprintf (stderr,
"%s: can't get unique gid (run out of GIDs)\n",
Prog);
fail_exit (4);
}
}
}
/*
* process_flags - perform command line argument setting
*
@@ -1268,8 +1336,110 @@ static void open_files (void)
pw_unlock ();
exit (E_PW_UPDATE);
}
/*
* Lock and open the group file.
*/
if (!gr_lock ()) {
fprintf (stderr, _("%s: error locking group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
if (!gr_open (O_RDWR)) {
fprintf (stderr, _("%s: error opening group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp && !sgr_lock ()) {
fprintf (stderr,
_("%s: error locking shadow group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
if (is_shadow_grp && !sgr_open (O_RDWR)) {
fprintf (stderr,
_("%s: error opening shadow group file\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#endif
}
static char *empty_list = NULL;
/*
* new_grent - initialize the values in a group file entry
*
* 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);
grent->gr_name = (char *) user_name;
grent->gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
grent->gr_gid = user_gid;
grent->gr_mem = &empty_list;
}
#ifdef SHADOWGRP
/*
* new_sgent - initialize the values in a shadow group file entry
*
* 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);
sgent->sg_name = (char *) user_name;
sgent->sg_passwd = "!"; /* XXX warning: const */
sgent->sg_adm = &empty_list;
sgent->sg_mem = &empty_list;
}
#endif /* SHADOWGRP */
/*
* grp_add - add new group file entries
*
* grp_add() writes the new records to the group files.
*/
static void grp_add (void)
{
struct group grp;
#ifdef SHADOWGRP
struct sgrp sgrp;
#endif /* SHADOWGRP */
/*
* Create the initial entries for this new group.
*/
new_grent (&grp);
#ifdef SHADOWGRP
new_sgent (&sgrp);
#endif /* SHADOWGRP */
/*
* Write out the new group file entry.
*/
if (!gr_update (&grp)) {
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
/*
* Write out the new shadow group entries as well.
*/
if (is_shadow_grp && !sgr_update (&sgrp)) {
fprintf (stderr, _("%s: error adding new group entry\n"), Prog);
fail_exit (E_GRP_UPDATE);
}
#endif /* SHADOWGRP */
SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid));
do_grp_update++;
}
static void faillog_reset (uid_t uid)
{
@@ -1455,13 +1625,6 @@ static void create_mail (void)
}
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* main - useradd command
*/
@@ -1490,6 +1653,11 @@ int main (int argc, char **argv)
sys_ngroups = sysconf (_SC_NGROUPS_MAX);
user_groups = malloc ((1 + sys_ngroups) * sizeof (char *));
/*
* Initialize the list to be empty
*/
user_groups[0] = (char *) 0;
is_shadow_pwd = spw_file_present ();
#ifdef SHADOWGRP
@@ -1587,6 +1755,18 @@ int main (int argc, char **argv)
*/
open_files ();
/* first, seek for a valid uid to use for this user.
* We do this because later we can use the uid we found as
* gid too ... --gafton */
find_new_uid ();
/* do we have to add a group for that user? This is why we need to
* open the group files in the open_files() function --gafton */
if (!(nflg || gflg)) {
find_new_gid ();
grp_add ();
}
usr_update ();
if (mflg) {

View File

@@ -29,7 +29,7 @@
#include <config.h>
#ident "$Id: userdel.c,v 1.52 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: userdel.c,v 1.58 2005/12/01 20:10:48 kloczek Exp $"
#include <errno.h>
#include <fcntl.h>
@@ -40,8 +40,7 @@
#include <sys/stat.h>
#include <sys/stat.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include "defines.h"
#include "getdef.h"
@@ -66,7 +65,9 @@
#define E_HOMEDIR 12 /* can't remove home directory */
static char *user_name;
static uid_t user_id;
static gid_t user_gid;
static char *user_home;
static char *user_group;
static char *Prog;
static int fflg = 0, rflg = 0;
@@ -171,23 +172,26 @@ static void update_groups (void)
if (grp && getdef_bool ("USERGROUPS_ENAB")
&& (grp->gr_mem[0] == NULL)) {
/*
* 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;
pwd = NULL;
if (!fflg) {
/*
* 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 ();
}
endpwent ();
if (pwd == NULL) {
/*
@@ -259,6 +263,65 @@ static void update_groups (void)
#endif /* SHADOWGRP */
}
/*
* remove_group - remove the user's group unless it is not really a user-private group
*/
static void remove_group ()
{
char *glist_name;
struct group *gr;
struct passwd *pwd;
if (user_group == NULL || user_name == NULL)
return;
if (strcmp (user_name, user_group)) {
return;
}
glist_name = NULL;
gr = getgrnam (user_group);
if (gr)
glist_name = *(gr->gr_mem);
while (glist_name) {
while (glist_name && *glist_name) {
if (strncmp (glist_name, user_name, 16)) {
return;
}
glist_name++;
}
}
setpwent ();
while ((pwd = getpwent ())) {
if (strcmp (pwd->pw_name, user_name) == 0)
continue;
if (pwd->pw_gid == user_gid) {
return;
}
}
/* now actually do the removal if we haven't already returned */
if (!gr_remove (user_group)) {
fprintf (stderr, _("%s: error removing group entry\n"), Prog);
}
#ifdef SHADOWGRP
/*
* Delete the shadow group entries as well.
*/
if (is_shadow_grp && !sgr_remove (user_group)) {
fprintf (stderr, _("%s: error removing shadow group entry\n"),
Prog);
}
#endif /* SHADOWGRP */
SYSLOG ((LOG_INFO, "remove group `%s'\n", user_group));
return;
}
/*
* close_files - close all of the files that were opened
*
@@ -583,23 +646,18 @@ static void remove_mailbox (void)
#ifdef WITH_AUDIT
else {
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting mail file",
user_name, user_id, 0);
user_name, user_id, 1);
}
#endif
}
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv, NULL
};
#endif /* USE_PAM */
/*
* main - userdel command
*/
int main (int argc, char **argv)
{
struct passwd *pwd;
struct group *grp;
int arg;
int errors = 0;
@@ -707,6 +765,10 @@ int main (int argc, char **argv)
#endif
user_id = pwd->pw_uid;
user_home = xstrdup (pwd->pw_dir);
user_gid = pwd->pw_gid;
grp = getgrgid (user_gid);
if (grp)
user_group = xstrdup (grp->gr_name);
/*
* Check to make certain the user isn't logged in.
*/
@@ -760,6 +822,9 @@ int main (int argc, char **argv)
}
#endif
/* Remove the user's group if appropriate. */
remove_group ();
if (rflg) {
if (remove_tree (user_home)
|| rmdir (user_home)) {

View File

@@ -29,17 +29,17 @@
#include <config.h>
#ident "$Id: usermod.c,v 1.58 2005/10/04 21:05:12 kloczek Exp $"
#ident "$Id: usermod.c,v 1.64 2005/12/05 18:19:47 kloczek Exp $"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <grp.h>
#include <lastlog.h>
#include <pwd.h>
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "pam_defs.h"
#endif /* USE_PAM */
#include <stdio.h>
#include <sys/stat.h>
@@ -68,12 +68,12 @@
#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))
/*
@@ -271,16 +271,27 @@ static int get_groups (char *list)
*/
static void usage (void)
{
fprintf (stderr,
_
("Usage: %s\t[-u uid [-o]] [-g group] [[-G group,...] [-a]] \n"),
Prog);
fprintf (stderr,
_
("\t\t[-d home [-m]] [-s shell] [-c comment] [-l new_name]\n"));
fprintf (stderr, "\t\t");
fprintf (stderr, _("[-f inactive] [-e expire] "));
fprintf (stderr, _("[-p passwd] [-L|-U] name\n"));
fprintf (stderr, _("Usage: usermod [options] login\n"
"\n"
"Options:\n"
" -a, --append GROUP append the user to the supplemental GROUP\n"
" -c, --comment COMMENT new value of the GECOS field\n"
" -d, --home HOME_DIR new login directory for the new user account\n"
" -e, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"
" -f, --inactive INACTIVE set password inactive after expiration\n"
" to INACTIVE\n"
" -g, --gid GROUP force use GROUP as new initial login group\n"
" -G, --groups GROUPS list of supplementary GROUPS\n"
" -h, --help display this help message and exit\n"
" -l, --login LOGIN new value of the login name\n"
" -L, --lock lock the user account\n"
" -m, --move-home move contents of the home directory to the new\n"
" location (use only with -d)\n"
" -o, --non-unique allow using duplicate (non-unique) UID\n"
" -p, --password PASSWORD use encrypted password for the new password\n"
" -s, --shell SHELL new login shell for the user account\n"
" -u, --uid UID new UID for the user account\n"
" -U, --unlock unlock the user account\n"));
exit (E_USAGE);
}
@@ -884,159 +895,187 @@ static void process_flags (int argc, char **argv)
#endif
}
while ((arg = getopt (argc, argv, "ac:d:e:f:g:G:l:Lmop:s:u:U")) != EOF) {
switch (arg) {
case 'a':
aflg++;
break;
case 'c':
if (!VALID (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
#ifdef WITH_AUDIT
user_newcomment = optarg;
#else
user_comment = optarg;
#endif
cflg++;
break;
case 'd':
if (!VALID (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
dflg++;
user_newhome = optarg;
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
{
/*
* Parse the command line options.
*/
int c;
static struct option long_options[] = {
{"append", required_argument, NULL, 'a'},
{"comment", required_argument, NULL, 'c'},
{"home", required_argument, NULL, 'd'},
{"expiredate", required_argument, NULL, 'e'},
{"inactive", required_argument, NULL, 'f'},
{"gid", required_argument, NULL, 'g'},
{"groups", required_argument, NULL, 'G'},
{"help", no_argument, NULL, 'h'},
{"login", required_argument, NULL, 'l'},
{"lock", no_argument, NULL, 'L'},
{"move-home", no_argument, NULL, 'm'},
{"non-unique", no_argument, NULL, 'o'},
{"password", required_argument, NULL, 'p'},
{"shell", required_argument, NULL, 's'},
{"uid", required_argument, NULL, 'u'},
{"unlock", no_argument, NULL, 'U'},
{NULL, 0, NULL, '\0'}
};
while ((c =
getopt_long (argc, argv, "ac:d:e:f:g:G:l:Lmop:s:u:U",
long_options, NULL)) != -1) {
switch (c) {
case 'a':
aflg++;
break;
case 'c':
if (!VALID (optarg)) {
fprintf (stderr,
_
("%s: invalid date `%s'\n"),
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
#ifdef WITH_AUDIT
user_newexpire *= DAY / SCALE;
user_newcomment = optarg;
#else
user_expire *= DAY / SCALE;
user_comment = optarg;
#endif
} else
cflg++;
break;
case 'd':
if (!VALID (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
dflg++;
user_newhome = optarg;
break;
case 'e':
if (*optarg) {
#ifdef WITH_AUDIT
user_newexpire = -1;
user_newexpire = strtoday (optarg);
if (user_newexpire == -1) {
#else
user_expire = -1;
user_expire = strtoday (optarg);
if (user_expire == -1) {
#endif
eflg++;
break;
case 'f':
fprintf (stderr,
_
("%s: invalid date `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
#ifdef WITH_AUDIT
user_newinactive = get_number (optarg);
user_newexpire *= DAY / SCALE;
#else
user_inactive = get_number (optarg);
user_expire *= DAY / SCALE;
#endif
fflg++;
break;
case 'g':
grp = getgr_nam_gid (optarg);
if (!grp) {
fprintf (stderr,
_("%s: unknown group %s\n"),
Prog, optarg);
exit (E_NOTFOUND);
}
user_newgid = grp->gr_gid;
gflg++;
break;
case 'G':
if (get_groups (optarg))
exit (E_NOTFOUND);
Gflg++;
break;
case 'l':
if (!check_user_name (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
/*
* If the name does not really change, we mustn't
* set the flag as this will cause rather serious
* problems later!
*/
if (strcmp (user_name, optarg))
lflg++;
user_newname = optarg;
break;
case 'L':
if (Uflg || pflg)
usage ();
Lflg++;
break;
case 'm':
if (!dflg)
usage ();
mflg++;
break;
case 'o':
if (!uflg)
usage ();
oflg++;
break;
case 'p':
if (Lflg || Uflg)
usage ();
user_pass = optarg;
pflg++;
break;
case 's':
if (!VALID (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
} else
#ifdef WITH_AUDIT
user_newshell = optarg;
user_newexpire = -1;
#else
user_shell = optarg;
user_expire = -1;
#endif
sflg++;
break;
case 'u':
user_newid = get_id (optarg);
uflg++;
break;
case 'U':
if (Lflg && pflg)
usage ();
eflg++;
break;
case 'f':
#ifdef WITH_AUDIT
user_newinactive = get_number (optarg);
#else
user_inactive = get_number (optarg);
#endif
fflg++;
break;
case 'g':
grp = getgr_nam_gid (optarg);
if (!grp) {
fprintf (stderr,
_("%s: unknown group %s\n"),
Prog, optarg);
exit (E_NOTFOUND);
}
user_newgid = grp->gr_gid;
gflg++;
break;
case 'G':
if (get_groups (optarg))
exit (E_NOTFOUND);
Gflg++;
break;
case 'l':
if (!check_user_name (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
Uflg++;
break;
default:
usage ();
/*
* If the name does not really change, we mustn't
* set the flag as this will cause rather serious
* problems later!
*/
if (strcmp (user_name, optarg))
lflg++;
user_newname = optarg;
break;
case 'L':
if (Uflg || pflg)
usage ();
Lflg++;
break;
case 'm':
if (!dflg)
usage ();
mflg++;
break;
case 'o':
if (!uflg)
usage ();
oflg++;
break;
case 'p':
if (Lflg || Uflg)
usage ();
user_pass = optarg;
pflg++;
break;
case 's':
if (!VALID (optarg)) {
fprintf (stderr,
_("%s: invalid field `%s'\n"),
Prog, optarg);
exit (E_BAD_ARG);
}
#ifdef WITH_AUDIT
user_newshell = optarg;
#else
user_shell = optarg;
#endif
sflg++;
break;
case 'u':
user_newid = get_id (optarg);
uflg++;
break;
case 'U':
if (Lflg && pflg)
usage ();
Uflg++;
break;
default:
usage ();
}
anyflag++;
}
anyflag++;
}
if (anyflag == 0) {
fprintf (stderr, _("%s: no flags given\n"), Prog);
exit (E_USAGE);
@@ -1406,13 +1445,6 @@ static void move_mailbox (void)
}
#endif
#ifdef USE_PAM
static struct pam_conv conv = {
misc_conv,
NULL
};
#endif /* USE_PAM */
/*
* main - usermod command
*/

View File

@@ -22,9 +22,10 @@
#include <config.h>
#ident "$Id: vipw.c,v 1.17 2005/09/07 15:00:45 kloczek Exp $"
#ident "$Id: vipw.c,v 1.20 2005/12/13 14:01:08 kloczek Exp $"
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -33,6 +34,7 @@
#include <unistd.h>
#include <utime.h>
#include "defines.h"
#include "exitcodes.h"
#include "groupio.h"
#include "nscd.h"
#include "prototypes.h"
@@ -45,12 +47,33 @@
static const char *progname, *filename, *fileeditname;
static int filelocked = 0, createedit = 0;
static int (*unlock) (void);
static int quiet = 0;
/* local function prototypes */
static void usage (void);
static int create_backup_file (FILE *, const char *, struct stat *);
static void vipwexit (const char *, int, int);
static void vipwedit (const char *, int (*)(void), int (*)(void));
/*
* usage - display usage message and exit
*/
static void usage (void)
{
fprintf (stderr, _("Usage: vipw [options]\n"
"\n"
"Options:\n"
" -g, --group edit group database\n"
" -h, --help display this help message and exit\n"
" -p, --passwd edit passwd database\n"
" -q, --quiet quiet mode\n"
" -s, --shadow edit shadow or gshadow database\n"));
exit (E_USAGE);
}
/*
*
*/
static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
{
struct utimbuf ub;
@@ -91,7 +114,9 @@ static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
return 0;
}
/*
*
*/
static void vipwexit (const char *msg, int syserr, int ret)
{
int err = errno;
@@ -104,7 +129,9 @@ static void vipwexit (const char *msg, int syserr, int ret)
fprintf (stderr, "%s: %s", progname, msg);
if (syserr)
fprintf (stderr, ": %s", strerror (err));
fprintf (stderr, _("\n%s: %s is unchanged\n"), progname, filename);
if (!quiet)
fprintf (stdout, _("\n%s: %s is unchanged\n"), progname,
filename);
exit (ret);
}
@@ -112,6 +139,9 @@ static void vipwexit (const char *msg, int syserr, int ret)
#define DEFAULT_EDITOR "vi"
#endif
/*
*
*/
static void
vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
{
@@ -207,36 +237,50 @@ int main (int argc, char **argv)
{
int flag;
int editshadow = 0;
char *c;
int e = 1;
char *a;
int do_vipw;
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
progname = ((c = strrchr (*argv, '/')) ? c + 1 : *argv);
progname = ((a = strrchr (*argv, '/')) ? a + 1 : *argv);
do_vipw = (strcmp (progname, "vigr") != 0);
while ((flag = getopt (argc, argv, "ghps")) != EOF) {
switch (flag) {
case 'g':
do_vipw = 0;
break;
case 'h':
e = 0;
case 'p':
do_vipw = 1;
break;
case 's':
editshadow = 1;
break;
default:
printf (_("Usage:\n\
`vipw' edits /etc/passwd `vipw -s' edits /etc/shadow\n\
`vigr' edits /etc/group `vigr -s' edits /etc/gshadow\n\
"));
exit (e);
{
/*
* Parse the command line options.
*/
int c;
static struct option long_options[] = {
{"group", no_argument, NULL, 'g'},
{"help", no_argument, NULL, 'h'},
{"passwd", no_argument, NULL, 'p'},
{"quiet", no_argument, NULL, 'q'},
{"shadow", no_argument, NULL, 's'},
};
while ((c =
getopt_long (argc, argv, "ghpqs",
long_options, NULL)) != -1) {
switch (c) {
case 'g':
do_vipw = 0;
break;
case 'h':
usage ();
break;
case 'p':
do_vipw = 1;
break;
case 'q':
quiet = 1;
break;
case 's':
editshadow = 1;
break;
default:
usage ();
}
}
}
@@ -257,5 +301,5 @@ int main (int argc, char **argv)
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");
return 0;
exit (E_SUCCESS);
}