Shadow Login Suite, patch 5
John F Haugh II
jfh at rpp386.cactus.org
Fri Jun 14 13:38:19 AEST 1991
The three new commands that were added in patch 4 had a few problems, and
this patch addresses them. One important change is that the directory
copy, move, and delete functions are better supported now. It is now
possible to rename someones home directory and have it copied to a completely
different device.
The most significant changes are for the support of "rlogin" on SCO Xenix.
These changes were made by Chip Rosenthal, as were many of the other
changes in this particular set of patches.
In the "Things to Come" catagory, the groupadd, groupdel, and groupmod
commands [ see your SVR4 documentation for more details ] have been
finished and will be part of patch 6, due out in a week or two. Also
in "Things to Come" are changes to these 6 commands that will allow
you to utilize the code without being forced to have all of the other
strange modifications that I've made. That is, you can stick with
just plain old /etc/passwd and /etc/group and still use the 6 more
recently added commands. I think I went overboard making those commands
only usable with the extensions that I've added ...
A gentleman from Down Under is currently working on SunOS patches, and
swears to have it running on SunOS. This is great news and I am
anxiously waiting those results.
--
Prereq: 4
*** rel3/patchlevel.h Thu Jun 13 21:28:41 1991
--- patchlevel.h Thu Jun 13 10:06:38 1991
***************
*** 10,13 ****
*/
#define RELEASE 3
! #define PATCHLEVEL 4
--- 10,14 ----
*/
#define RELEASE 3
! #define PATCHLEVEL 5
! #define VERSION "3.0.5"
*** rel3/Makefile Thu Jun 13 21:28:42 1991
--- Makefile Thu Jun 13 21:16:50 1991
***************
*** 8,16 ****
# and conspicuously displayed on all copies of object code or
# distribution media.
#
! # @(#)Makefile 3.11 11:11:42 - Shadow password system
#
! # @(#)Makefile 3.11 11:11:42 6/7/91
#
SHELL = /bin/sh
--- 8,16 ----
# and conspicuously displayed on all copies of object code or
# distribution media.
#
! # @(#)Makefile 3.15 20:52:45 - Shadow password system
#
! # @(#)Makefile 3.15 20:52:45 6/13/91
#
SHELL = /bin/sh
***************
*** 26,31 ****
--- 26,35 ----
# LOGINDIR = /bin
LOGINDIR = /etc
+ # Define any special libraries required to access the directory routines.
+ # NDIR = -lndir
+ NDIR = -lx
+
# Pick your favorite C compiler and tags command
CC = cc
TAGS = ctags
***************
*** 39,44 ****
--- 43,57 ----
RANLIB = ranlib
# RANLIB = echo
+ # Configuration Flags
+ #
+ # LIBS - system libraries
+ # -lsocket - needed for TCP/IP and possibly SYSLOG
+ # -ldbm or -lndbm - needed for DBM support
+ # -lcrypt - needed for SCO crypt() functions
+ # CFLAGS - C compiler flags
+ # -DLAI_TCP - needed for SCO Xenix Lachman TCP/IP
+
# Flags for SCO Xenix/386
CFLAGS = -O -M3 -g $(OS)
LIBS = -lcrypt -lndbm
***************
*** 128,134 ****
chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
! userdel.c patchlevel.h usermod.c
FILES1 = README newgrp.c Makefile config.h pwunconv.c obscure.c age.c id.c \
patchlevel.h
--- 141,147 ----
chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c useradd.c \
! userdel.c patchlevel.h usermod.c copydir.c mkrmdir.c
FILES1 = README newgrp.c Makefile config.h pwunconv.c obscure.c age.c id.c \
patchlevel.h
***************
*** 149,155 ****
FILES7 = groupio.c shadowio.c sgroupio.c
! FILES8 = useradd.c userdel.c usermod.c
MAN_1 = chage.1 chfn.1 chsh.1 login.1 passwd.1 su.1
MAN_3 = shadow.3
--- 162,168 ----
FILES7 = groupio.c shadowio.c sgroupio.c
! FILES8 = useradd.c userdel.c usermod.c copydir.c mkrmdir.c
MAN_1 = chage.1 chfn.1 chsh.1 login.1 passwd.1 su.1
MAN_3 = shadow.3
***************
*** 333,355 ****
id.lint: id.c
$(LINT) $(LINTFLAGS) id.c > id.lint
! useradd: useradd.o libshadow.a
! $(CC) -o useradd $(LDFLAGS) useradd.o libshadow.a $(LIBS)
! useradd.lint: useradd.c
! $(LINT) $(LINTFLAGS) useradd.c > useradd.lint
!
! userdel: userdel.o libshadow.a
! $(CC) -o userdel $(LDFLAGS) userdel.o libshadow.a $(LIBS)
!
! userdel.lint: userdel.c
! $(LINT) $(LINTFLAGS) userdel.c > userdel.lint
!
! usermod: usermod.o libshadow.a
! $(CC) -o usermod $(LDFLAGS) usermod.o libshadow.a $(LIBS)
! usermod.lint: usermod.c
! $(LINT) $(LINTFLAGS) usermod.c > usermod.lint
sulog.o: config.h
--- 346,371 ----
id.lint: id.c
$(LINT) $(LINTFLAGS) id.c > id.lint
! useradd: useradd.o copydir.o mkrmdir.o libshadow.a
! $(CC) -o useradd $(LDFLAGS) useradd.o copydir.o mkrmdir.o \
! libshadow.a $(LIBS) $(NDIR)
! useradd.lint: useradd.c copydir.c mkrmdir.c
! $(LINT) $(LINTFLAGS) useradd.c copydir.c mkrmdir.c > useradd.lint
!
! userdel: userdel.o copydir.o mkrmdir.o libshadow.a
! $(CC) -o userdel $(LDFLAGS) userdel.o copydir.o mkrmdir.o \
! libshadow.a $(LIBS) $(NDIR)
!
! userdel.lint: userdel.c copydir.c mkrmdir.c
! $(LINT) $(LINTFLAGS) userdel.c copydir.c mkrmdir.c > userdel.lint
!
! usermod: usermod.o copydir.o mkrmdir.o libshadow.a
! $(CC) -o usermod $(LDFLAGS) usermod.o copydir.o mkrmdir.o \
! libshadow.a $(LIBS) $(NDIR)
! usermod.lint: usermod.c copydir.c mkrmdir.c
! $(LINT) $(LINTFLAGS) usermod.c copydir.c mkrmdir.c > usermod.lint
sulog.o: config.h
***************
*** 464,466 ****
--- 480,483 ----
login.sh.9: $(DOCS) Makefile
shar -a $(DOCS) > login.sh.9
+
*** rel3/chpasswd.c Thu Jun 13 21:27:57 1991
--- chpasswd.c Mon Jun 10 10:14:05 1991
***************
*** 28,39 ****
#endif
#ifndef lint
! static char sccsid[] = "@(#)chpasswd.c 3.3 09:07:09 5/28/91";
#endif
char *Prog;
extern char *pw_encrypt();
/*
* If it weren't for the different structures and differences in how
--- 28,40 ----
#endif
#ifndef lint
! static char sccsid[] = "@(#)chpasswd.c 3.4 08:57:30 6/10/91";
#endif
char *Prog;
extern char *pw_encrypt();
+ extern char *l64a();
/*
* If it weren't for the different structures and differences in how
*** rel3/config.h Thu Jun 13 21:28:42 1991
--- config.h Thu Jun 13 10:06:41 1991
***************
*** 12,18 ****
/*
* Configuration file for login.
*
! * @(#)config.h 3.8 11:11:17 6/7/91
*/
/*
--- 12,18 ----
/*
* Configuration file for login.
*
! * @(#)config.h 3.10 10:04:15 6/13/91
*/
/*
***************
*** 223,228 ****
--- 223,236 ----
#define NDBM /* */
/*
+ * Enable RLOGIN to support the "-r" and "-h" options.
+ * If your /etc/utmp provides for a host name, enable UT_HOST.
+ */
+
+ #define RLOGIN
+ #undef UT_HOST
+
+ /*
* Define file name for sulog. If SULOG is not defined, there will be
* no logging. This is NOT a good idea ... We also define other file
* names.
***************
*** 238,243 ****
--- 246,253 ----
#define GRPFILE "/etc/group"
#define OGRPFILE "/etc/group-"
#define NGRPFILE "/etc/ngroup"
+ #define OGSHADOW "/etc/gshadow-"
+ #define NGSHADOW "/etc/ngshadow"
/*
* Define PWDLOCK to be a locking semaphore for updating the password
***************
*** 247,252 ****
--- 257,263 ----
#define PWDLOCK "/etc/passwd.lock"
#define GRPLOCK "/etc/group.lock"
#define SPWLOCK "/etc/shadow.lock"
+ #define SGRPLOCK "/etc/gshadow.lock"
/*
* Define USE_SYSLOG if you want to have SYSLOG functions included
***************
*** 256,261 ****
--- 267,280 ----
#define USE_SYSLOG
#undef SULOGONLY
+
+ /*
+ * Select one of the following
+ */
+
+ #define DIR_XENIX /* include <sys/ndir.h>, use (struct direct) */
+ /* #define DIR_BSD /* include <ndir.h>, use (struct direct) */
+ /* #define DIR_SYSV /* include <dirent.h>, use (struct dirent) */
/*
* Wierd stuff follows ...
*** /dev/null Thu Jun 13 21:28:57 1991
--- copydir.c Thu Jun 13 10:09:40 1991
***************
*** 0 ****
--- 1,372 ----
+ /*
+ * Copyright 1991, John F. Haugh II
+ * An unpublished work.
+ * All rights reserved.
+ *
+ * Permission is granted to copy and create derivative works for any
+ * non-commercial purpose, provided this copyright notice is preserved
+ * in all copies of source code, or included in human readable form
+ * and conspicuously displayed on all copies of object code or
+ * distribution media.
+ */
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include "config.h"
+ #ifdef DIR_XENIX
+ #include <sys/ndir.h>
+ #define DIRECT direct
+ #endif
+ #ifdef DIR_BSD
+ #include <ndir.h>
+ #define DIRECT direct
+ #endif
+ #ifdef DIR_SYSV
+ #include <dirent.h>
+ #define DIRECT dirent
+ #endif
+ #include <fcntl.h>
+ #include <stdio.h>
+
+ #ifndef lint
+ static char sccsid[] = "@(#)copydir.c 3.1 10:09:26 6/13/91";
+ #endif
+
+ #ifndef S_ISDIR
+ #define S_ISDIR(x) (((x)&S_IFMT)==S_IFDIR)
+ #endif
+ #ifndef S_ISREG
+ #define S_ISREG(x) (((x)&S_IFMT)==S_IFREG)
+ #endif
+
+ static char *src_orig;
+ static char *dst_orig;
+
+ struct link_name {
+ int ln_dev;
+ int ln_ino;
+ int ln_count;
+ char *ln_name;
+ struct link_name *ln_next;
+ };
+ static struct link_name *links;
+
+ /*
+ * remove_link - delete a link from the link list
+ */
+
+ void
+ remove_link (link)
+ struct link_name *link;
+ {
+ struct link_name *lp;
+
+ if (links == link) {
+ links = link->ln_next;
+ free (link->ln_name);
+ free (link);
+ return;
+ }
+ for (lp = links;lp;lp = lp->ln_next)
+ if (lp->ln_next == link)
+ break;
+
+ if (! lp)
+ return;
+
+ lp->ln_next = lp->ln_next->ln_next;
+ free (link->ln_name);
+ free (link);
+ }
+
+ /*
+ * check_link - see if a file is really a link
+ */
+
+ struct link_name *
+ check_link (name, sb)
+ char *name;
+ struct stat *sb;
+ {
+ struct link_name *lp;
+ int src_len;
+ int dst_len;
+ int name_len;
+ char *malloc ();
+
+ for (lp = links;lp;lp = lp->ln_next)
+ if (lp->ln_dev == sb->st_dev && lp->ln_ino == sb->st_ino)
+ return lp;
+
+ if (sb->st_nlink == 1)
+ return 0;
+
+ lp = (struct link_name *) malloc (sizeof *lp);
+ src_len = strlen (src_orig);
+ dst_len = strlen (dst_orig);
+ name_len = strlen (name);
+ lp->ln_dev = sb->st_dev;
+ lp->ln_ino = sb->st_ino;
+ lp->ln_count = sb->st_nlink;
+ lp->ln_name = malloc (name_len - src_len + dst_len + 1);
+ sprintf (lp->ln_name, "%s%s", dst_orig, name + src_len);
+ lp->ln_next = links;
+ links = lp;
+
+ return 0;
+ }
+
+ /*
+ * copy_tree - copy files in a directory tree
+ *
+ * copy_tree() walks a directory tree and copies ordinary files
+ * as it goes.
+ */
+
+ int
+ copy_tree (src_root, dst_root, uid, gid)
+ char *src_root;
+ char *dst_root;
+ int uid;
+ int gid;
+ {
+ char src_name[BUFSIZ];
+ char dst_name[BUFSIZ];
+ char buf[BUFSIZ];
+ int ifd;
+ int ofd;
+ int err = 0;
+ int cnt;
+ int set_orig = 0;
+ struct DIRECT *ent;
+ struct stat sb;
+ struct link_name *lp;
+ DIR *dir;
+
+ /*
+ * Make certain both directories exist. This routine is called
+ * after the home directory is created, or recursively after the
+ * target is created. It assumes the target directory exists.
+ */
+
+ if (access (src_root, 0) != 0 || access (dst_root, 0) != 0)
+ return -1;
+
+ /*
+ * Open the source directory and read each entry. Every file
+ * entry in the directory is copied with the UID and GID set
+ * to the provided values. As an added security feature only
+ * regular files (and directories ...) are copied, and no file
+ * is made set-ID.
+ */
+
+ if (! (dir = opendir (src_root)))
+ return -1;
+
+ if (src_orig == 0) {
+ src_orig = src_root;
+ dst_orig = dst_root;
+ set_orig++;
+ }
+ while (ent = readdir (dir)) {
+
+ /*
+ * Skip the "." and ".." entries
+ */
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+
+ /*
+ * Make the filename for both the source and the
+ * destination files.
+ */
+
+ if (strlen (src_root) + strlen (ent->d_name) + 2 > BUFSIZ) {
+ err++;
+ break;
+ }
+ sprintf (src_name, "%s/%s", src_root, ent->d_name);
+
+ if (strlen (dst_root) + strlen (ent->d_name) + 2 > BUFSIZ) {
+ err++;
+ break;
+ }
+ sprintf (dst_name, "%s/%s", dst_root, ent->d_name);
+
+ if (stat (src_name, &sb) == -1)
+ continue;
+
+ if (S_ISDIR (sb.st_mode)) {
+
+ /*
+ * Create a new target directory, make it owned by
+ * the user and then recursively copy that directory.
+ */
+
+ mkdir (dst_name, sb.st_mode & 0777);
+ chown (dst_name, uid == -1 ? sb.st_uid:uid,
+ gid == -1 ? sb.st_gid:gid);
+
+ if (copy_tree (src_name, dst_name, uid, gid)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+
+ /*
+ * See if this is a previously copied link
+ */
+
+ if (lp = check_link (src_name, &sb)) {
+ if (link (lp->ln_name, dst_name)) {
+ err++;
+ break;
+ }
+ if (unlink (src_name)) {
+ err++;
+ break;
+ }
+ if (--lp->ln_count <= 0)
+ remove_link (lp);
+
+ continue;
+ }
+
+ /*
+ * Deal with FIFOs and special files. The user really
+ * shouldn't have any of these, but it seems like it
+ * would be nice to copy everything ...
+ */
+
+ if (! S_ISREG (sb.st_mode)) {
+ if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev) ||
+ chown (dst_name, uid == -1 ? sb.st_uid:uid,
+ gid == -1 ? sb.st_gid:gid) ||
+ chmod (dst_name, sb.st_mode & 07777)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+
+ /*
+ * Create the new file and copy the contents. The new
+ * file will be owned by the provided UID and GID values.
+ */
+
+ if ((ifd = open (src_name, O_RDONLY)) < 0) {
+ err++;
+ break;
+ }
+ if ((ofd = open (dst_name, O_WRONLY|O_CREAT, 0)) < 0 ||
+ chown (dst_name, uid == -1 ? sb.st_uid:uid,
+ gid == -1 ? sb.st_gid:gid) ||
+ chmod (dst_name, sb.st_mode & 07777)) {
+ close (ifd);
+ err++;
+ break;
+ }
+ while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
+ if (write (ofd, buf, cnt) != cnt) {
+ cnt = -1;
+ break;
+ }
+ }
+ close (ifd);
+ close (ofd);
+
+ if (cnt == -1) {
+ err++;
+ break;
+ }
+ }
+ closedir (dir);
+
+ if (set_orig) {
+ src_orig = 0;
+ dst_orig = 0;
+ }
+ return err ? -1:0;
+ }
+
+ /*
+ * remove_tree - remove files in a directory tree
+ *
+ * remove_tree() walks a directory tree and deletes all the files
+ * and directories.
+ */
+
+ int
+ remove_tree (root)
+ char *root;
+ {
+ char new_name[BUFSIZ];
+ int err = 0;
+ struct DIRECT *ent;
+ struct stat sb;
+ DIR *dir;
+
+ /*
+ * Make certain the directory exists.
+ */
+
+ if (access (root, 0) != 0)
+ return -1;
+
+ /*
+ * Open the source directory and read each entry. Every file
+ * entry in the directory is copied with the UID and GID set
+ * to the provided values. As an added security feature only
+ * regular files (and directories ...) are copied, and no file
+ * is made set-ID.
+ */
+
+ dir = opendir (root);
+
+ while (ent = readdir (dir)) {
+
+ /*
+ * Skip the "." and ".." entries
+ */
+
+ if (strcmp (ent->d_name, ".") == 0 ||
+ strcmp (ent->d_name, "..") == 0)
+ continue;
+
+ /*
+ * Make the filename for the current entry.
+ */
+
+ if (strlen (root) + strlen (ent->d_name) + 2 > BUFSIZ) {
+ err++;
+ break;
+ }
+ sprintf (new_name, "%s/%s", root, ent->d_name);
+ if (stat (new_name, &sb) == -1)
+ continue;
+
+ if (S_ISDIR (sb.st_mode)) {
+
+ /*
+ * Recursively delete this directory.
+ */
+
+ if (remove_tree (new_name)) {
+ err++;
+ break;
+ }
+ if (rmdir (new_name)) {
+ err++;
+ break;
+ }
+ continue;
+ }
+ unlink (new_name);
+ }
+ closedir (dir);
+
+ return err ? -1:0;
+ }
*** rel3/getpass.c Thu Jun 13 21:27:59 1991
--- getpass.c Mon Jun 10 10:02:54 1991
***************
*** 9,15 ****
* distribution media.
*/
! #include <sys/signal.h>
#include <stdio.h>
#include "config.h"
--- 9,15 ----
* distribution media.
*/
! #include <signal.h>
#include <stdio.h>
#include "config.h"
***************
*** 22,28 ****
#endif
#ifndef lint
! static char sccsid[] = "@(#)getpass.c 3.3 09:09:36 5/28/91";
#endif
/*
--- 22,28 ----
#endif
#ifndef lint
! static char sccsid[] = "@(#)getpass.c 3.4 08:59:38 6/10/91";
#endif
/*
*** rel3/lmain.c Thu Jun 13 21:28:01 1991
--- lmain.c Thu Jun 13 10:06:44 1991
***************
*** 44,52 ****
#endif
#ifndef lint
! static char sccsid[] = "@(#)lmain.c 3.5 09:07:32 5/28/91";
#endif
#ifndef ERASECHAR
#define ERASECHAR '\b' /* backspace */
#endif
--- 44,55 ----
#endif
#ifndef lint
! static char sccsid[] = "@(#)lmain.c 3.10 10:04:50 6/13/91";
#endif
+ /* danger - side effects */
+ #define STRFCPY(A,B) strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0'
+
#ifndef ERASECHAR
#define ERASECHAR '\b' /* backspace */
#endif
***************
*** 55,62 ****
#define KILLCHAR '\025' /* control U */
#endif
! #ifdef UT_HOST
! char host[BUFSIZ];
#endif
#ifdef HUSHLOGIN
int hushed;
--- 58,66 ----
#define KILLCHAR '\025' /* control U */
#endif
! #ifdef RLOGIN
! char host[128];
! char term[128] = "TERM=";
#endif
#ifdef HUSHLOGIN
int hushed;
***************
*** 69,74 ****
--- 73,79 ----
int rflg;
int fflg;
int hflg;
+ int preauth_flag;
#ifndef BSD
struct termio termio;
#endif
***************
*** 114,120 ****
#ifdef TZ
FILE *tzfile;
! char tzbuf[32] = TZ;
#endif
#ifndef ALARM
--- 119,125 ----
#ifdef TZ
FILE *tzfile;
! char tzbuf[BUFSIZ] = TZ;
#endif
#ifndef ALARM
***************
*** 153,172 ****
/*
* usage - print login command usage and exit
*/
usage ()
{
fprintf (stderr, "usage: login [ -p ] [ name ]\n");
! #ifdef UT_HOST
! fprintf (stderr, " login -r name\n");
! fprintf (stderr, " login [ -p ] -f name [ -h host ]\n");
#else
fprintf (stderr, " login [ -p ] -f name\n");
! #endif
exit (1);
}
/*
* login - create a new login session for a user
*
--- 158,224 ----
/*
* usage - print login command usage and exit
+ *
+ * login [ name ]
+ * login -r hostname (for rlogind)
+ * login -h hostname (for telnetd, etc.)
+ * login -f name (for pre-authenticated login: datakit, xterm, etc.)
*/
usage ()
{
fprintf (stderr, "usage: login [ -p ] [ name ]\n");
! #ifdef RLOGIN
! #ifdef LAI_TCP
! fprintf (stderr, " login -r rem_host rem_name name\n");
#else
+ fprintf (stderr, " login [ -p ] -r name\n");
+ #endif /* LAI_TCP */
+ fprintf (stderr, " login [ -p ] [ -f name ] -h host\n");
+ #else
fprintf (stderr, " login [ -p ] -f name\n");
! #endif /* RLOGIN */
exit (1);
}
+ #ifdef RLOGIN
+ rlogin (host, name, namelen)
+ char *host;
+ char *name;
+ int namelen;
+ {
+ struct passwd *pwd;
+ char remote_name[32];
+ char *cp;
+
+ get_remote_string (remote_name, sizeof remote_name);
+ get_remote_string (name, namelen);
+ get_remote_string (term + 5, sizeof term - 5);
+ if (cp = strchr (term, '/'))
+ *cp = '\0';
+
+ if (! (pwd = getpwnam (name)))
+ return 0;
+
+ return ruserok (host, pwd->pw_uid == 0, remote_name, name);
+ }
+
+ get_remote_string (buf, size)
+ char *buf;
+ int size;
+ {
+ for (;;) {
+ if (read (0, buf, 1) != 1)
+ exit (1);
+ if (*buf == '\0')
+ return;
+ if (--size > 0)
+ ++buf;
+ }
+ /*NOTREACHED*/
+ }
+ #endif
+
/*
* login - create a new login session for a user
*
***************
*** 223,230 ****
*/
checkutmp (argc > 1 && argv[1][0] != '-');
! strncpy (tty, utent.ut_line, sizeof tty);
! tty[sizeof tty - 1] = '\0';
if (Prog = strrchr (argv[0], '/'))
Prog++;
--- 275,281 ----
*/
checkutmp (argc > 1 && argv[1][0] != '-');
! STRFCPY (tty, utent.ut_line);
if (Prog = strrchr (argv[0], '/'))
Prog++;
***************
*** 231,237 ****
else
Prog = argv[0];
! #ifdef UT_HOST
while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
#else
while ((flag = getopt (argc, argv, "pf:")) != EOF)
--- 282,310 ----
else
Prog = argv[0];
! #ifdef LAI_TCP /*{*/
! /*
! * SCO/Lachman rlogind calls:
! * /bin/login -r rem_host rem_name local_name"
! */
! if ( argc == 5 && strcmp(argv[1], "-r") == 0 ) {
! char rem_name[16];
! int root_user;
!
! STRFCPY(host, argv[2]);
! STRFCPY(rem_name, argv[3]);
! STRFCPY(name, argv[4]);
!
! root_user = ((pwd = getpwnam(name)) && pwd->pw_uid == 0);
! preauth_flag = ! ruserok(host, root_user, rem_name, name);
! pflg++; /* in case SCO ever fixes rlogind */
! rflg++;
! argc = 1;
! argv[1] = NULL;
! }
! #endif /*}LAI_TCP*/
!
! #ifdef RLOGIN
while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
#else
while ((flag = getopt (argc, argv, "pf:")) != EOF)
***************
*** 240,286 ****
switch (flag) {
case 'p': pflg++;
break;
! case 'f': fflg++;
! strncpy (name, optarg, sizeof name);
break;
#ifdef UT_HOST
! case 'r': rflg++;
! strncpy (name, optarg, sizeof name);
break;
! case 'h': hflg++;
! strncpy (host, optarg, sizeof host);
! strncpy (utmp.ut_host, host,
! sizeof utmp.ut_host);
break;
! #endif
default:
usage ();
}
}
/*
! * The -r option is not valid with any other flags
*/
! if (rflg && (hflg || fflg || pflg))
usage ();
-
- #ifdef USE_SYSLOG
- openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
#endif
/*
! * The -r and -f flags both require the real UID to be
! * zero. No authentication may be required for these
! * flags, so the user must already be root.
*/
if ((rflg || fflg) && getuid () != 0) {
#ifdef USE_SYSLOG
! closelog ();
#endif
! exit (1); /* only root can use -r or -f */
! }
if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
#ifdef USE_SYSLOG
closelog ();
--- 313,369 ----
switch (flag) {
case 'p': pflg++;
break;
! case 'f':
! fflg++;
! preauth_flag++;
! STRFCPY (name, optarg);
break;
+ #ifdef RLOGIN
+ case 'r':
+ rflg++;
+ STRFCPY (host, optarg);
#ifdef UT_HOST
! STRFCPY (utent.ut_host, optarg);
! #endif /*UT_HOST*/
! if (rlogin (host, name, sizeof name))
! preauth_flag++;
!
break;
! case 'h':
! hflg++;
! STRFCPY (host, optarg);
! #ifdef UT_HOST
! STRFCPY (utent.ut_host, optarg);
! #endif /*UT_HOST*/
break;
! #endif /*RLOGIN*/
default:
usage ();
}
}
+ #ifdef RLOGIN
/*
! * Neither -h nor -f should be combined with -r.
*/
! if (rflg && (hflg || fflg))
usage ();
#endif
/*
! * Allow authentication bypass only if real UID is zero.
*/
if ((rflg || fflg) && getuid () != 0) {
+ fprintf(stderr, "%s: permission denied\n", Prog);
+ exit (1);
+ }
+
#ifdef USE_SYSLOG
! openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
#endif
!
if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
#ifdef USE_SYSLOG
closelog ();
***************
*** 312,319 ****
while (*envp) /* add inherited environment, */
addenv (*envp++); /* some variables change later */
#ifdef TZ
! if (! pflg) {
if (tzbuf[0] == '/') {
if ((tzfile = fopen (tzbuf, "r")) != (FILE *) 0) {
if (fgets (tzbuf, sizeof tzbuf, tzfile)) {
--- 395,406 ----
while (*envp) /* add inherited environment, */
addenv (*envp++); /* some variables change later */
+ #ifdef RLOGIN
+ if (term[5] != '\0') /* see if anything after "TERM=" */
+ addenv (term);
+ #endif
#ifdef TZ
! if (! pflg || ! getenv("TZ")) {
if (tzbuf[0] == '/') {
if ((tzfile = fopen (tzbuf, "r")) != (FILE *) 0) {
if (fgets (tzbuf, sizeof tzbuf, tzfile)) {
***************
*** 328,342 ****
}
#endif /* TZ */
#ifdef HZ
! if (! pflg)
addenv (HZ); /* set the default $HZ, if one */
#endif /* HZ */
- if (optind < argc) { /* now set command line variables */
- if (optind + 1 < argc)
- setenv (argc - optind - 1, &argv[optind + 1]);
! (void) strncpy (name, argv[optind], sizeof name);
}
top:
(void) alarm (ALARM); /* only allow ALARM sec. for login */
--- 415,434 ----
}
#endif /* TZ */
#ifdef HZ
! if (! pflg || ! getenv("HZ"))
addenv (HZ); /* set the default $HZ, if one */
#endif /* HZ */
! if (optind < argc) { /* get the user name */
! if (rflg || fflg)
! usage ();
!
! STRFCPY (name, argv[optind]);
! ++optind;
}
+ if (optind < argc) /* now set command line variables */
+ setenv (argc - optind, &argv[optind]);
+
top:
(void) alarm (ALARM); /* only allow ALARM sec. for login */
***************
*** 351,357 ****
#endif
exit (1);
}
! rflg = fflg = 0;
login (name);
continue;
}
--- 443,451 ----
#endif
exit (1);
}
! #ifdef RLOGIN
! preauth_flag = 0;
! #endif
login (name);
continue;
}
***************
*** 373,385 ****
} else
failed = 1; /* will never pass validation */
/*
* The -r and -f flags provide a name which has already
* been authenticated by some server.
*/
! if (pwent.pw_name && (rflg || fflg))
goto have_name;
/*
* Get the user's password. One will only be prompted for
--- 467,481 ----
} else
failed = 1; /* will never pass validation */
+ #ifdef RLOGIN
/*
* The -r and -f flags provide a name which has already
* been authenticated by some server.
*/
! if (pwent.pw_name && preauth_flag)
goto have_name;
+ #endif /*RLOGIN*/
/*
* Get the user's password. One will only be prompted for
***************
*** 393,399 ****
continue;
if (cp)
! strncpy (pass, cp, sizeof pass);
if (! valid (pass, &pwent)) { /* check encrypted passwords */
#ifdef USE_SYSLOG
--- 489,495 ----
continue;
if (cp)
! STRFCPY (pass, cp);
if (! valid (pass, &pwent)) { /* check encrypted passwords */
#ifdef USE_SYSLOG
***************
*** 467,472 ****
--- 563,569 ----
break;
puts ("Login incorrect");
+ #ifdef RLOGIN
if (rflg || fflg) {
#ifdef USE_SYSLOG
closelog ();
***************
*** 473,478 ****
--- 570,576 ----
#endif
exit (1);
}
+ #endif /*RLOGIN*/
#ifdef FAILLOG
if (pwent.pw_name) /* don't log non-existent users */
failure (pwent.pw_uid, tty, &faillog);
***************
*** 481,493 ****
failent = utent;
if (pwent.pw_name)
! strncpy (failent.ut_name,
! pwent.pw_name, sizeof failent.ut_name);
else
#ifdef UNKNOWNS
! strcpy (failent.ut_name, name);
#else /* !UNKNOWNS */
! strcpy (failent.ut_name, "UNKNOWN");
#endif /* UNKNOWNS */
time (&failent.ut_time);
failent.ut_type = USER_PROCESS;
--- 579,590 ----
failent = utent;
if (pwent.pw_name)
! STRFCPY (failent.ut_name, pwent.pw_name);
else
#ifdef UNKNOWNS
! STRFCPY (failent.ut_name, name);
#else /* !UNKNOWNS */
! STRFCPY (failent.ut_name, "UNKNOWN");
#endif /* UNKNOWNS */
time (&failent.ut_time);
failent.ut_type = USER_PROCESS;
***************
*** 575,581 ****
--- 672,680 ----
hushed = access (hush, 0) == 0;
#endif /* HUSHLOGIN */
#ifdef MOTD
+ #ifdef HUSHLOGIN
if (! hushed)
+ #endif
motd (); /* print the message of the day */
#endif
#ifdef FAILLOG
***************
*** 583,603 ****
failprint (pwent.pw_uid, &faillog);
#endif /* FAILLOG */
#ifdef LASTLOG
! if (lastlog.ll_time != 0 && ! hushed)
! printf ("Last login: %.19s on %s\n",
! ctime (&lastlog.ll_time), lastlog.ll_line);
#endif /* LASTLOG */
#ifdef AGING
if (! hushed)
agecheck (&pwent, spwd);
#endif /* AGING */
#ifdef MAILCHECK
if (! hushed)
mailcheck (); /* report on the status of mail */
#endif /* MAILCHECK */
#ifdef TTYTYPE
! if (! pflg)
! ttytype (tty);
#endif /* TTYTYPE */
signal (SIGINT, SIG_DFL); /* default interrupt signal */
signal (SIGQUIT, SIG_DFL); /* default quit signal */
--- 682,709 ----
failprint (pwent.pw_uid, &faillog);
#endif /* FAILLOG */
#ifdef LASTLOG
! #ifdef HUSHLOGIN
! if (! hushed)
! #endif
! if (lastlog.ll_time != 0)
! printf ("Last login: %.19s on %s\n",
! ctime (&lastlog.ll_time), lastlog.ll_line);
#endif /* LASTLOG */
#ifdef AGING
+ #ifdef HUSHLOGIN
if (! hushed)
+ #endif
agecheck (&pwent, spwd);
#endif /* AGING */
#ifdef MAILCHECK
+ #ifdef HUSHLOGIN
if (! hushed)
+ #endif
mailcheck (); /* report on the status of mail */
#endif /* MAILCHECK */
#ifdef TTYTYPE
! if (! getenv("TERM"))
! ttytype (tty);
#endif /* TTYTYPE */
signal (SIGINT, SIG_DFL); /* default interrupt signal */
signal (SIGQUIT, SIG_DFL); /* default quit signal */
*** /dev/null Thu Jun 13 21:28:57 1991
--- mkrmdir.c Thu Jun 13 10:09:40 1991
***************
*** 0 ****
--- 1,76 ----
+ /*
+ * Copyright 1991, John F. Haugh II
+ * An unpublished work.
+ * All rights reserved.
+ *
+ * Permission is granted to copy and create derivative works for any
+ * non-commercial purpose, provided this copyright notice is preserved
+ * in all copies of source code, or included in human readable form
+ * and conspicuously displayed on all copies of object code or
+ * distribution media.
+ */
+
+ #include <fcntl.h>
+ #include "config.h"
+
+ #ifndef lint
+ static char sccsid[] = "@(#)mkrmdir.c 3.1 10:09:21 6/13/91";
+ #endif
+
+ #ifdef NEED_MKDIR
+ /*
+ * mkdir - create a directory
+ *
+ * mkdir is provided for systems which do not include the mkdir()
+ * system call.
+ */
+
+ int
+ mkdir (dir, mode)
+ char *dir;
+ int mode;
+ {
+ int status;
+
+ if (fork ()) {
+ while (wait (&status) != -1)
+ ;
+
+ return status >> 8;
+ }
+ #ifdef USE_SYSLOG
+ closelog ();
+ #endif
+ close (2);
+ open ("/dev/null", O_WRONLY);
+ umask (0777 & ~ mode);
+ execl ("/bin/mkdir", "mkdir", dir, 0);
+ _exit (128);
+ }
+ #endif
+ #ifdef NEED_RMDIR
+ /*
+ * rmdir - remove a directory
+ *
+ * rmdir is provided for systems which do not include the rmdir()
+ * system call.
+ */
+
+ int
+ rmdir (dir)
+ char *dir;
+ {
+ int status;
+
+ if (fork ()) {
+ while (wait (&status) != -1)
+ ;
+
+ return status >> 8;
+ }
+ close (2);
+ open ("/dev/null", O_WRONLY);
+ execl ("/bin/rmdir", "rmdir", dir, 0);
+ _exit (128);
+ }
+ #endif
*** rel3/useradd.c Thu Jun 13 21:28:44 1991
--- useradd.c Thu Jun 13 10:06:45 1991
***************
*** 10,16 ****
*/
#ifndef lint
! static char sccsid[] = "@(#)useradd.c 3.1 11:08:18 6/7/91";
#endif
#include <sys/types.h>
--- 10,16 ----
*/
#ifndef lint
! static char sccsid[] = "@(#)useradd.c 3.2 20:15:10 6/11/91";
#endif
#include <sys/types.h>
***************
*** 43,48 ****
--- 43,49 ----
gid_t def_group;
char def_home[BUFSIZ];
char def_shell[BUFSIZ];
+ char def_template[BUFSIZ] = "/etc/skel";
long def_inactive;
long def_expire;
char def_file[] = "/etc/default/useradd";
***************
*** 51,56 ****
--- 52,59 ----
#define NGROUPS_MAX 64
#endif
+ #define VALID(s) (strcspn (s, ":\n") == strlen (s))
+
char user_name[BUFSIZ];
uid_t user_id;
gid_t user_gid;
***************
*** 141,177 ****
0, 31, 59, 90, 120, 151, /* JAN - JUN */
181, 212, 243, 273, 304, 334 }; /* JUL - DEC */
- #ifdef NEED_MKDIR
- /*
- * mkdir - create a directory
- *
- * mkdir is provided for systems which do not include the mkdir()
- * system call.
- */
-
- int
- mkdir (dir, mode)
- char *dir;
- int mode;
- {
- int status;
-
- if (fork ()) {
- while (wait (&status) != -1)
- ;
-
- return status >> 8;
- }
- #ifdef USE_SYSLOG
- closelog ();
- #endif
- close (2);
- open ("/dev/null", O_WRONLY);
- umask (0777 & ~ mode);
- execl ("/bin/mkdir", "mkdir", dir, 0);
- _exit (128);
- }
- #endif
#ifdef NEED_RENAME
/*
* rename - rename a file to another name
--- 144,149 ----
***************
*** 927,932 ****
--- 899,910 ----
while ((arg = getopt (argc, argv, "Du:og:G:d:s:c:mk:f:e:b:")) != EOF) {
switch (arg) {
case 'b':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
bflg++;
if (! Dflg)
usage ();
***************
*** 934,943 ****
--- 912,933 ----
strncpy (def_home, optarg, BUFSIZ);
break;
case 'c':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
cflg++;
strncpy (user_comment, optarg, BUFSIZ);
break;
case 'd':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
dflg++;
strncpy (user_home, optarg, BUFSIZ);
break;
***************
*** 987,992 ****
--- 977,983 ----
if (! mflg)
usage ();
+ strncpy (def_template, optarg, BUFSIZ);
kflg++;
break;
case 'm':
***************
*** 999,1004 ****
--- 990,1001 ----
oflg++;
break;
case 's':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
sflg++;
strncpy (user_shell, optarg, BUFSIZ);
break;
***************
*** 1086,1096 ****
exit (1);
}
if (! spw_lock ()) {
! fprintf ("%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf ("%s: cannot open shadow password file\n", Prog);
exit (1);
}
}
--- 1083,1093 ----
exit (1);
}
if (! spw_lock ()) {
! fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
exit (1);
}
}
***************
*** 1236,1244 ****
usr_update ();
! if (mflg)
create_home ();
!
close_files ();
exit (0);
/*NOTREACHED*/
--- 1233,1242 ----
usr_update ();
! if (mflg) {
create_home ();
! copy_tree (def_template, user_home, user_id, user_gid);
! }
close_files ();
exit (0);
/*NOTREACHED*/
*** rel3/userdel.c Thu Jun 13 21:28:45 1991
--- userdel.c Thu Jun 13 21:16:54 1991
***************
*** 10,16 ****
*/
#ifndef lint
! static char sccsid[] = "@(#)userdel.c 3.1 11:08:47 6/7/91";
#endif
#include <sys/types.h>
--- 10,16 ----
*/
#ifndef lint
! static char sccsid[] = "@(#)userdel.c 3.5 20:53:04 6/13/91";
#endif
#include <sys/types.h>
***************
*** 90,123 ****
extern char *malloc();
- #ifdef NEED_RMDIR
/*
- * rmdir - remove a directory
- *
- * rmdir is provided for systems which do not include the rmdir()
- * system call.
- */
-
- int
- rmdir (dir)
- char *dir;
- {
- int status;
-
- if (fork ()) {
- while (wait (&status) != -1)
- ;
-
- return status >> 8;
- }
- close (2);
- open ("/dev/null", O_WRONLY);
- execl ("/bin/rmdir", "rmdir", dir, 0);
- _exit (128);
- }
- #endif
-
- /*
* del_list - delete a member from a list of group members
*
* the array of member names is searched for the old member
--- 90,96 ----
***************
*** 175,181 ****
usage ()
{
fprintf (stderr, "usage: userdel [-r] name\n");
! exit (1);
}
/*
--- 148,154 ----
usage ()
{
fprintf (stderr, "usage: userdel [-r] name\n");
! exit (2);
}
/*
***************
*** 224,239 ****
Prog);
exit (1);
}
- #ifdef NDBM
/*
* Update the DBM group file with the new entry as well.
*/
if (! gr_dbm_update (grp)) {
fprintf (stderr, "%s: cannot update dbm group entry\n",
Prog);
exit (1);
}
#endif
}
--- 197,216 ----
Prog);
exit (1);
}
/*
* Update the DBM group file with the new entry as well.
*/
+ #ifdef NDBM
if (! gr_dbm_update (grp)) {
fprintf (stderr, "%s: cannot update dbm group entry\n",
Prog);
exit (1);
}
+ #endif /* NDBM */
+ #ifdef USE_SYSLOG
+ syslog (LOG_INFO, "delete `%s' from group `%s'\n",
+ user_name, grp->gr_name);
#endif
}
***************
*** 287,292 ****
--- 264,273 ----
exit (1);
}
#endif
+ #ifdef USE_SYSLOG
+ syslog (LOG_INFO, "delete `%s' from shadow group `%s'\n",
+ user_name, grp->gr_name);
+ #endif
}
#endif
}
***************
*** 312,318 ****
if (! gr_close ()) {
fprintf (stderr, "%s: cannot rewrite group file\n",
Prog);
! exit (1);
}
(void) gr_unlock ();
#ifdef SHADOWGRP
--- 293,299 ----
if (! gr_close ()) {
fprintf (stderr, "%s: cannot rewrite group file\n",
Prog);
! exit (10);
}
(void) gr_unlock ();
#ifdef SHADOWGRP
***************
*** 319,325 ****
if (! sgr_close ()) {
fprintf (stderr, "%s: cannot rewrite shadow group file\n",
Prog);
! exit (1);
}
(void) sgr_unlock ();
#endif
--- 300,306 ----
if (! sgr_close ()) {
fprintf (stderr, "%s: cannot rewrite shadow group file\n",
Prog);
! exit (10);
}
(void) sgr_unlock ();
#endif
***************
*** 343,353 ****
exit (1);
}
if (! spw_lock ()) {
! fprintf ("%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf ("%s: cannot open shadow password file\n", Prog);
exit (1);
}
if (! gr_lock ()) {
--- 324,334 ----
exit (1);
}
if (! spw_lock ()) {
! fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
exit (1);
}
if (! gr_lock ()) {
***************
*** 414,419 ****
--- 395,403 ----
fprintf (stderr, "%s: error deleting shadow passwd dbm entry\n",
Prog);
#endif
+ #ifdef USE_SYSLOG
+ syslog (LOG_INFO, "delete user `%s'\n", user_name);
+ #endif
}
/*
***************
*** 426,431 ****
--- 410,416 ----
{
struct passwd *pwd;
int arg;
+ int errors = 0;
extern int optind;
extern char *optarg;
***************
*** 475,481 ****
if (! (pwd = getpwnam (user_name))) {
fprintf (stderr, "%s: user %s does not exist\n",
Prog, user_name);
! exit (1);
}
user_id = pwd->pw_uid;
strcpy (user_home, pwd->pw_dir);
--- 460,466 ----
if (! (pwd = getpwnam (user_name))) {
fprintf (stderr, "%s: user %s does not exist\n",
Prog, user_name);
! exit (6);
}
user_id = pwd->pw_uid;
strcpy (user_home, pwd->pw_dir);
***************
*** 490,499 ****
update_user ();
update_groups ();
! if (rflg)
! rmdir (user_home);
!
close_files ();
! exit (0);
/*NOTREACHED*/
}
--- 475,485 ----
update_user ();
update_groups ();
! if (rflg) {
! if (remove_tree (user_home) || rmdir (user_home))
! errors++;
! }
close_files ();
! exit (errors ? 12:0);
/*NOTREACHED*/
}
*** rel3/usermod.c Thu Jun 13 21:28:46 1991
--- usermod.c Thu Jun 13 10:06:47 1991
***************
*** 10,16 ****
*/
#ifndef lint
! static char sccsid[] = "@(#)usermod.c 3.1 11:08:35 6/7/91";
#endif
#include <sys/types.h>
--- 10,16 ----
*/
#ifndef lint
! static char sccsid[] = "@(#)usermod.c 3.2 20:26:57 6/11/91";
#endif
#include <sys/types.h>
***************
*** 44,49 ****
--- 44,51 ----
#define NGROUPS_MAX 64
#endif
+ #define VALID(s) (strcspn (s, ":\n") == strlen (s))
+
char user_name[BUFSIZ];
char user_newname[BUFSIZ];
uid_t user_id;
***************
*** 115,121 ****
extern int spw_lock();
extern int spw_unlock();
extern int spw_open();
! extern int spw_locate();
#define DAY (24L*3600L)
#define WEEK (7*DAY)
--- 117,123 ----
extern int spw_lock();
extern int spw_unlock();
extern int spw_open();
! extern struct spwd *spw_locate();
#define DAY (24L*3600L)
#define WEEK (7*DAY)
***************
*** 140,176 ****
0, 31, 59, 90, 120, 151, /* JAN - JUN */
181, 212, 243, 273, 304, 334 }; /* JUL - DEC */
- #ifdef NEED_MKDIR
- /*
- * mkdir - create a directory
- *
- * mkdir is provided for systems which do not include the mkdir()
- * system call.
- */
-
- int
- mkdir (dir, mode)
- char *dir;
- int mode;
- {
- int status;
-
- if (fork ()) {
- while (wait (&status) != -1)
- ;
-
- return status >> 8;
- }
- #ifdef USE_SYSLOG
- closelog ();
- #endif
- close (2);
- open ("/dev/null", O_WRONLY);
- umask (0777 & ~ mode);
- execl ("/bin/mkdir", "mkdir", dir, 0);
- _exit (128);
- }
- #endif
#ifdef NEED_RENAME
/*
* rename - rename a file to another name
--- 142,147 ----
***************
*** 831,836 ****
--- 802,813 ----
while ((arg = getopt (argc, argv, "u:og:G:d:s:c:mf:e:l:")) != EOF) {
switch (arg) {
case 'c':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
if (strcmp (optarg, user_comment)) {
cflg++;
strncpy (user_comment, optarg, BUFSIZ);
***************
*** 837,842 ****
--- 814,825 ----
}
break;
case 'd':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
dflg++;
strncpy (user_newhome, optarg, BUFSIZ);
break;
***************
*** 880,885 ****
--- 863,874 ----
break;
case 'l':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
if (strcmp (user_name, optarg)) {
lflg++;
strcpy (user_newname, optarg);
***************
*** 898,903 ****
--- 887,898 ----
oflg++;
break;
case 's':
+ if (! VALID (optarg)) {
+ fprintf (stderr,
+ "%s: invalid field `%s'\n",
+ Prog, optarg);
+ exit (3);
+ }
if (strcmp (user_shell, optarg)) {
strncpy (user_shell, optarg, BUFSIZ);
sflg++;
***************
*** 980,990 ****
exit (1);
}
if (! spw_lock ()) {
! fprintf ("%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf ("%s: cannot open shadow password file\n", Prog);
exit (1);
}
}
--- 975,985 ----
exit (1);
}
if (! spw_lock ()) {
! fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
exit (1);
}
if (! spw_open (O_RDWR)) {
! fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
exit (1);
}
}
***************
*** 1076,1087 ****
move_home ()
{
! if (mflg && access (user_home, 0) == 0) {
if (access (user_newhome, 0) == 0) {
fprintf (stderr, "%s: directory %s exists\n",
Prog, user_newhome);
exit (12);
} else if (rename (user_home, user_newhome)) {
fprintf (stderr,
"%s: cannot rename directory %s to %s\n",
Prog, user_home, user_newhome);
--- 1071,1100 ----
move_home ()
{
! struct stat sb;
!
! if (mflg && stat (user_home, &sb) == 0) {
if (access (user_newhome, 0) == 0) {
fprintf (stderr, "%s: directory %s exists\n",
Prog, user_newhome);
exit (12);
} else if (rename (user_home, user_newhome)) {
+ if (errno == EXDEV) {
+ if (mkdir (user_newhome, sb.st_mode & 0777)) {
+ fprintf (stderr,
+ "%s: can't create %s\n",
+ Prog, user_newhome);
+ }
+ chown (user_newhome, sb.st_uid, sb.st_gid);
+ if (copy_tree (user_home, user_newhome,
+ -1, -1) == 0 &&
+ remove_tree (user_home) == 0 &&
+ rmdir (user_home) == 0)
+ return;
+
+ remove_tree (user_newhome);
+ rmdir (user_newhome);
+ }
fprintf (stderr,
"%s: cannot rename directory %s to %s\n",
Prog, user_home, user_newhome);
--
John F. Haugh II | Distribution to | UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 255-8251 | GEnie PROHIBITED :-) | Domain: jfh at rpp386.cactus.org
"I carry a lot of weight, and I carry it well."
-- Rush Limbaugh
More information about the Alt.sources
mailing list