$NetBSD$

--- modules/pam_unix/pam_unix_acct.c.orig	Wed Dec 20 00:15:05 2000
+++ modules/pam_unix/pam_unix_acct.c
@@ -43,7 +43,9 @@
 #include <sys/types.h>
 #include <syslog.h>
 #include <pwd.h>
+#ifdef HAVE_SHADOW_H
 #include <shadow.h>
+#endif
 #include <time.h>		/* for time() */
 
 #include <security/_pam_macros.h>
@@ -71,8 +73,10 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 	unsigned int ctrl;
 	const char *uname;
 	int retval, daysleft;
-	time_t curdays;
+	time_t now, curdays;
+#ifdef HAVE_GETSPNAM
 	struct spwd *spent;
+#endif
 	struct passwd *pwent;
 	char buf[80];
 
@@ -113,7 +117,9 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 					return PAM_CRED_INSUFFICIENT;
 			}
 		}
+#ifdef HAVE_GETSPNAM
 		spent = getspnam( uname );
+#endif
 		if (save_uid == pwent->pw_uid)
 			setreuid( save_uid, save_euid );
 		else {
@@ -123,15 +129,21 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 		}
 
 	} else if (!strcmp( pwent->pw_passwd, "x" )) {
+#ifdef HAVE_GETSPNAM
 		spent = getspnam(uname);
+#endif
 	} else {
 		return PAM_SUCCESS;
 	}
 
+#ifdef HAVE_GETSPNAM
 	if (!spent)
 		return PAM_AUTHINFO_UNAVAIL;	/* Couldn't get username from shadow */
+#endif
 
-	curdays = time(NULL) / (60 * 60 * 24);
+	now = time(NULL);
+	curdays = now / (60 * 60 * 24);
+#ifdef HAVE_GETSPNAM
 	D(("today is %d, last change %d", curdays, spent->sp_lstchg));
 	if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)
 	    && (spent->sp_lstchg != 0)) {
@@ -143,6 +155,29 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 		D(("account expired"));
 		return PAM_ACCT_EXPIRED;
 	}
+#else
+	if ((now > pwent->pw_expire) && (pwent->pw_expire != 0)) {
+		_log_err(LOG_NOTICE, pamh
+			 ,"account %s has expired (account expired)"
+			 ,uname);
+		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
+			    "Your account has expired; please contact your system administrator");
+		D(("account expired"));
+		return PAM_ACCT_EXPIRED;
+	}
+	if ((now + _PASSWORD_WARNDAYS * 60 * 60 * 24 > pwent->pw_expire)
+	    && (pwent->pw_expire != 0)) {
+		daysleft = (pwent->pw_expire - now) / (60 * 60 * 24);
+		_log_err(LOG_DEBUG, pamh
+			 ,"account for user %s will expire in %d days"
+			 ,uname, daysleft);
+		snprintf(buf, 80, "Warning: your account will expire in %d day%.2s",
+			 daysleft, daysleft == 1 ? "" : "s");
+		_make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
+	}
+#endif
+
+#ifdef HAVE_GETSPNAM
 	if ((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
 	    && (spent->sp_max != -1) && (spent->sp_inact != -1)
 	    && (spent->sp_lstchg != 0)) {
@@ -154,7 +189,9 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 		D(("account expired 2"));
 		return PAM_ACCT_EXPIRED;
 	}
+#endif
 	D(("when was the last change"));
+#ifdef HAVE_GETSPNAM
 	if (spent->sp_lstchg == 0) {
 		_log_err(LOG_NOTICE, pamh
 			 ,"expired password for user %s (root enforced)"
@@ -173,6 +210,19 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 		D(("need a new password 2"));
 		return PAM_NEW_AUTHTOK_REQD;
 	}
+#else
+	if (pwent->pw_change == -1) {
+		_log_err(LOG_NOTICE, pamh
+			 ,"expired password for user %s (root enforced)"
+			 ,uname);
+		_make_remark(pamh, ctrl, PAM_ERROR_MSG,
+			    "You are required to change your password immediately (root enforced)");
+		D(("need a new password"));
+		return PAM_NEW_AUTHTOK_REQD;
+	}
+#endif
+
+#ifdef HAVE_GETSPNAM
 	if ((curdays > (spent->sp_lstchg + spent->sp_max - spent->sp_warn))
 	    && (spent->sp_max != -1) && (spent->sp_warn != -1)) {
 		daysleft = (spent->sp_lstchg + spent->sp_max) - curdays;
@@ -183,6 +233,21 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_hand
 			 daysleft, daysleft == 1 ? "" : "s");
 		_make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
 	}
+#else
+#ifndef _PASSWORD_WARNDAYS
+#define _PASSWORD_WARNDAYS 14
+#endif
+	if ((now + _PASSWORD_WARNDAYS * 60 * 60 * 24 > pwent->pw_change)
+	    && (pwent->pw_change != 0) && (pwent->pw_change != -1)) {
+		daysleft = (pwent->pw_change - now) / (60 * 60 * 24);
+		_log_err(LOG_DEBUG, pamh
+			 ,"password for user %s will expire in %d days"
+			 ,uname, daysleft);
+		snprintf(buf, 80, "Warning: your password will expire in %d day%.2s",
+			 daysleft, daysleft == 1 ? "" : "s");
+		_make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
+	}
+#endif
 
 	D(("all done"));
 
