[svn-upgrade] Integrating new upstream version, shadow (4.0.14)
This commit is contained in:
@@ -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 \
|
||||
|
@@ -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@
|
||||
|
16
src/chage.c
16
src/chage.c
@@ -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
|
||||
*/
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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];
|
||||
|
60
src/chsh.c
60
src/chsh.c
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
*/
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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
|
||||
*
|
||||
|
72
src/login.c
72
src/login.c
@@ -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);
|
||||
|
31
src/newgrp.c
31
src/newgrp.c
@@ -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);
|
||||
}
|
||||
|
@@ -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
47
src/nologin.c
Normal 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;
|
||||
}
|
40
src/passwd.c
40
src/passwd.c
@@ -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
322
src/su.c
@@ -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);
|
||||
|
256
src/useradd.c
256
src/useradd.c
@@ -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) {
|
||||
|
115
src/userdel.c
115
src/userdel.c
@@ -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)) {
|
||||
|
344
src/usermod.c
344
src/usermod.c
@@ -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
|
||||
*/
|
||||
|
96
src/vipw.c
96
src/vipw.c
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user