[Pkg-shadow-commits] r168 - trunk/debian/patches
Nicolas FRANCOIS
pkg-shadow-devel@lists.alioth.debian.org
Sun, 22 May 2005 23:29:19 +0000
Author: nekral-guest
Date: 2005-05-22 23:29:18 +0000 (Sun, 22 May 2005)
New Revision: 168
Removed:
trunk/debian/patches/008_src.dpatch.new
Log:
008_src.dpatch.new was never used.
Deleted: trunk/debian/patches/008_src.dpatch.new
===================================================================
--- trunk/debian/patches/008_src.dpatch.new 2005-05-22 23:27:28 UTC (rev 167)
+++ trunk/debian/patches/008_src.dpatch.new 2005-05-22 23:29:18 UTC (rev 168)
@@ -1,1354 +0,0 @@
-#! /bin/sh -e
-## 008_src.dpatch by <unknown>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Various patches in src for the Debian package (before switch to dpatch)
-
-if [ $# -lt 1 ]; then
- echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
- exit 1
-fi
-
-[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
-patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
-
-case "$1" in
- -patch) patch -p1 ${patch_opts} < $0;;
- -unpatch) patch -R -p1 ${patch_opts} < $0;;
- *)
- echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
- exit 1;;
-esac
-
-exit 0
-
-@DPATCH@
-
-diff -Nru shadow-4.0.3/src/chage.c shadow-4.0.3_30.4/src/chage.c
---- shadow-4.0.3/src/chage.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/chage.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/types.h>
-diff -Nru shadow-4.0.3/src/cppw.c shadow-4.0.3_30.4/src/cppw.c
---- shadow-4.0.3/src/cppw.c 1970-01-01 01:00:00.000000000 +0100
-+++ shadow-4.0.3_30.4/src/cppw.c 2004-11-02 22:17:39.000000000 +0100
-@@ -0,0 +1,200 @@
-+/*
-+ cppw, cpgr copy with locking given file over the password or group file
-+ with -s will copy with locking given file over shadow or gshadow file
-+
-+ Copyright (C) 1999 Stephen Frost <sfrost@snowman.net>
-+
-+ Based on vipw, vigr by:
-+ Copyright (C) 1997 Guy Maor <maor@ece.utexas.edu>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful, but
-+ WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+
-+ */
-+
-+#include <config.h>
-+#include "defines.h"
-+
-+#include <errno.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <signal.h>
-+#include <utime.h>
-+#include "prototypes.h"
-+#include "pwio.h"
-+#include "shadowio.h"
-+#include "groupio.h"
-+#include "sgroupio.h"
-+
-+
-+static const char *progname, *filename, *filenewname;
-+static int filelocked = 0;
-+static int (*unlock)();
-+
-+/* local function prototypes */
-+static int create_backup_file (FILE *, const char *, struct stat *);
-+static void cppwexit (const char *, int, int);
-+static void cppwcopy (const char *, const char *, int (*) (void), int (*) (void));
-+int main (int, char **);
-+
-+static int
-+create_backup_file(FILE *fp, const char *backup, struct stat *sb)
-+{
-+ struct utimbuf ub;
-+ FILE *bkfp;
-+ int c;
-+ mode_t mask;
-+
-+ mask = umask(077);
-+ bkfp = fopen(backup, "w");
-+ umask(mask);
-+ if (!bkfp) return -1;
-+
-+ rewind(fp);
-+ while ((c = getc(fp)) != EOF) {
-+ if (putc(c, bkfp) == EOF) break;
-+ }
-+
-+ if (c != EOF || fflush(bkfp)) {
-+ fclose(bkfp);
-+ unlink(backup);
-+ return -1;
-+ }
-+ if (fclose(bkfp)) {
-+ unlink(backup);
-+ return -1;
-+ }
-+
-+ ub.actime = sb->st_atime;
-+ ub.modtime = sb->st_mtime;
-+ if (utime(backup, &ub) ||
-+ chmod(backup, sb->st_mode) ||
-+ chown(backup, sb->st_uid, sb->st_gid)) {
-+ unlink(backup);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static void
-+cppwexit(const char *msg, int syserr, int ret)
-+{
-+ int err = errno;
-+ if (filelocked) (*unlock)();
-+ if (msg) fprintf(stderr, "%s: %s", progname, msg);
-+ if (syserr) fprintf(stderr, ": %s", strerror(err));
-+ fprintf(stderr, "\n%s: %s is unchanged\n", progname, filename);
-+ exit(ret);
-+}
-+
-+static void
-+cppwcopy(const char *file, const char *in_file, int (*file_lock) (void), int (*file_unlock) (void))
-+{
-+ struct stat st1;
-+ FILE *f;
-+ char filenew[1024];
-+
-+ snprintf(filenew, sizeof filenew, "%s.new", file);
-+ unlock = file_unlock;
-+ filename = file;
-+ filenewname = filenew;
-+
-+ if (access(file, F_OK)) cppwexit(file, 1, 1);
-+ if (!file_lock()) cppwexit("Couldn't lock file", errno, 5);
-+ filelocked = 1;
-+
-+ /* file to copy has same owners, perm */
-+ if (stat(file, &st1)) cppwexit(file, 1, 1);
-+ if (!(f = fopen(in_file, "r"))) cppwexit(file, 1, 1);
-+ if (create_backup_file(f, filenew, &st1))
-+ cppwexit("Couldn't make backup", errno, 1);
-+
-+ /* XXX - here we should check filenew for errors; if there are any,
-+ fail w/ an appropriate error code and let the user manually fix
-+ it. Use pwck or grpck to do the check. - Stephen (Shamelessly
-+ stolen from '--marekm's comment) */
-+
-+ if (rename(filenew, file) == -1) {
-+ fprintf(stderr, "%s: can't copy %s: %s)\n",
-+ progname, filenew, strerror(errno));
-+ cppwexit(0,0,1);
-+ }
-+
-+ (*file_unlock)();
-+}
-+
-+
-+int
-+main(int argc, char **argv)
-+{
-+ int flag;
-+ int cpshadow = 0;
-+ char *in_file;
-+ char *c;
-+ int e = 1;
-+ int do_cppw;
-+
-+ progname = ((c = strrchr(*argv, '/')) ? c+1 : *argv);
-+ do_cppw = (strcmp(progname, "cpgr") != 0);
-+
-+ while ((flag = getopt(argc, argv, "ghps")) != EOF) {
-+ switch (flag) {
-+ case 'p':
-+ do_cppw = 1;
-+ break;
-+ case 'g':
-+ do_cppw = 0;
-+ break;
-+ case 's':
-+ cpshadow = 1;
-+ break;
-+ case 'h':
-+ e = 0;
-+ default:
-+ printf("Usage:\n\
-+`cppw <file>' copys over /etc/passwd `cppw -s <file>' copys over /etc/shadow\n\
-+`cpgr <file>' copys over /etc/group `cpgr -s <file>' copys over /etc/gshadow\n\
-+");
-+ exit(e);
-+ }
-+ }
-+
-+ if (optind >= argc) {
-+ cppwexit ("missing file argument, -h for usage",0,1);
-+ }
-+
-+ in_file = argv[argc - 1];
-+
-+ if (do_cppw) {
-+#ifdef SHADOWPWD
-+ if (cpshadow)
-+ cppwcopy(SHADOW_FILE, in_file, spw_lock, spw_unlock);
-+ else
-+#endif
-+ cppwcopy(PASSWD_FILE, in_file, pw_lock, pw_unlock);
-+ }
-+ else {
-+#ifdef SHADOWGRP
-+ if (cpshadow)
-+ cppwcopy(SGROUP_FILE, in_file, sgr_lock, sgr_unlock);
-+ else
-+#endif
-+ cppwcopy(GROUP_FILE, in_file, gr_lock, gr_unlock);
-+ }
-+
-+ return 0;
-+}
-diff -Nru shadow-4.0.3/src/groupadd.c shadow-4.0.3_30.4/src/groupadd.c
---- shadow-4.0.3/src/groupadd.c 2002-01-06 15:09:07.000000000 +0100
-+++ shadow-4.0.3_30.4/src/groupadd.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/types.h>
-diff -Nru shadow-4.0.3/src/groupdel.c shadow-4.0.3_30.4/src/groupdel.c
---- shadow-4.0.3/src/groupdel.c 2000-10-09 21:02:20.000000000 +0200
-+++ shadow-4.0.3_30.4/src/groupdel.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID(PKG_VER "$Id$")
-
-diff -Nru shadow-4.0.3/src/groupmod.c shadow-4.0.3_30.4/src/groupmod.c
---- shadow-4.0.3/src/groupmod.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/groupmod.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/types.h>
-diff -Nru shadow-4.0.3/src/grpck.c shadow-4.0.3_30.4/src/grpck.c
---- shadow-4.0.3/src/grpck.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/grpck.c 2004-11-02 22:17:38.000000000 +0100
-@@ -146,6 +146,7 @@
- int errors = 0;
- int deleted = 0;
- int i;
-+ int prune = 0;
- struct commonio_entry *gre, *tgre;
- struct group *grp;
- int sort_mode = 0;
-@@ -172,7 +173,7 @@
- * Parse the command line arguments
- */
-
-- while ((arg = getopt (argc, argv, "qrs")) != EOF) {
-+ while ((arg = getopt (argc, argv, "qprs")) != EOF) {
- switch (arg) {
- case 'q':
- /* quiet - ignored for now */
-@@ -183,6 +184,9 @@
- case 's':
- sort_mode = 1;
- break;
-+ case 'p':
-+ prune = 1;
-+ break;
- default:
- usage ();
- }
-@@ -315,9 +319,13 @@
- /*
- * prompt the user to delete the entry or not
- */
--
-- if (!yes_or_no ())
-+ if (!prune) {
-+ if (!yes_or_no ())
-+ continue;
-+ } else {
-+ puts("Yes");
- continue;
-+ }
-
- /*
- * All group file deletions wind up here. This code
-diff -Nru shadow-4.0.3/src/lastlog.c shadow-4.0.3_30.4/src/lastlog.c
---- shadow-4.0.3/src/lastlog.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/lastlog.c 2004-11-02 22:17:38.000000000 +0100
-@@ -184,7 +184,13 @@
- #endif
- once++;
- }
-- tm = localtime (&lastlog.ll_time);
-+ /* don't assume lastlog.ll_time is a time_t */
-+ {
-+ time_t when;
-+
-+ when = lastlog.ll_time;
-+ tm = localtime (&when);
-+ }
- #ifdef HAVE_STRFTIME
- strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm);
- cp = ptime;
-@@ -193,7 +199,7 @@
- cp[24] = '\0';
- #endif
-
-- if (lastlog.ll_time == (time_t) 0)
-+ if (lastlog.ll_time == 0)
- cp = _("**Never logged in**\0");
-
- #ifdef HAVE_LL_HOST
-diff -Nru shadow-4.0.3/src/login.c shadow-4.0.3_30.4/src/login.c
---- shadow-4.0.3/src/login.c 2002-03-08 05:30:28.000000000 +0100
-+++ shadow-4.0.3_30.4/src/login.c 2004-11-02 22:17:38.000000000 +0100
-@@ -58,6 +58,11 @@
- #include <sys/proc.h>
- #include <sys/sysi86.h>
- #endif
-+
-+#ifndef MAXHOSTNAMELEN
-+#define MAXHOSTNAMELEN 64
-+#endif
-+
- #ifdef RADIUS
- /*
- * Support for RADIUS authentication based on a hacked util-linux login
-@@ -289,6 +294,8 @@
- for (arg = 1; arg < argc; arg++) {
- if (argv[arg][0] == '-' && strlen (argv[arg]) > 2)
- usage ();
-+ if (!strcmp(argv[arg], "--"))
-+ break; /* stop checking on a "--" */
- }
- }
-
-@@ -466,7 +473,7 @@
-
- check_flags (argc, argv);
-
-- while ((flag = getopt (argc, argv, "d:f:h:pr:")) != EOF) {
-+ while ((flag = getopt (argc, argv, "d:f::h:pr:")) != EOF) {
- switch (flag) {
- case 'p':
- pflg++;
-@@ -475,11 +482,16 @@
- /*
- * username must be a separate token
- * (-f root, *not* -froot). --marekm
-+ *
-+ * if -f has an arg, use that, else use the
-+ * normal user name passed after all options
-+ * --benc
- */
-- if (optarg != argv[optind - 1])
-+ if (optarg != NULL && optarg != argv[optind - 1])
- usage ();
- fflg++;
-- STRFCPY (username, optarg);
-+ if (optarg)
-+ STRFCPY (username, optarg);
- break;
- #ifdef RLOGIN
- case 'r':
-@@ -633,7 +645,7 @@
- init_env ();
-
- if (optind < argc) { /* get the user name */
-- if (rflg || fflg)
-+ if (rflg || (fflg && username[0]))
- usage ();
-
- #ifdef SVR4
-@@ -763,49 +775,106 @@
- * MAX_LOGIN_TRIES?
- */
-
-- retcode = pam_authenticate (pamh, 0);
-- while ((failcount++ < retries) &&
-- ((retcode == PAM_AUTH_ERR) ||
-- (retcode == PAM_USER_UNKNOWN) ||
-- (retcode == PAM_CRED_INSUFFICIENT) ||
-- (retcode == PAM_AUTHINFO_UNAVAIL))) {
-- pam_get_item (pamh, PAM_USER,
-- (const void **) &pam_user);
-- syslog (LOG_NOTICE,
-- "FAILED LOGIN %d FROM %s FOR %s, %s",
-- failcount, hostname, pam_user,
-- pam_strerror (pamh, retcode));
--#ifdef HAVE_PAM_FAIL_DELAY
-- pam_fail_delay (pamh, 1000000 * delay);
-+ failcount = 0;
-+ while (1) {
-+ const char *failent_user;
-+ failed = 0;
-+
-+ failcount++;
-+ if (delay > 0)
-+ retcode = pam_fail_delay(pamh, 1000000*delay);
-+
-+ retcode = pam_authenticate (pamh, 0);
-+
-+ pam_get_item (pamh, PAM_USER,
-+ (const void **) &pam_user);
-+
-+ if (pam_user && pam_user[0]) {
-+ pwd = getpwnam(pam_user);
-+ if (pwd) {
-+ pwent = *pwd;
-+ failent_user = pwent.pw_name;
-+ } else {
-+ if (getdef_bool("LOG_UNKFAIL_ENAB") && pam_user)
-+ failent_user = pam_user;
-+ else
-+ failent_user = "UNKNOWN";
-+ }
-+ } else {
-+ pwd = NULL;
-+ failent_user = "UNKNOWN";
-+ }
-+
-+ if (retcode == PAM_MAXTRIES || failcount >= retries) {
-+ syslog (LOG_NOTICE,
-+ _("TOO MANY LOGIN TRIES (%d)%s FOR `%s'"),
-+ failcount, fromhost, failent_user);
-+#ifndef USE_PAM
-+ if (pwd && getdef_bool("FAILLOG_ENAB"))
-+ failure (pwent.pw_uid, tty, &faillog);
-+#endif
-+ fprintf(stderr,
-+ _("Maximum number of tries exceeded (%d)\n"),
-+ failcount);
-+ PAM_END;
-+ exit(0);
-+ } else if (retcode == PAM_ABORT) {
-+ /* Serious problems, quit now */
-+ fprintf(stderr,_("login: abort requested by PAM\n"));
-+ syslog(LOG_ERR,_("PAM_ABORT returned from pam_authenticate()"));
-+ PAM_END;
-+ exit(99);
-+ } else if (retcode != PAM_SUCCESS) {
-+ syslog(LOG_NOTICE,_("FAILED LOGIN (%d)%s FOR `%s', %s"),
-+ failcount, fromhost, failent_user,
-+ pam_strerror (pamh, retcode));
-+ failed = 1;
-+ }
-+#ifndef USE_PAM
-+ if (pwd && getdef_bool("FAILLOG_ENAB") &&
-+ ! failcheck (pwent.pw_uid, &faillog, failed)) {
-+ SYSLOG((LOG_CRIT, FAILURE_CNT, failent_user, fromhost));
-+ failed = 1;
-+ }
- #endif
-- fprintf (stderr, "Login incorrect\n\n");
-- pam_set_item (pamh, PAM_USER, NULL);
-- retcode = pam_authenticate (pamh, 0);
-- }
-
-- if (retcode != PAM_SUCCESS) {
-- pam_get_item (pamh, PAM_USER,
-- (const void **) &pam_user);
--
-- if (retcode == PAM_MAXTRIES)
-- syslog (LOG_NOTICE,
-- "TOO MANY LOGIN TRIES (%d) FROM %s FOR %s, %s",
-- failcount, hostname,
-- pam_user,
-- pam_strerror (pamh,
-- retcode));
-- else
-- syslog (LOG_NOTICE,
-- "FAILED LOGIN SESSION FROM %s FOR %s, %s",
-- hostname, pam_user,
-- pam_strerror (pamh,
-- retcode));
--
-- fprintf (stderr, "\nLogin incorrect\n");
-- pam_end (pamh, retcode);
-- exit (0);
-+ if (!failed)
-+ break;
-+
-+ fprintf(stderr,"Login incorrect\n\n");
-+#ifndef USE_PAM
-+ if (pwd && getdef_bool("FAILLOG_ENAB"))
-+ failure (pwent.pw_uid, tty, &faillog);
-+#endif
-+ if (getdef_str("FTMP_FILE") != NULL) {
-+#if HAVE_UTMPX_H
-+ failent = utxent;
-+ /* don't assume that utmpx.ut_tv is a struct
-+ timeval */
-+ {
-+ struct timeval tv;
-+
-+ gettimeofday(&tv, NULL);
-+ failent.ut_tv.tv_sec = tv.tv_sec;
-+ failent.ut_tv.tv_usec = tv.tv_usec;
-+ }
-+#else
-+ failent = utent;
-+ failent.ut_time = time(0);
-+#endif
-+ strncpy(failent.ut_user, failent_user, sizeof(failent.ut_user));
-+#ifdef USER_PROCESS
-+ failent.ut_type = USER_PROCESS;
-+#endif
-+ failtmp(&failent);
-+ }
-+
-+ /* Let's give it another go around */
-+ pam_set_item(pamh,PAM_USER,NULL);
- }
-
-+ /* We don't get here unless they were authenticated above */
-+ alarm(0);
- retcode = pam_acct_mgmt (pamh, 0);
-
- if (retcode == PAM_NEW_AUTHTOK_REQD) {
-@@ -828,11 +897,14 @@
-
- if (!pwd || setup_groups (pwd))
- exit (1);
-+ else
-+ pwent = *pwd;
-
- retcode = pam_setcred (pamh, PAM_ESTABLISH_CRED);
- PAM_FAIL_CHECK;
-
-- retcode = pam_open_session (pamh, 0);
-+ retcode = pam_open_session (pamh,
-+ hushed(&pwent) ? PAM_SILENT : 0);
- PAM_FAIL_CHECK;
-
- #else /* ! USE_PAM */
-@@ -1002,6 +1074,7 @@
- failed = 1;
- }
- #endif
-+#ifndef USE_PAM
- if (pwd && getdef_bool ("FAILLOG_ENAB") &&
- !failcheck (pwent.pw_uid, &faillog, failed)) {
- SYSLOG ((LOG_CRIT,
-@@ -1009,21 +1082,31 @@
- username, fromhost));
- failed = 1;
- }
-+#endif
- if (!failed)
- break;
-
-+#ifndef USE_PAM
- /* don't log non-existent users */
- if (pwd && getdef_bool ("FAILLOG_ENAB"))
- failure (pwent.pw_uid, tty, &faillog);
-+#endif
- if (getdef_str ("FTMP_FILE") != NULL) {
- const char *failent_user;
-
- #if HAVE_UTMPX_H
- failent = utxent;
-- gettimeofday (&(failent.ut_tv), NULL);
-+ /* don't assume that utmpx.ut_tv is a struct timeval */
-+ {
-+ struct timeval tv;
-+
-+ gettimeofday(&tv, NULL);
-+ failent.ut_tv.tv_sec = tv.tv_sec;
-+ failent.ut_tv.tv_usec = tv.tv_usec;
-+ }
- #else
- failent = utent;
-- time (&failent.ut_time);
-+ failent.ut_time = time(0);
- #endif
- if (pwd) {
- failent_user = pwent.pw_name;
-@@ -1208,6 +1291,40 @@
- login_fbtab (tty, pwent.pw_uid, pwent.pw_gid);
- #endif
-
-+#ifdef USE_PAM
-+ /*
-+ * We must fork before setuid() because we need to call
-+ * pam_close_session() as root.
-+ *
-+ * Note: not true in other (non-Linux) PAM implementations, where
-+ * the parent process of login (init, telnetd, ...) is responsible
-+ * for calling pam_close_session(). This avoids an extra process for
-+ * each login. Maybe we should do this on Linux too? We let the
-+ * admin configure whether they need to keep login around to close
-+ * sessions.
-+ */
-+ if (getdef_bool ("CLOSE_SESSIONS")) {
-+ signal (SIGINT, SIG_IGN);
-+ child = fork ();
-+ if (child < 0) {
-+ /* error in fork() */
-+ fprintf (stderr,
-+ "login: failure forking: %s",
-+ strerror (errno));
-+ PAM_END;
-+ exit (0);
-+ } else if (child) {
-+ /*
-+ * parent - wait for child to finish, then cleanup
-+ * session
-+ */
-+ wait (NULL);
-+ PAM_END;
-+ exit (0);
-+ }
-+ /* child */
-+ }
-+#endif
- /* We call set_groups() above because this clobbers pam_groups.so */
- #ifndef USE_PAM
- if (setup_uid_gid (&pwent, is_console))
-@@ -1271,15 +1388,16 @@
- }
- if (getdef_bool ("LASTLOG_ENAB")
- && lastlog.ll_time != 0) {
-+ time_t when = lastlog.ll_time; /* may not be a time_t */
- #ifdef HAVE_STRFTIME
- strftime (ptime, sizeof (ptime),
- "%a %b %e %H:%M:%S %z %Y",
-- localtime (&lastlog.ll_time));
-+ localtime (&when));
- printf (_("Last login: %s on %s"),
- ptime, lastlog.ll_line);
- #else
- printf (_("Last login: %.19s on %s"),
-- ctime (&lastlog.ll_time),
-+ ctime (&when),
- lastlog.ll_line);
- #endif
- #ifdef HAVE_LL_HOST /* SVR4 || __linux__ || SUN4 */
-@@ -1309,41 +1427,6 @@
- signal (SIGTERM, SIG_DFL); /* default terminate signal */
- signal (SIGALRM, SIG_DFL); /* default alarm signal */
- signal (SIGHUP, SIG_DFL); /* added this. --marekm */
--
--#ifdef USE_PAM
-- /*
-- * We must fork before setuid() because we need to call
-- * pam_close_session() as root.
-- *
-- * Note: not true in other (non-Linux) PAM implementations, where
-- * the parent process of login (init, telnetd, ...) is responsible
-- * for calling pam_close_session(). This avoids an extra process for
-- * each login. Maybe we should do this on Linux too? We let the
-- * admin configure whether they need to keep login around to close
-- * sessions.
-- */
-- if (getdef_bool ("CLOSE_SESSIONS")) {
-- signal (SIGINT, SIG_IGN);
-- child = fork ();
-- if (child < 0) {
-- /* error in fork() */
-- fprintf (stderr,
-- "login: failure forking: %s",
-- strerror (errno));
-- PAM_END;
-- exit (0);
-- } else if (child) {
-- /*
-- * parent - wait for child to finish, then cleanup
-- * session
-- */
-- wait (NULL);
-- PAM_END;
-- exit (0);
-- }
-- /* child */
-- }
--#endif
- signal (SIGINT, SIG_DFL); /* default interrupt signal */
-
- endpwent (); /* stop access to password file */
-@@ -1357,7 +1440,11 @@
- if (pwent.pw_uid == 0)
- SYSLOG ((LOG_NOTICE, "ROOT LOGIN %s", fromhost));
- else if (getdef_bool ("LOG_OK_LOGINS"))
-+#ifdef USE_PAM
-+ SYSLOG ((LOG_INFO, "`%s' logged in %s", pam_user, fromhost));
-+#else
- SYSLOG ((LOG_INFO, "`%s' logged in %s", username, fromhost));
-+#endif
- closelog ();
- #ifdef RADIUS
- if (is_rad_login) {
-diff -Nru shadow-4.0.3/src/Makefile.am shadow-4.0.3_30.4/src/Makefile.am
---- shadow-4.0.3/src/Makefile.am 2002-03-10 08:12:52.000000000 +0100
-+++ shadow-4.0.3_30.4/src/Makefile.am 2004-11-02 22:17:37.000000000 +0100
-@@ -25,7 +25,7 @@
- ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
- usbin_PROGRAMS = chpasswd dpasswd groupadd groupdel groupmod \
- logoutd mkpasswd newusers useradd userdel usermod grpck \
-- pwck vipw grpconv grpunconv pwconv pwunconv
-+ pwck vipw grpconv grpunconv pwconv pwunconv cppw
-
- noinst_PROGRAMS = id sulogin
-
-@@ -54,7 +54,6 @@
- usermod_LDADD = $(LDADD) $(LIBPAM)
-
- install-exec-hook:
-- ln -sf newgrp $(DESTDIR)$(bindir)/sg
- ln -sf vigr $(DESTDIR)$(bindir)/vipw
- for i in $(suidbins); do \
- chmod 4755 $(DESTDIR)$(bindir)/$$i; \
-diff -Nru shadow-4.0.3/src/newusers.c shadow-4.0.3_30.4/src/newusers.c
---- shadow-4.0.3/src/newusers.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/newusers.c 2004-11-02 22:17:38.000000000 +0100
-@@ -35,6 +35,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/types.h>
-diff -Nru shadow-4.0.3/src/passwd.c shadow-4.0.3_30.4/src/passwd.c
---- shadow-4.0.3/src/passwd.c 2002-01-05 16:41:43.000000000 +0100
-+++ shadow-4.0.3_30.4/src/passwd.c 2004-11-02 22:17:38.000000000 +0100
-@@ -1173,8 +1173,8 @@
-
- if (!amroot && pw->pw_uid != getuid ()) {
- fprintf (stderr,
-- _("You may not change the password for %s.\n"),
-- name);
-+ _("%s: You may not view or modify password information for %s.\n"),
-+ Prog, name);
- SYSLOG ((LOG_WARN, "can't change pwd for `%s'", name));
- closelog ();
- exit (E_NOPERM);
-diff -Nru shadow-4.0.3/src/su.c shadow-4.0.3_30.4/src/su.c
---- shadow-4.0.3/src/su.c 2002-03-08 05:30:28.000000000 +0100
-+++ shadow-4.0.3_30.4/src/su.c 2004-11-02 22:17:38.000000000 +0100
-@@ -26,6 +26,24 @@
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-+/* Some parts substantially derived from an ancestor of: */
-+/* su for GNU. Run a shell with substitute user and group IDs.
-+ Copyright (C) 1992-2003 Free Software Foundation, Inc.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software Foundation,
-+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-+
-
- #include <config.h>
-
-@@ -49,6 +67,7 @@
- #include <grp.h>
- #include <signal.h>
- #include <pwd.h>
-+#include <getopt.h>
- #include "pwauth.h"
- #include "getdef.h"
-
-@@ -79,6 +98,18 @@
-
- /* local function prototypes */
-
-+/* If nonzero, change some environment vars to indicate the user su'd to. */
-+static int change_environment;
-+
-+static struct option const longopts[] =
-+{
-+ {"command", required_argument, 0, 'c'},
-+ {"preserve-environment", no_argument, 0, 'p'},
-+ {"shell", required_argument, 0, 's'},
-+ {"help", no_argument, 0, 'h'},
-+ {0, 0, 0, 0}
-+};
-+
- #ifndef USE_PAM
-
- static RETSIGTYPE die (int);
-@@ -118,6 +149,96 @@
- }
- #endif /* !USE_PAM */
-
-+/* borrowed from GNU sh-utils' "su.c" */
-+static int
-+restricted_shell (const char *shell)
-+{
-+ char *line;
-+
-+ setusershell ();
-+ while ((line = getusershell ()) != NULL) {
-+ if (*line != '#' && strcmp (line, shell) == 0) {
-+ endusershell ();
-+ return 0;
-+ }
-+ }
-+ endusershell ();
-+ return 1;
-+}
-+
-+/* borrowed from GNU sh-utils' "su.c" */
-+static int
-+elements (char **arr)
-+{
-+ int n = 0;
-+
-+ for (n = 0; *arr; ++arr)
-+ ++n;
-+ return n;
-+}
-+
-+/* borrowed from GNU sh-utils' "su.c" */
-+static void
-+run_shell (char *shell, const char *command, char **additional_args, int login)
-+{
-+ const char **args;
-+ int argno = 1;
-+ char cmd[BUFSIZ];
-+ int cmd_len_left = sizeof(cmd) - 1;
-+
-+ cmd[0] = '\0';
-+
-+ if (additional_args)
-+ args = (const char **) xmalloc (sizeof (char *)
-+ * (10 + elements (additional_args)));
-+ else
-+ args = (const char **) xmalloc (sizeof (char *) * 10);
-+
-+ if (login)
-+ {
-+ char *arg0;
-+ char *shell_basename;
-+
-+ shell_basename = getdef_str("SU_NAME");
-+ if (!shell_basename)
-+ shell_basename = Basename(shell);
-+
-+ arg0 = xmalloc (strlen (shell_basename) + 2);
-+ arg0[0] = '-';
-+ strcpy (arg0 + 1, shell_basename);
-+ args[0] = arg0;
-+ }
-+ else
-+ args[0] = Basename(shell);
-+ if (command || additional_args)
-+ args[argno++] = "-c";
-+ if (command) {
-+ if (strlen(command) > cmd_len_left) {
-+ fprintf(stderr, _("Command line args too long\n"));
-+ exit(1);
-+ }
-+ strcat(cmd, command);
-+ cmd_len_left -= strlen(command);
-+ }
-+ if (additional_args)
-+ for (; *additional_args; ++additional_args) {
-+ if ((strlen(*additional_args) + 1) > cmd_len_left) {
-+ fprintf(stderr, _("Command line args too long\n"));
-+ exit(1);
-+ }
-+ if (cmd[0]) {
-+ strcat(cmd, " ");
-+ cmd_len_left--;
-+ }
-+ strcat(cmd, *additional_args);
-+ cmd_len_left -= strlen(*additional_args);
-+ }
-+ if (cmd[0]) args[argno++] = cmd;
-+ args[argno] = NULL;
-+ execv (shell, (char **) args);
-+ fprintf (stderr, _("No shell\n"));
-+ SYSLOG((LOG_WARN, "Cannot execute %s\n", shell));
-+}
-
- static void su_failure (const char *tty)
- {
-@@ -125,7 +246,7 @@
- #ifdef USE_SYSLOG
- if (getdef_bool ("SYSLOG_SU_ENAB"))
- SYSLOG ((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
-- "- %s %s-%s", tty,
-+ "- %s %s:%s", tty,
- oldname[0] ? oldname : "???",
- name[0] ? name : "???"));
- closelog ();
-@@ -153,13 +274,14 @@
- {
- char *cp;
- const char *tty = 0; /* Name of tty SU is run from */
-- int doshell = 0;
- int fakelogin = 0;
- int amroot = 0;
- uid_t my_uid;
- struct passwd *pw = 0;
- char **envp = environ;
--
-+ char *command = 0, *shell = 0, **additional_args = 0;
-+ int optc;
-+ char *tmp_name;
- #ifdef USE_PAM
- int ret;
- #else /* !USE_PAM */
-@@ -174,12 +296,14 @@
- #endif
- #endif /* !USE_PAM */
-
-- sanitize_env ();
-+ /* sanitize_env (); */
-
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-
-+ change_environment = 1;
-+
- /*
- * Get the program name. The program name is used as a prefix to
- * most error messages.
-@@ -224,15 +348,67 @@
- * Process the command line arguments.
- */
-
-- argc--;
-- argv++; /* shift out command name */
--
-- if (argc > 0 && strcmp (argv[0], "-") == 0) {
-+ while ((optc = getopt_long (argc, argv, "c:mps:h", longopts, NULL)) != -1) {
-+ switch (optc) {
-+ case 0:
-+ break;
-+ case 'c':
-+ command = optarg;
-+ break;
-+ case 'm':
-+ case 'p':
-+ change_environment = 0;
-+ break;
-+ case 's':
-+ shell = optarg;
-+ break;
-+ default:
-+ fprintf(stderr, _("\
-+Usage: su [OPTS] [-] [username [ARGS]]\n\
-+ - make this a login shell\n\
-+ -c, --command=<command>\n\
-+ pass command to the invoked shell using its -c\n\
-+ option\n\
-+ -m, -p, --preserve-environment\n\
-+ do not reset environment variables, and keep the\n\
-+ same shell\n\
-+ -s, --shell=<shell>\n\
-+ use shell instead of the default in /etc/passwd\n"));
-+ exit(1);
-+ }
-+ }
-+
-+ if (optind < argc && !strcmp (argv[optind], "-")) {
- fakelogin = 1;
-- argc--;
-- argv++; /* shift ... */
-+ ++optind;
- }
-
-+ if (optind < argc)
-+ strncpy(name, argv[optind++], sizeof(name) - 1);
-+ else {
-+ struct passwd *root_pw = getpwuid(0);
-+ if (root_pw == NULL) {
-+ SYSLOG((LOG_CRIT, "There is no UID 0 user."));
-+ su_failure(tty);
-+ }
-+ strcpy(name, root_pw->pw_name);
-+ }
-+
-+ if (optind < argc)
-+ additional_args = argv + optind;
-+
-+ /*
-+ * Get the user's real name. The current UID is used to determine
-+ * who has executed su. That user ID must exist.
-+ */
-+
-+ pw = get_my_pwent();
-+ if (!pw) {
-+ SYSLOG((LOG_CRIT, "Unknown UID: %d\n", (int) my_uid));
-+ su_failure(tty);
-+ }
-+ STRFCPY(oldname, pw->pw_name);
-+
- /*
- * If a new login is being set up, the old environment will be
- * ignored and a new one created later on.
-@@ -257,35 +433,6 @@
- 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 (!name[0]) /* use default user ID */
-- (void) strcpy (name, "root");
--
-- doshell = argc == 0; /* any arguments remaining? */
--
-- /*
-- * Get the user's real name. The current UID is used to determine
-- * who has executed su. That user ID must exist.
-- */
--
-- pw = get_my_pwent ();
-- if (!pw) {
-- SYSLOG ((LOG_CRIT, "Unknown UID: %u", my_uid));
-- su_failure (tty);
-- }
-- STRFCPY (oldname, pw->pw_name);
--
- #ifndef USE_PAM
- #ifdef SU_ACCESS
- /*
-@@ -399,9 +546,17 @@
- * Set the default shell.
- */
-
-- if (pwent.pw_shell[0] == '\0')
-- pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
-+ if (pwent.pw_shell == NULL || pwent.pw_shell[0] == '\0')
-+ pwent.pw_shell = (char *) "/bin/sh";
-+
-+ if (shell == 0 && change_environment == 0)
-+ shell = getenv ("SHELL");
-+ if (shell != 0 && getuid () && restricted_shell (pwent.pw_shell))
-+ shell = 0;
-+ if (shell == 0)
-+ shell = (char *) strdup (pwent.pw_shell);
-
-+ signal(SIGINT, SIG_IGN);
- #ifdef USE_PAM
- ret = pam_authenticate (pamh, 0);
- if (ret != PAM_SUCCESS) {
-@@ -427,6 +582,14 @@
- su_failure (tty);
- }
- }
-+ ret = pam_get_item(pamh, PAM_USER, (const void **) &tmp_name);
-+ if (ret != PAM_SUCCESS) {
-+ SYSLOG((LOG_ERR, "pam_get_item: internal PAM error\n"));
-+ fprintf(stderr, "%s: Internal PAM error retrieving username\n", Prog);
-+ pam_end(pamh, ret);
-+ su_failure(tty);
-+ }
-+ strncpy(name, tmp_name, sizeof(name) - 1);
- #else /* !USE_PAM */
- /*
- * Set up a signal handler in case the user types QUIT.
-@@ -507,10 +670,14 @@
- }
- #endif
-
-- environ = newenvp; /* make new environment active */
--
-- if (getenv ("IFS")) /* don't export user IFS ... */
-- addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
-+ if (change_environment || restricted_shell(pwent.pw_shell)) {
-+ environ = newenvp; /* make new environment active */
-+ if (getenv ("IFS")) /* don't export user IFS ... */
-+ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
-+ } else {
-+ if (getenv ("IFS"))
-+ putenv("IFS= \t\n");
-+ }
-
- if (pwent.pw_shell[0] == '*') { /* subsystem root required */
- pwent.pw_shell++; /* skip the '*' */
-@@ -529,7 +696,7 @@
- #endif
- #ifdef USE_SYSLOG
- if (getdef_bool ("SYSLOG_SU_ENAB"))
-- SYSLOG ((LOG_INFO, "+ %s %s-%s", tty,
-+ SYSLOG ((LOG_INFO, "+ %s %s:%s", tty,
- oldname[0] ? oldname : "???",
- name[0] ? name : "???"));
- #endif
-@@ -554,17 +721,56 @@
- pam_end (pamh, ret);
- exit (1);
- }
-+ ret = pam_open_session(pamh, 0);
-+ if (ret != PAM_SUCCESS) {
-+ SYSLOG((LOG_ERR, "pam_open_session: %s\n", pam_strerror(pamh, ret)));
-+ fprintf(stderr, "%s: %s\n", Prog, pam_strerror(pamh, ret));
-+ pam_setcred(pamh, PAM_DELETE_CRED);
-+ pam_end(pamh, ret);
-+ exit(1);
-+ }
-+ /* We must fork before setuid() because we need to call
-+ * pam_close_session() as root.
-+ */
-+
-+ /* We let the admin configure whether they need to keep login
-+ around to close sessions */
-+ if (getdef_bool("CLOSE_SESSIONS")) {
-+ pid_t pid;
-+ int status;
-+
-+ signal(SIGINT, SIG_IGN);
-+ pid = fork();
-+
-+ switch(pid) {
-+ case -1:
-+ SYSLOG((LOG_ERR, "su: fork failure: %m"));
-+ perror("su: fork failure");
-+ pam_setcred(pamh, PAM_DELETE_CRED);
-+ pam_close_session(pamh, 0);
-+ pam_end(pamh, PAM_ABORT);
-+ exit(1);
-+ case 0: /* child */
-+ signal(SIGINT, SIG_DFL);
-+ break;
-+ default: /* parent */
-+ waitpid(pid, &status, 0);
-+ /* now we are done using PAM */
-+ pam_setcred(pamh, PAM_DELETE_CRED);
-+ ret = pam_close_session(pamh, 0);
-+ pam_end(pamh, ret);
-+ exit(WEXITSTATUS(status));
-+ }
-+ }
-
- /* become the new user */
- if (change_uid (&pwent)) {
-+ pam_close_session(pamh, 0);
- pam_setcred (pamh, PAM_DELETE_CRED);
- pam_end (pamh, PAM_ABORT);
- exit (1);
- }
-
-- /* now we are done using PAM */
-- pam_end (pamh, PAM_SUCCESS);
--
- #else /* !USE_PAM */
- if (!amroot) /* no limits if su from root */
- setup_limits (&pwent);
-@@ -573,11 +779,14 @@
- exit (1);
- #endif /* !USE_PAM */
-
-- if (fakelogin)
-- setup_env (&pwent);
-+ if (fakelogin && (change_environment || restricted_shell(pwent.pw_shell)))
-+ setup_env(&pwent);
- #if 1 /* Suggested by Joey Hess. XXX - is this right? */
-- else
-- addenv ("HOME", pwent.pw_dir);
-+ else if (change_environment || restricted_shell(pwent.pw_shell)) {
-+ addenv("HOME", pwent.pw_dir);
-+ addenv("USER", pwent.pw_name);
-+ addenv("SHELL", shell);
-+ }
- #endif
-
- /*
-@@ -589,46 +798,6 @@
- */
- closelog ();
-
-- /*
-- * See if the user has extra arguments on the command line. In that
-- * case they will be provided to the new user's shell as arguments.
-- */
--
-- if (fakelogin) {
-- char *arg0;
--
--#if 0 /* XXX - GNU su doesn't do this. --marekm */
-- if (!hushed (&pwent)) {
-- motd ();
-- mailcheck ();
-- }
--#endif
-- cp = getdef_str ("SU_NAME");
-- if (!cp)
-- cp = Basename (pwent.pw_shell);
--
-- arg0 = xmalloc (strlen (cp) + 2);
-- arg0[0] = '-';
-- strcpy (arg0 + 1, cp);
-- cp = arg0;
-- } else
-- cp = Basename (pwent.pw_shell);
--
-- if (!doshell) {
--
-- /*
-- * Use new user's shell from /etc/passwd and create an argv
-- * with the rest of the command line included.
-- */
--
-- argv[-1] = pwent.pw_shell;
-- (void) execv (pwent.pw_shell, &argv[-1]);
-- (void) fprintf (stderr, _("No shell\n"));
-- SYSLOG ((LOG_WARN, "Cannot execute %s", pwent.pw_shell));
-- closelog ();
-- exit (1);
-- }
--
-- shell (pwent.pw_shell, cp);
-+ run_shell (shell, command, additional_args, fakelogin);
- /*NOTREACHED*/ exit (1);
- }
-diff -Nru shadow-4.0.3/src/useradd.c shadow-4.0.3_30.4/src/useradd.c
---- shadow-4.0.3/src/useradd.c 2002-01-10 14:01:28.000000000 +0100
-+++ shadow-4.0.3_30.4/src/useradd.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include "prototypes.h"
-diff -Nru shadow-4.0.3/src/userdel.c shadow-4.0.3_30.4/src/userdel.c
---- shadow-4.0.3/src/userdel.c 2002-01-05 16:41:44.000000000 +0100
-+++ shadow-4.0.3_30.4/src/userdel.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/stat.h>
-@@ -147,6 +149,7 @@
- struct group *ngrp;
-
- #ifdef SHADOWGRP
-+ int deleted_user_group = 0;
- const struct sgrp *sgrp;
- struct sgrp *nsgrp;
- #endif /* SHADOWGRP */
-@@ -209,6 +212,10 @@
-
- gr_remove (grp->gr_name);
-
-+#ifdef SHADOWGRP
-+ deleted_user_group = 1;
-+#endif
-+
- /*
- * Update the DBM group file with the new entry as well.
- */
-@@ -279,6 +286,10 @@
- SYSLOG ((LOG_INFO, "delete `%s' from shadow group `%s'\n",
- user_name, nsgrp->sg_name));
- }
-+
-+ if (deleted_user_group)
-+ sgr_remove(user_name);
-+
- #ifdef NDBM
- endsgent ();
- #endif /* NDBM */
-diff -Nru shadow-4.0.3/src/usermod.c shadow-4.0.3_30.4/src/usermod.c
---- shadow-4.0.3/src/usermod.c 2002-01-05 16:41:44.000000000 +0100
-+++ shadow-4.0.3_30.4/src/usermod.c 2004-11-02 22:17:38.000000000 +0100
-@@ -29,6 +29,8 @@
-
- #include <config.h>
-
-+#undef USE_PAM
-+
- #include "rcsid.h"
- RCSID (PKG_VER "$Id$")
- #include <sys/types.h>
-@@ -1544,9 +1546,14 @@
- if (copy_tree (user_home, user_newhome,
- uflg ? user_newid : -1,
- gflg ? user_newgid : -1) ==
-- 0 && remove_tree (user_home) == 0
-- && rmdir (user_home) == 0)
-- return;
-+ 0) {
-+ if (remove_tree (user_home) != 0 ||
-+ rmdir (user_home) != 0)
-+ fprintf (stderr,
-+ _("%s: warning: failed to completely remove old home directory %s"),
-+ Prog, user_home);
-+ return;
-+ }
-
- (void) remove_tree (user_newhome);
- (void) rmdir (user_newhome);