]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
contrib/: Burn it all
authorAlejandro Colomar <alx@kernel.org>
Fri, 13 Jun 2025 11:49:19 +0000 (13:49 +0200)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Wed, 18 Jun 2025 07:15:02 +0000 (09:15 +0200)
Closes: <https://github.com/shadow-maint/shadow/issues/1273>
Cc: Chris Hofstaedtler <zeha@debian.org>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Makefile.am
configure.ac
contrib/Makefile.am [deleted file]
contrib/README [deleted file]
contrib/adduser.c [deleted file]
contrib/adduser.sh [deleted file]
contrib/adduser2.sh [deleted file]

index 47eb9c44045f2b9d8e702d9d03d7163f92527f57..4c9c655f606499514fc7515dd9d4c1a91f3f0b38 100644 (file)
@@ -6,7 +6,7 @@ if ENABLE_SUBIDS
 SUBDIRS += libsubid
 endif
 
-SUBDIRS += src po contrib doc etc tests/unit
+SUBDIRS += src po doc etc tests/unit
 
 if ENABLE_REGENERATE_MAN
 SUBDIRS += man
index 92e2dd299d5579cd3e8e08951d9cb5e9d7a8743d..f849070b3307801485a5d30c378ea0a2ae5dbbef 100644 (file)
@@ -683,7 +683,6 @@ AC_CONFIG_FILES([
        libsubid/Makefile
        libsubid/subid.h
        src/Makefile
-       contrib/Makefile
        etc/Makefile
        etc/pam.d/Makefile
        etc/shadow-maint/Makefile
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
deleted file mode 100644 (file)
index dc3ccd2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# This is a dummy Makefile.am to get automake work flawlessly,
-# and also cooperate to make a distribution for `make dist'
-
-EXTRA_DIST = README adduser.c adduser.sh adduser2.sh
diff --git a/contrib/README b/contrib/README
deleted file mode 100644 (file)
index 6002923..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-People keep sending various adduser programs and scripts...  They are
-all in this directory.  I haven't tested them, use at your own risk.
-Anyway, the best one I've seen so far is adduser-3.x from Debian.
-
-udbachk.tgz is a passwd/group/shadow file integrity checker.
-
---marekm
diff --git a/contrib/adduser.c b/contrib/adduser.c
deleted file mode 100644 (file)
index 9e16215..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/****
-** 04/21/96
-** hacked even more, replaced gets() with something slightly harder to buffer
-** overflow. Added support for setting a default quota on new account, with
-** edquota -p. Other cleanups for security, I let some users run adduser suid
-** root to add new accounts. (overflow checks, clobber environment, valid 
-** shell checks, restrictions on gid + home dir settings).
-
-** Added max. username length. Used syslog() a bit for important events. 
-** Support to immediately expire account with passwd -e.
-
-** Called it version 2.0! Because I felt like it!
-
-** -- Chris, chris@ferret.lmh.ox.ac.uk
-
-** 03/17/96
-** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
-** --marekm
-**
-** 02/26/96
-** modified to call shadow utils (useradd,chage,passwd) on shadowed 
-** systems - Cristian Gafton, gafton@sorosis.ro
-**
-** 6/27/95
-** shadow-adduser 1.4:
-**
-** now it copies the /etc/skel dir into the person's dir, 
-** makes the mail folders, changed some defaults and made a 'make 
-** install' just for the hell of it.
-**
-** Greg Gallagher
-** CIN.Net
-**
-** 1/28/95
-** shadow-adduser 1.3:
-** 
-** Basically a bug-fix on my additions in 1.2.  Thanks to Terry Stewart 
-** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
-** It was such a stupid bug that I would have never seen it myself.
-**
-**                                Brandon
-*****
-** 01/27/95
-** 
-** shadow-adduser 1.2:
-** I took the C source from adduser-shadow (credits are below) and made
-** it a little more worthwhile.  Many small changes... Here's
-** the ones I can remember:
-** 
-** Removed support for non-shadowed systems (if you don't have shadow,
-**     use the original adduser, don't get this shadow version!)
-** Added support for the correct /etc/shadow fields (Min days before
-**     password change, max days before password change, Warning days,
-**     and how many days from expiry date does the account go invalid)
-**     The previous version just left all of those fields blank.
-**     There is still one field left (expiry date for the account, period)
-**     which I have left blank because I do not use it and didn't want to
-**     spend any more time on this.  I'm sure someone will put it in and
-**     tack another plethora of credits on here. :)
-** Added in the password date field, which should always reflect the last
-**     date the password was changed, for expiry purposes.  "passwd" always
-**     updates this field, so the adduser program should set it up right
-**     initially (or a user could keep their initial password forever ;)
-**     The number is in days since Jan 1st, 1970.
-**
-**                       Have fun with it, and someone please make
-**                       a real version(this is still just a hack)
-**                       for us all to use (and Email it to me???)
-**
-**                               Brandon
-**                                  photon@usis.com
-**
-***** 
-** adduser 1.0: add a new user account (For systems not using shadow)
-** With a nice little interface and a will to do all the work for you.
-**
-** Craig Hagan
-** hagan@opine.cs.umass.edu
-**
-** Modified to really work, look clean, and find unused uid by Chris Cappuccio
-** chris@slinky.cs.umass.edu
-**
-*****
-**
-** 01/19/95
-**
-** FURTHER modifications to enable shadow passwd support (kludged, but
-** no more so than the original)  by Dan Crowson - dcrowson@mo.net
-**
-** Search on DAN for all changes...
-**
-*****
-**
-** cc -O -o adduser adduser.c
-** Use gcc if you have it... (political reasons beyond my control) (chris)
-**
-** I've gotten this program to work with success under Linux (without
-** shadow) and SunOS 4.1.3. I would assume it should work pretty well
-** on any system that uses no shadow. (chris)
-**
-** If you have no crypt() then try
-** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
-** I'm not sure how login operates with no crypt()... I guess
-** the same way we're doing it here.
-*/
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <pwd.h>
-#include <grp.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/timeb.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#include "string/strcmp/streq.h"
-#include "string/strcmp/strcaseprefix.h"
-
-
-#define IMMEDIATE_CHANGE       /* Expire newly created password, must be changed
-                                * immediately upon next login */
-#define HAVE_QUOTAS            /* Obvious */
-#define EXPIRE_VALS_SET                /* If defined, 'normal' users can't change 
-                                * password expiry values (if running suid root) */
-
-#define LOGGING                        /* If we want to log various things to syslog */
-#define MAX_USRNAME  8         /* Longer usernames seem to work on my system....
-                                * But they're probably a poor idea */
-
-
-#define DEFAULT_SHELL  "/bin/bash"     /* because BASH is your friend */
-#define DEFAULT_HOME   "/home"
-#define USERADD_PATH   "/usr/sbin/useradd"
-#define CHAGE_PATH     "/usr/bin/chage"
-#define PASSWD_PATH    "/usr/bin/passwd"
-#define EDQUOTA_PATH   "/usr/sbin/edquota"
-#define QUOTA_DEFAULT  "defuser"
-#define DEFAULT_GROUP  100
-
-#define DEFAULT_MIN_PASS 0
-#define DEFAULT_MAX_PASS 100
-#define DEFAULT_WARN_PASS 14
-#define DEFAULT_USER_DIE 366
-
-void safeget (char *, int);
-
-void 
-main (void)
-{
-  char foo[32];
-  char usrname[32], person[32], dir[32], shell[32];
-  unsigned int group, min_pass, max_pass, warn_pass, user_die;
-  /* the group and uid of the new user */
-  int bad = 0, done = 0, correct = 0, olduid;
-  char cmd[255];
-  struct group *grp;
-
-  /* flags, in order:
-   * bad to see if the username is in /etc/passwd, or if strange stuff has
-   * been typed if the user might be put in group 0
-   * done allows the program to exit when a user has been added
-   * correct loops until a username is found that isn't in /etc/passwd
-   */
-
-  /* The real program starts HERE! */
-
-  if (geteuid () != 0)
-    {
-      printf ("It seems you don't have access to add a new user.  Try\n");
-      printf ("logging in as root or su root to gain superuser access.\n");
-      exit (1);
-    }
-
-  /* Sanity checks
-   */
-
-#ifdef LOGGING
-  openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
-  syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
-#endif
-
-  if (!(grp = getgrgid (DEFAULT_GROUP)))
-    {
-      printf ("Error: the default group %d does not exist on this system!\n",
-             DEFAULT_GROUP);
-      printf ("adduser must be recompiled.\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "warning: failed. no such default group\n");
-      closelog ();
-#endif
-      exit (1);
-    };
-
-  while (!correct)
-    {                          /* loop until a "good" usrname is chosen */
-      while (!done)
-       {
-         printf ("\nLogin to add (^C to quit): ");
-         fflush (stdout);
-
-         safeget (usrname, sizeof (usrname));
-
-         if (!strlen (usrname))
-           {
-             printf ("Empty input.\n");
-             done = 0;
-             continue;
-           };
-
-         /* what I saw here before made me think maybe I was running DOS */
-         /* might this be a solution? (chris) */
-         if (strlen (usrname) > MAX_USRNAME)
-           {
-             printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
-             done = 0;
-           }
-         else if (getpwnam (usrname) != NULL)
-           {
-             printf ("That name is in use, choose another.\n");
-             done = 0;
-           }
-         else if (strchr (usrname, ' ') != NULL)
-           {
-             printf ("No spaces in username!!\n");
-             done = 0;
-           }
-         else
-           done = 1;
-       };                      /* done, we have a valid new user name */
-
-      /* all set, get the rest of the stuff */
-      printf ("\nEditing information for new user [%s]\n", usrname);
-
-      printf ("\nFull Name [%s]: ", usrname);
-      fflush (stdout);
-      safeget (person, sizeof (person));
-      if (!strlen (person))
-       {
-         bzero (person, sizeof (person));
-         strcpy (person, usrname);
-       };
-
-      if (getuid () == 0)
-       {
-         do
-           {
-             bad = 0;
-             printf ("GID [%d]: ", DEFAULT_GROUP);
-             fflush (stdout);
-             safeget (foo, sizeof (foo));
-             if (!strlen (foo))
-               group = DEFAULT_GROUP;
-             else if (isdigit (*foo))
-               {
-                 group = atoi (foo);
-                 if (!(grp = getgrgid (group)))
-                   {
-                     printf ("unknown gid %s\n", foo);
-                     group = DEFAULT_GROUP;
-                     bad = 1;
-                   };
-               }
-             else if ((grp = getgrnam (foo)))
-               group = grp->gr_gid;
-             else
-               {
-                 printf ("unknown group %s\n", foo);
-                 group = DEFAULT_GROUP;
-                 bad = 1;
-               }
-             if (group == 0)
-               {               /* You're not allowed to make root group users! */
-                 printf ("Creation of root group users not allowed (must be done by hand)\n");
-                 group = DEFAULT_GROUP;
-                 bad = 1;
-               };
-           }
-         while (bad);
-       }
-      else
-       {
-         printf ("Group will be default of: %d\n", DEFAULT_GROUP);
-         group = DEFAULT_GROUP;
-       }
-
-      if (getuid () == 0)
-       {
-         printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
-         printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
-         fflush (stdout);
-         safeget (dir, sizeof (dir));
-         if (!strlen(dir))  /* hit return */
-           sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
-         else if (dir[strlen (dir) - 1] == '/')
-           strcat(dir, usrname);
-       }
-      else
-       {
-         printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
-         sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
-       }
-
-      printf ("\nShell [%s]: ", DEFAULT_SHELL);
-      fflush (stdout);
-      safeget (shell, sizeof (shell));
-      if (!strlen (shell))
-       strcpy(shell, DEFAULT_SHELL);
-      else
-       {
-         char *sh;
-         int ok = 0;
-
-         setusershell ();
-         while ((sh = getusershell ()) != NULL)
-           if (streq(shell, sh))
-             ok = 1;
-         endusershell ();
-
-         if (!ok)
-           {
-             if (getuid () == 0)
-               printf ("Warning: root allowed non standard shell\n");
-             else
-               {
-                 printf ("Shell NOT in /etc/shells, DEFAULT used\n");
-                 strcpy(shell, DEFAULT_SHELL);
-               }
-           }
-       }
-
-#ifdef EXPIRE_VALS_SET
-      if (getuid () == 0)
-       {
-#endif
-         printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
-         fflush (stdout);
-         safeget (foo, sizeof (foo));
-         if (strlen (foo) > 1)
-           min_pass = DEFAULT_MIN_PASS;
-         else
-           min_pass = atoi (foo);
-
-         printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
-         fflush (stdout);
-         safeget (foo, sizeof (foo));
-         if (strlen (foo) > 1)
-           max_pass = atoi (foo);
-         else
-           max_pass = DEFAULT_MAX_PASS;
-
-         printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
-         fflush (stdout);
-         safeget (foo, sizeof (foo));
-         warn_pass = atoi (foo);
-         if (warn_pass == 0)
-
-           warn_pass = DEFAULT_WARN_PASS;
-
-         printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
-         fflush (stdout);
-         safeget (foo, sizeof (foo));
-         user_die = atoi (foo);
-         if (user_die == 0)
-           user_die = DEFAULT_USER_DIE;
-
-#ifdef EXPIRE_VALS_SET
-       }
-      else
-       {
-         printf ("\nSorry, account expiry values are set.\n");
-         user_die = DEFAULT_USER_DIE;
-         warn_pass = DEFAULT_WARN_PASS;
-         max_pass = DEFAULT_MAX_PASS;
-         min_pass = DEFAULT_MIN_PASS;
-       }
-#endif
-
-      printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
-      printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
-      printf ("GID: [%d]\n", group);
-      printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
-             min_pass, max_pass, warn_pass, user_die);
-      printf ("\nIs this correct? [y/N]: ");
-      fflush (stdout);
-      safeget (foo, sizeof (foo));
-
-      done = bad = correct = strcaseprefix(foo, "y");
-
-      if (bad != 1)
-       printf ("\nUser [%s] not added\n", usrname);
-    }
-
-  /* Clobber the environment, I run this suid root sometimes to let 
-   * non root privileged accounts add users --chris */
-
-  *environ = NULL;
-
-  bzero (cmd, sizeof (cmd));
-  sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
-          USERADD_PATH, group, dir, shell, person, usrname);
-  printf ("Calling useradd to add new user:\n%s\n", cmd);
-  if (system (cmd))
-    {
-      printf ("User add failed!\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "could not add new user\n");
-      closelog ();
-#endif
-      exit (errno);
-    };
-
-  olduid = getuid ();  /* chage, passwd, edquota etc. require ruid = root
-                        */
-  setuid (0);
-
-  bzero (cmd, sizeof (cmd));
-
-  /* Chage runs suid root. => we need ruid root to run it with
-   * anything other than chage -l
-   */
-
-  sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
-          min_pass, max_pass, warn_pass, user_die, usrname);
-  printf ("%s\n", cmd);
-  if (system (cmd))
-    {
-      printf ("There was an error setting password expire values\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "password expire values could not be set\n");
-#endif
-    };
-
-  /* I want to add a user completely with one easy command --chris */
-
-#ifdef HAVE_QUOTAS
-  bzero (cmd, sizeof (cmd));
-  sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
-  printf ("%s\n", cmd);
-  if (system (cmd))
-    {
-      printf ("\nWarning: error setting quota\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
-#endif /* LOGGING */
-    }
-  else
-    printf ("\nDefault quota set.\n");
-#endif /* HAVE_QUOTAS */
-
-  bzero (cmd, sizeof (cmd));
-  sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
-  if (system (cmd))
-    {
-      printf ("\nWarning: error setting password\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "warning: password set failed!\n");
-#endif
-    }
-#ifdef IMMEDIATE_CHANGE
-  bzero (cmd, sizeof (cmd));
-  sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
-  if (system (cmd))
-    {
-      printf ("\nWarning: error expiring password\n");
-#ifdef LOGGING
-      syslog (LOG_ERR, "warning: password expire failed!\n");
-#endif /* LOGGING */
-    }
-#endif /* IMMEDIATE_CHANGE */
-
-  setuid (olduid);
-
-#ifdef LOGGING
-  closelog ();
-#endif
-
-  printf ("\nDone.\n");
-}
-
-void 
-safeget (char *buf, int maxlen)
-{
-  int c, i = 0, bad = 0;
-  char *bstart = buf;
-  while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
-    {
-      bad = (!isalnum (c) && (c != '_') && (c != ' '));
-      *(buf++) = c;
-    }
-  stpcpy(buf, "");
-
-  if (bad)
-    {
-      printf ("\nString contained banned character. Please stick to alphanumerics.\n");
-      stpcpy(bstart, "");
-    }
-}
-
diff --git a/contrib/adduser.sh b/contrib/adduser.sh
deleted file mode 100755 (executable)
index 0efb27a..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/sh
-# adduser script for use with shadow passwords and useradd command.
-# by Hrvoje Dogan <hdogan@student.math.hr>, Dec 1995.
-
-echo -n "Login name for new user []:"
-read LOGIN
-if [ -z $LOGIN ]
-then echo "Come on, man, you can't leave the login field empty...";exit
-fi
-echo
-echo -n "User id for $LOGIN [ defaults to next available]:"
-read ID
-GUID="-u $ID"
-if [ -z $ID ] 
-then GUID=""
-fi
-
-echo
-echo -n "Initial group for $LOGIN [users]:"
-read GID
-GGID="-g $GID"
-if [ -z $GID ]
-then GGID=""
-fi
-
-echo
-echo -n "Additional groups for $LOGIN []:"
-read AGID
-GAGID="-G $AGID"
-if [ -z $AGID ]
-then GAGID=""
-fi
-
-echo
-echo -n "$LOGIN's home directory [/home/$LOGIN]:"
-read HME
-GHME="-d $HME"
-if [ -z $HME ]
-then GHME=""
-fi
-
-echo
-echo -n "$LOGIN's shell [/bin/bash]:"
-read SHL
-GSHL="-s $SHL"
-if [ -z $SHL ]
-then GSHL=""
-fi
-
-echo
-echo -n "$LOGIN's account expiry date (MM/DD/YY) []:"
-read EXP
-GEXP="-e $EXP"
-if [ -z $EXP ]
-then GEXP=""
-fi
-echo
-echo OK, I'm about to make a new account. Here's what you entered so far:
-echo New login name: $LOGIN
-if [ -z $GUID ] 
-then echo New UID: [Next available]
-else echo New UID: $UID
-fi
-if [ -z $GGID ]
-then echo Initial group: users
-else echo Initial group: $GID
-fi
-if [ -z $GAGID ]
-then echo Additional groups: [none]
-else echo Additional groups: $AGID
-fi
-if [ -z $GHME ]
-then echo Home directory: /home/$LOGIN
-else echo Home directory: $HME
-fi
-if [ -z $GSHL ]
-then echo Shell: /bin/bash
-else echo Shell: $SHL
-fi
-if [ -z $GEXP ]
-then echo Expiry date: [no expiration]
-else echo Expiry date: $EXP
-fi
-echo "This is it... if you want to bail out, you'd better do it now."
-read FOO
-echo Making new account...
-/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN
-/usr/bin/chfn $LOGIN
-/usr/bin/passwd $LOGIN
-echo "Done..."
diff --git a/contrib/adduser2.sh b/contrib/adduser2.sh
deleted file mode 100755 (executable)
index 7656d02..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-#!/bin/bash
-#
-#  adduser                     Interactive user adding program.
-#
-#  Copyright (C) 1996          Petri Mattila, Prihateam Networks
-#                              petri@prihateam.fi
-#      
-#  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.
-#
-# Changes:
-#      220496  v0.01   Initial version
-#      230496  v0.02   More checks, embolden summary
-#      240496          Even more checks
-#      250496          Help with ?
-#      040596  v0.03   Cleanups
-#      050596  v0.04   Bug fixes, expire date checks
-#      070596  v0.05   Iso-latin-1 names
-#
-
-## Defaults
-
-# default groups
-def_group="users"
-def_other_groups=""
-
-# default home directory
-def_home_dir=/home/users
-
-# default shell
-def_shell=/bin/tcsh
-
-# Default expiration date (mm/dd/yy)
-def_expire=""
-
-# default dates
-def_pwd_min=0
-def_pwd_max=90
-def_pwd_warn=14
-def_pwd_iact=14
-
-
-# possible UIDs
-uid_low=1000
-uid_high=64000
-
-# skel directory
-skel=/etc/skel
-
-# default mode for home directory
-def_mode=711
-
-# Regex, that the login name must meet, only ANSI characters
-login_regex='^[0-9a-zA-Z_-]*$'
-
-# Regex, that the user name must meet
-# ANSI version
-##name_regex='^[0-9a-zA-Z_-\ ]*$'
-# ISO-LATIN-1 version
-name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$'
-
-# set PATH
-export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
-
-# Some special characters
-case "$TERM" in
-   vt*|ansi*|con*|xterm*|linux*)
-       S='\e[1m'        # start embolden
-       E='\e[m' # end embolden
-       ;;
-   *)  
-       S=''
-       E=''
-       ;;
-esac
-
-
-## Functions
-
-check_root() {
-       if test "$EUID" -ne 0
-       then
-               echo "You must be root to run this program."
-               exit 1
-       fi
-}
-
-check_user() {
-       local usr pwd uid gid name home sh
-
-       cat /etc/passwd | (
-               while IFS=":" read usr pwd uid gid name home sh
-               do
-                       if test "$1" = "${usr}"
-                       then
-                               return 1
-                       fi
-               done
-               return 0
-       )
-}
-
-check_group() {
-       local read grp pwd gid members
-
-       cat /etc/group | (
-               while IFS=":" read grp pwd gid members
-               do
-                       if test "$1" = "${grp}"
-                       then
-                               return 1
-                       fi
-               done
-               return 0
-       )
-}
-
-check_other_groups() {
-       local grp check IFS
-
-       check="$1"
-       IFS=","
-
-       set ${check}
-       for grp
-       do
-               if check_group "${grp}"
-               then
-                       echo "Group ${grp} does not exist."
-                       return 1
-               fi
-       done
-       return 0
-}              
-
-check_uid() {
-       local usr pwd uid gid name home sh
-       
-       cat /etc/passwd | (
-               while IFS=":" read usr pwd uid gid name home sh
-               do
-                       if test "$1" = "${uid}"
-                       then
-                               return 1
-                       fi
-               done
-               return 0
-       )
-}
-
-read_yn() {
-       local ans ynd
-       
-       ynd="$1"
-       
-       while :
-       do
-               read ans        
-               case "${ans}" in
-                     "") return ${ynd} ;;
-                   [nN]) return 1 ;;
-                   [yY]) return 0 ;;
-                      *) echo -n "Y or N, please ? " ;;
-               esac
-       done
-}
-
-read_login() {
-       echo
-       while :
-       do
-               echo -n "Login: ${def_login:+[${def_login}] }"
-               read login
-               
-               if test "${login}" = '?'
-               then
-                       less /etc/passwd
-                       echo
-                       continue
-               fi
-
-               if test -z "${login}" -a -n "${def_login}"
-               then
-                       login="${def_login}"
-                       echo "Using ${login}"
-                       return
-               fi
-               
-               if test "${#login}" -gt 8
-               then
-                       echo "Login must be at most 8 characters long"
-                       continue
-               fi
-               
-               if test "${#login}" -lt 2
-               then
-                       echo "Login must be at least 2 characters long"
-                       continue
-               fi
-               
-               if ! expr "${login}" : "${login_regex}" &> /dev/null
-               then
-                       echo "Please use letters, numbers and special characters _-,."
-                       continue
-               fi
-               
-               if ! check_user "${login}"
-               then
-                       echo "Username ${login} is already in use"
-                       continue
-               fi
-               
-               def_login="${login}"
-               return
-       done
-}
-
-read_name () {
-       echo
-       while :
-       do
-               echo -n "Real name: ${def_name:+[${def_name}] }"
-               read name
-               
-               if test "${name}" = '?'
-               then
-                       less /etc/passwd
-                       echo
-                       continue
-               fi
-
-               if test -z "${name}" -a -n "${def_name}"
-               then
-                       name="${def_name}"
-                       echo "Using ${name}"
-               fi
-
-               if test "${#name}" -gt 32
-               then
-                       echo "Name should be at most 32 characters long"
-                       continue
-               fi
-
-               if ! expr "${name}" : "${name_regex}" &> /dev/null
-               then
-                       echo "Please use letters, numbers, spaces and special characters ,._-"
-                       continue
-               fi
-               
-               def_name="${name}"
-               return
-       done
-}
-
-read_home() {
-       local x
-       
-       echo
-       while :
-       do
-               echo -n "Home Directory: [${def_home_dir}/${login}] "
-               read home
-               
-               if test -z "${home}"
-               then
-                       home="${def_home_dir}/${login}"
-                       echo "Using ${home}"
-               fi
-               
-               if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null
-               then
-                       echo "Please use letters, numbers, spaces and special characters ,._-/"
-                       continue
-               fi
-               
-               x="$(basename ${home})"
-               if test "${x}" != "${login}"
-               then
-                       echo "Warning: you are about to use different login name and home directory."
-               fi
-               
-               x="$(dirname ${home})"
-               if ! test -d "${x}"
-               then
-                       echo "Directory ${x} does not exist."
-                       echo "If you still want to use it, please make it manually."
-                       continue
-               fi
-               
-               def_home_dir="${x}"
-               return
-       done
-}
-
-read_shell () {
-       local x
-
-       echo
-       while :
-       do
-               echo -n "Shell: [${def_shell}] "
-               read shell
-               
-               if test -z "${shell}"
-               then
-                       shell="${def_shell}"
-                       echo "Using ${shell}"
-               fi
-               
-               for x in $(cat /etc/shells)
-               do
-                       if test "${x}" = "${shell}"
-                       then
-                               def_shell="${shell}"
-                               return
-                       fi
-               done
-
-               echo "Possible shells are:"
-               cat /etc/shells
-       done
-}
-
-read_group () {
-       echo
-       while :
-       do
-               echo -n "Group: [${def_group}] "
-               read group
-               
-               if test -z "${group}"
-               then
-                       group="${def_group}"
-                       echo "Using ${group}"
-               fi
-               
-               if test "${group}" = '?'
-               then
-                       less /etc/group
-                       echo
-                       continue
-               fi
-
-               if check_group "${group}"
-               then
-                       echo "Group ${group} does not exist."
-                       continue
-               fi
-               
-               def_group="${group}"
-               return
-       done
-}
-
-read_other_groups () {
-       echo
-       while :
-       do
-               echo -n "Other groups: [${def_og:-none}] "
-               read other_groups
-               
-               if test "${other_groups}" = '?'
-               then
-                       less /etc/group
-                       echo
-                       continue
-               fi
-
-               if test -z "${other_groups}"
-               then
-                       if test -n "${def_og}"
-                       then
-                               other_groups="${def_og}"
-                               echo "Using ${other_groups}"
-                       else    
-                               echo "No other groups"
-                               return
-                       fi
-               fi
-               
-               
-               if ! check_other_groups "${other_groups}"
-               then
-                       continue
-               fi
-               
-               def_og="${other_groups}"
-               return
-       done
-}
-
-read_uid () {
-       echo
-       while :
-       do
-               echo -n "uid: [first free] "
-               read uid
-                       
-               if test -z "${uid}"
-               then
-                       echo "Using first free UID."
-                       return
-               fi
-               
-               if test "${uid}" = '?'
-               then
-                       less /etc/passwd
-                       echo
-                       continue
-               fi
-
-               if ! expr "${uid}" : '^[0-9]+$' &> /dev/null
-               then
-                       echo "Please use numbers only."
-                       continue
-               fi
-               if test "${uid}" -lt "${uid_low}"
-               then
-                       echo "UID must be greater than ${uid_low}"
-                       continue
-               fi
-               if test "${uid}" -gt "${uid_high}"
-               then
-                       echo "UID must be smaller than ${uid_high}"
-                       continue
-               fi
-               if ! check_uid "${uid}"
-               then
-                       echo "UID ${uid} is already in use"
-                       continue
-               fi
-               
-               return
-       done
-}
-
-read_max_valid_days() {
-       echo
-       while :
-       do
-               echo -en "Maximum days between password changes: [${def_pwd_max}] "
-               read max_days
-               
-               if test -z "${max_days}"
-               then
-                       max_days="${def_pwd_max}"
-                       echo "Using ${max_days}"
-                       return
-               fi
-               
-               if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null
-               then
-                       echo "Please use numbers only."
-                       continue
-               fi
-               if test "${max_days}" -lt 7
-               then
-                       echo "Warning: you are using a value shorter than a week."
-               fi
-               
-               def_pwd_max="${max_days}"
-               return  
-       done
-}
-
-read_min_valid_days() {
-       echo
-       while :
-       do
-               echo -en "Minimum days between password changes: [${def_pwd_min}] "
-               read min_days
-               
-               if test -z "${min_days}"
-               then
-                       min_days="${def_pwd_min}"
-                       echo "Using ${min_days}"
-                       return
-               fi
-               
-               if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null
-               then
-                       echo "Please use numbers only."
-                       continue
-               fi
-               if test "${min_days}" -gt 7
-               then
-                       echo "Warning: you are using a value longer than a week."
-               fi
-               
-               def_pwd_min="${min_days}"
-               return  
-       done
-}
-
-read_warning_days() {
-       echo
-       while :
-       do
-               echo -en "Number of warning days before password expires: [${def_pwd_warn}] "
-               read warn_days
-               
-               if test -z "${warn_days}"
-               then
-                       warn_days="${def_pwd_warn}"
-                       echo "Using ${warn_days}"
-               fi
-
-               if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null
-               then
-                       echo "Please use numbers only."
-                       continue
-               fi
-               if test "${warn_days}" -gt 14
-               then
-                       echo "Warning: you are using a value longer than two week."
-               fi
-               
-               def_pwd_warn="${warn_days}"
-               return  
-       done
-}
-
-
-read_inactive_days() {
-       echo
-       while :
-       do
-               echo -en "Number of usable days after expiration: [${def_pwd_iact}] "
-               read iact_days
-               
-               if test -z "${iact_days}"
-               then
-                       iact_days="${def_pwd_iact}"
-                       echo "Using ${iact_days}"
-                       return
-               fi
-               if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null
-               then
-                       echo "Please use numbers only."
-                       continue
-               fi
-               if test "${iact_days}" -gt 14
-               then
-                       echo "Warning: you are using a value that is more than two weeks."
-               fi
-               
-               def_pwd_iact="${iact_days}"
-               return  
-       done
-}
-
-read_expire_date() {
-       local ans
-       
-       echo
-       while :
-       do
-               echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] "
-               read ans
-               
-               if test -z "${ans}"
-               then
-                       if test -z "${def_expire}"
-                       then
-                               ans="never"
-                       else
-                               ans="${def_expire}"
-                               echo "Using ${def_expire}"
-                       fi
-               fi
-               
-               if test "${ans}" = "never"
-               then
-                       echo "Account will never expire."
-                       def_expire=""
-                       expire=""
-                       return
-               fi
-
-               if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null
-               then
-                       echo "Please use format mm/dd/yy"
-                       continue
-               fi
-               
-               if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')"
-               then
-                       continue
-               fi
-               
-               def_expire="${expire}"
-               return  
-       done
-}
-
-read_passwd_yn() {
-       echo -en "\nDo you want to set password [Y/n] ? "
-       if read_yn 0
-       then
-               set_pwd="YES"
-       else
-               set_pwd=""
-       fi
-}
-
-
-print_values() {
-
-clear
-cat << EOM
-
-Login:        ${S}${login}${E}
-Group:        ${S}${group}${E}
-Other groups: ${S}${other_groups:-[none]}${E}
-
-Real Name:    ${S}${name}${E}
-
-uid:          ${S}${uid:-[first free]}${E}
-home:         ${S}${home}${E}
-shell:        ${S}${shell}${E}
-
-Account expiration date:                   ${S}${expire_date:-never}${E}
-Minimum days between password changes:     ${S}${min_days}${E}
-Maximum days between password changes:     ${S}${max_days}${E}
-Number of usable days after expiration:    ${S}${iact_days}${E}
-Number of warning days before expiration:  ${S}${warn_days}${E}
-
-${S}${set_pwd:+Set password for this account.}${E}
-
-EOM
-}
-
-set_user() {
-       if ! useradd \
-               -c "${name}" \
-               -d "${home}" \
-               -g "${group}" \
-               -s "${shell}" \
-               ${expire:+-e ${expire}} \
-               ${uid:+-u ${uid}} \
-               ${other_groups:+-G ${other_groups}} \
-               ${login}
-       then
-               echo "Error ($?) in useradd...exiting..."
-               exit 1
-       fi
-}
-
-set_aging() {
-       if ! passwd \
-               -x ${max_days} \
-               -n ${min_days} \
-               -w ${warn_days} \
-               -i ${iact_days} \
-               ${login}
-       then
-               echo "Error ($?) in setting password aging...exiting..." 
-               exit 1
-       fi
-}
-
-set_password() {
-       if test -n "${set_pwd}"
-       then
-               echo
-               passwd ${login}
-               echo
-       fi
-}      
-
-set_system() {
-       if test -d "${home}"
-       then
-               echo "Directory ${home} already exists."
-               echo "Skeleton files not copied."
-               return
-       fi
-       
-       echo -n "Copying skeleton files..."
-       ( 
-         mkdir ${home}
-         cd ${skel} && cp -af . ${home}
-         chmod ${def_mode} ${home}
-         chown -R ${login}:${group} ${home}
-       )
-       echo "done."
-
-       ## Add your own stuff here:
-       echo -n "Setting up other files..."
-       (
-         mailbox="/var/spool/mail/${login}"
-         touch ${mailbox}
-         chown "${login}:mail" ${mailbox}
-         chmod 600 ${mailbox}
-       )
-       echo "done."
-}
-
-
-read_values() {
-       clear
-       echo -e "\nPlease answer the following questions about the new user to be added."
-       
-       while :
-       do
-               read_login
-               read_name
-               read_group
-               read_other_groups
-               read_home
-               read_shell
-               read_uid
-               read_expire_date
-               read_max_valid_days
-               read_min_valid_days
-               read_warning_days
-               read_inactive_days
-               read_passwd_yn
-
-               print_values
-               
-               echo -n "Is this correct [N/y] ? "
-               read_yn 1 && return
-       done
-}
-
-
-main() {
-       check_root
-       read_values
-       set_user
-       set_aging
-       set_system
-       set_password
-}
-
-
-## Run it 8-)
-main
-
-# End.