diff options
Diffstat (limited to 'libmisc/isexpired.c')
-rw-r--r-- | libmisc/isexpired.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/libmisc/isexpired.c b/libmisc/isexpired.c new file mode 100644 index 0000000..ff20396 --- /dev/null +++ b/libmisc/isexpired.c @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh + * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz + * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko + * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Extracted from age.c and made part of libshadow.a - may be useful + * in other shadow-aware programs. --marekm + */ + +#include <config.h> + +#include <sys/types.h> +#include "prototypes.h" +#include "defines.h" +#include <pwd.h> +#include <time.h> + +#ident "$Id$" + + +/* + * isexpired - determine if account is expired yet + * + * isexpired calculates the expiration date based on the + * password expiration criteria. + * + * Return value: + * 0: The password is still valid + * 1: The password has expired, it must be changed + * 2: The password has expired since a long time and the account is + * now disabled. (password cannot be changed) + * 3: The account has expired + */ +int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp) +{ + long now; + + now = (long) time ((time_t *) 0) / SCALE; + + if (NULL == sp) { + return 0; + } + + /* + * Quick and easy - there is an expired account field + * along with an inactive account field. Do the expired + * one first since it is worse. + */ + + if ((sp->sp_expire > 0) && (now >= sp->sp_expire)) { + return 3; + } + + /* + * Last changed date 1970-01-01 (not very likely) means that + * the password must be changed on next login (passwd -e). + * + * The check for "x" is a workaround for RedHat NYS libc bug - + * if /etc/shadow doesn't exist, getspnam() still succeeds and + * returns sp_lstchg==0 (must change password) instead of -1! + */ + if ( (0 == sp->sp_lstchg) + && (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)) { + return 1; + } + + if ( (sp->sp_lstchg > 0) + && (sp->sp_max >= 0) + && (sp->sp_inact >= 0) + && (now >= (sp->sp_lstchg + sp->sp_max + sp->sp_inact))) { + return 2; + } + + /* + * The last and max fields must be present for an account + * to have an expired password. A maximum of >10000 days + * is considered to be infinite. + */ + + if ( (-1 == sp->sp_lstchg) + || (-1 == sp->sp_max) + || (sp->sp_max >= ((10000L * DAY) / SCALE))) { + return 0; + } + + /* + * Calculate today's day and the day on which the password + * is going to expire. If that date has already passed, + * the password has expired. + */ + + if (now >= (sp->sp_lstchg + sp->sp_max)) { + return 1; + } + return 0; +} + |