Subject: Re: Password Expiration Change
To: Dave Burgess <burgess@s069.netins.net>
From: Simon J. Gerraty <sjg@zen.void.oz.au>
List: current-users
Date: 04/03/1995 11:42:22
> > I noticed too that su(1) does not support change or expire.  The
> > change warning at least should be there as many folk don't allow root
> > logins so no ageing would be enforced.
> > 
> 
> I don't allow root to password age, for two reasons.  One - if you are
> root, you deserve whatever you get if you don't regulary change the root

I quite agree.  I don't use ageing for system accounts either.
But I think the facility should be there...

Now for the embarrasing bit - all the sums in the patches I posted
were out by an order of 7 :-) - I fogot to remove the DAYSPERWEEK
multiplyer!

Here is an amended set.

#!/bin/sh
# This is a shell archive.
# remove everything above the "#!/bin/sh" line
# and feed to /bin/sh
# Use -c option to overwrite existing files
#
# Contents: 
#	login.age2.diff
#	passwd.age2.diff
#	su.age2.diff
#
# packed by: <sjg@zen.void.oz.au> on Mon Apr  3 10:56:57 EST 1995
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f login.age2.diff -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"login.age2.diff\"
else
  echo shar: Extracting \"login.age2.diff\" \(    3678 characters\)
  sed 's/^X//' > login.age2.diff << '!EOF'
X*** login/login.c.orig	Fri Dec 23 22:27:17 1994
X***************
X*** 83,88 ****
X--- 83,89 ----
X  int	 rootterm __P((char *));
X  void	 sigint __P((int));
X  void	 sleepexit __P((int));
X+ void	do_chpass __P((void));
X  char	*stypeof __P((char *));
X  void	 timedout __P((int));
X  int	 pwcheck __P((char *, char *, char *, char *));
X***************
X*** 112,118 ****
X--- 113,129 ----
X  struct	passwd *pwd;
X  int	failures;
X  char	term[64], *envinit[1], *hostname, *username, *tty;
X+ #ifdef SKEY
X+ int	used_skey = 0;
X+ #endif
X  
X+ #ifndef IMEDIATE_CHANGE
X+ # define IMEDIATE_CHANGE 1
X+ #endif
X+ #ifndef WARN_DAYS
X+ # define WARN_DAYS 14
X+ #endif
X+ 
X  int
X  main(argc, argv)
X  	int argc;
X***************
X*** 128,133 ****
X--- 139,145 ----
X  	char *domain, *p, *salt, *ttyn;
X  	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
X  	char localhost[MAXHOSTNAMELEN];
X+ 	int need_chpass = 0;
X  	
X  	(void)signal(SIGALRM, timedout);
X  	(void)alarm(timeout);
X***************
X*** 349,359 ****
X  	if (pwd->pw_change || pwd->pw_expire)
X  		(void)gettimeofday(&tp, (struct timezone *)NULL);
X  	if (pwd->pw_change)
X! 		if (tp.tv_sec >= pwd->pw_change) {
X  			(void)printf("Sorry -- your password has expired.\n");
X  			sleepexit(1);
X  		} else if (pwd->pw_change - tp.tv_sec <
X! 		    2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
X  			(void)printf("Warning: your password expires on %s",
X  			    ctime(&pwd->pw_change));
X  	if (pwd->pw_expire)
X--- 361,373 ----
X  	if (pwd->pw_change || pwd->pw_expire)
X  		(void)gettimeofday(&tp, (struct timezone *)NULL);
X  	if (pwd->pw_change)
X! 		if (pwd->pw_change == IMEDIATE_CHANGE) {
X! 			need_chpass = 1;
X! 		} else if (tp.tv_sec >= pwd->pw_change) {
X  			(void)printf("Sorry -- your password has expired.\n");
X  			sleepexit(1);
X  		} else if (pwd->pw_change - tp.tv_sec <
X! 		    WARN_DAYS * SECSPERDAY && !quietlog)
X  			(void)printf("Warning: your password expires on %s",
X  			    ctime(&pwd->pw_change));
X  	if (pwd->pw_expire)
X***************
X*** 361,367 ****
X  			(void)printf("Sorry -- your account has expired.\n");
X  			sleepexit(1);
X  		} else if (pwd->pw_expire - tp.tv_sec <
X! 		    2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
X  			(void)printf("Warning: your account expires on %s",
X  			    ctime(&pwd->pw_expire));
X  
X--- 375,381 ----
X  			(void)printf("Sorry -- your account has expired.\n");
X  			sleepexit(1);
X  		} else if (pwd->pw_expire - tp.tv_sec <
X! 		    WARN_DAYS * SECSPERDAY && !quietlog)
X  			(void)printf("Warning: your account expires on %s",
X  			    ctime(&pwd->pw_expire));
X  
X***************
X*** 457,462 ****
X--- 471,480 ----
X  	else
X  		(void) setuid(pwd->pw_uid);
X  
X+ 	/* wait until we are un-privileged */
X+ 	if (need_chpass)
X+ 		do_chpass();
X+ 	
X  	execlp(pwd->pw_shell, tbuf, 0);
X  	err(1, "%s", pwd->pw_shell);
X  }
X***************
X*** 471,477 ****
X  			fprintf(stderr, "You have no s/key. ");
X  			return 1;
X  		} else {
X! 			return skey_authenticate(user);
X  		}
X  	}
X  #endif
X--- 489,499 ----
X  			fprintf(stderr, "You have no s/key. ");
X  			return 1;
X  		} else {
X! 			int ret = skey_authenticate(user);
X! 
X! 			if (ret == 0)
X! 				used_skey = 1;
X! 			return ret;
X  		}
X  	}
X  #endif
X***************
X*** 675,678 ****
X--- 697,718 ----
X  {
X  	(void)sleep(5);
X  	exit(eval);
X+ }
X+ 
X+ void
X+ do_chpass()
X+ {
X+ #ifdef SKEY
X+ 	/*
X+ 	 * if user logged on using skey, don't make them
X+ 	 * type a password in...
X+ 	 */
X+ 	if (used_skey) {
X+ 		(void)printf("Warning: your password has expired, change it as soon as possible.\n");
X+ 		return;
X+ 	}
X+ #endif
X+ 	(void)printf("Your password has expired, chose a new one.\n");
X+ 	if (system("passwd") != 0)
X+ 		sleepexit(1);
X  }
!EOF
  if test     3678 -ne `wc -c < login.age2.diff`; then
    echo shar: \"login.age2.diff\" unpacked with wrong size!
  fi
  
fi
if test -f passwd.age2.diff -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"passwd.age2.diff\"
else
  echo shar: Extracting \"passwd.age2.diff\" \(    1232 characters\)
  sed 's/^X//' > passwd.age2.diff << '!EOF'
X*** passwd/local_passwd.c.orig	Sun Dec 25 22:29:16 1994
X***************
X*** 42,47 ****
X--- 42,61 ----
X  #include <stdio.h>
X  #include <string.h>
X  
X+ #ifdef  PASSWD_CHANGE
X+ # undef PASSWD_CHANGE
X+ # include <time.h>
X+ # include <tzfile.h>
X+ 
X+ # ifndef CHPASS_DAYS
X+ #   define CHPASS_DAYS 180			/* 6 months */
X+ # endif
X+ 
X+ # define PASSWD_CHANGE  (CHPASS_DAYS * SECSPERDAY) + time((time_t *)NULL) 
X+ #else
X+ # define PASSWD_CHANGE 0
X+ #endif
X+   
X  uid_t uid;
X  
X  char *progname = "passwd";
X***************
X*** 74,85 ****
X  	tfd = pw_tmp();
X  
X  	/*
X! 	 * Get the new password.  Reset passwd change time to zero; when
X  	 * classes are implemented, go and get the "offset" value for this
X  	 * class and reset the timer.
X  	 */
X  	pw->pw_passwd = getnewpasswd(pw);
X! 	pw->pw_change = 0;
X  	pw_copy(pfd, tfd, pw);
X  
X  	if (!pw_mkdb())
X--- 88,99 ----
X  	tfd = pw_tmp();
X  
X  	/*
X! 	 * Get the new password.  Set passwd change time to default; when
X  	 * classes are implemented, go and get the "offset" value for this
X  	 * class and reset the timer.
X  	 */
X  	pw->pw_passwd = getnewpasswd(pw);
X! 	pw->pw_change = PASSWD_CHANGE;
X  	pw_copy(pfd, tfd, pw);
X  
X  	if (!pw_mkdb())
!EOF
  if test     1232 -ne `wc -c < passwd.age2.diff`; then
    echo shar: \"passwd.age2.diff\" unpacked with wrong size!
  fi
  
fi
if test -f su.age2.diff -a x$1 != x-c ; then
  echo shar: Will not over-write existing file \"su.age2.diff\"
else
  echo shar: Extracting \"su.age2.diff\" \(    1754 characters\)
  sed 's/^X//' > su.age2.diff << '!EOF'
X*** su/su.c.orig	Wed May 25 22:46:15 1994
X***************
X*** 51,56 ****
X--- 51,57 ----
X  #include <pwd.h>
X  #include <grp.h>
X  #include <string.h>
X+ #include <tzfile.h>
X  #include <unistd.h>
X  #include <paths.h>
X  
X***************
X*** 66,71 ****
X--- 67,76 ----
X  #define	ARGSTR	"-flm"
X  #endif
X  
X+ #ifndef WARN_DAYS
X+ # define WARN_DAYS 14				/* give 1 week warning */
X+ #endif
X+ 
X  extern char *crypt();
X  int chshell();
X  
X***************
X*** 79,84 ****
X--- 84,90 ----
X  	register struct passwd *pwd;
X  	register char *p, **g;
X  	struct group *gr;
X+ 	struct timeval tp;
X  	uid_t ruid, getuid();
X  	int asme, ch, asthem, fastlogin, prio;
X  	enum { UNSET, YES, NO } iscsh = UNSET;
X***************
X*** 269,274 ****
X--- 275,307 ----
X  	}
X  			
X  	*np = avshell;
X+ 
X+ 	if (pwd->pw_change || pwd->pw_expire)
X+ 		(void)gettimeofday(&tp, (struct timezone *)NULL);
X+ 	if (pwd->pw_change)
X+ 		if (tp.tv_sec >= pwd->pw_change) {
X+ 			(void)printf("%s -- %s's password has expired.\n",
X+ 				     (ruid ? "Sorry" : "Note"),
X+ 				     user);
X+ 			if (ruid != 0)
X+ 				exit(1);
X+ 		} else if (pwd->pw_change - tp.tv_sec <
X+ 			   WARN_DAYS * SECSPERDAY)
X+ 			(void)printf("Warning: %s's password expires on %s",
X+ 				     user,
X+ 				     ctime(&pwd->pw_change));
X+ 	if (pwd->pw_expire)
X+ 		if (tp.tv_sec >= pwd->pw_expire) {
X+ 			(void)printf("%s -- %s's account has expired.\n",
X+ 				     (ruid ? "Sorry" : "Note"),
X+ 				     user);
X+ 			if (ruid != 0)
X+ 				exit(1);
X+ 		} else if (pwd->pw_expire - tp.tv_sec <
X+ 			   WARN_DAYS * SECSPERDAY)
X+ 			(void)printf("Warning: %s's account expires on %s",
X+ 				     user,
X+ 				     ctime(&pwd->pw_expire));
X  
X  	if (ruid != 0)
X  		syslog(LOG_NOTICE|LOG_AUTH, "%s to %s%s",
!EOF
  if test     1754 -ne `wc -c < su.age2.diff`; then
    echo shar: \"su.age2.diff\" unpacked with wrong size!
  fi
  
fi
exit 0