1126274Sdes/* 2126274Sdes * Copyright (c) 2004 Darren Tucker. All rights reserved. 3126274Sdes * 4126274Sdes * Redistribution and use in source and binary forms, with or without 5126274Sdes * modification, are permitted provided that the following conditions 6126274Sdes * are met: 7126274Sdes * 1. Redistributions of source code must retain the above copyright 8126274Sdes * notice, this list of conditions and the following disclaimer. 9126274Sdes * 2. Redistributions in binary form must reproduce the above copyright 10126274Sdes * notice, this list of conditions and the following disclaimer in the 11126274Sdes * documentation and/or other materials provided with the distribution. 12126274Sdes * 13126274Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14126274Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15126274Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16126274Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17126274Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18126274Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19126274Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20126274Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21126274Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22126274Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23126274Sdes */ 24126274Sdes 25126274Sdes#include "includes.h" 26126274Sdes 27126274Sdes#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) 28126274Sdes#include <shadow.h> 29162852Sdes#include <stdarg.h> 30162852Sdes#include <string.h> 31181111Sdes#include <time.h> 32126274Sdes 33162852Sdes#include "key.h" 34162852Sdes#include "hostfile.h" 35126274Sdes#include "auth.h" 36126274Sdes#include "buffer.h" 37126274Sdes#include "log.h" 38126274Sdes 39146998Sdes#ifdef DAY 40146998Sdes# undef DAY 41146998Sdes#endif 42126274Sdes#define DAY (24L * 60 * 60) /* 1 day in seconds */ 43126274Sdes 44126274Sdesextern Buffer loginmsg; 45126274Sdes 46126274Sdes/* 47126274Sdes * For the account and password expiration functions, we assume the expiry 48126274Sdes * occurs the day after the day specified. 49126274Sdes */ 50126274Sdes 51126274Sdes/* 52126274Sdes * Check if specified account is expired. Returns 1 if account is expired, 53126274Sdes * 0 otherwise. 54126274Sdes */ 55126274Sdesint 56126274Sdesauth_shadow_acctexpired(struct spwd *spw) 57126274Sdes{ 58126274Sdes time_t today; 59126274Sdes int daysleft; 60126274Sdes char buf[256]; 61126274Sdes 62126274Sdes today = time(NULL) / DAY; 63126274Sdes daysleft = spw->sp_expire - today; 64126274Sdes debug3("%s: today %d sp_expire %d days left %d", __func__, (int)today, 65126274Sdes (int)spw->sp_expire, daysleft); 66126274Sdes 67126274Sdes if (spw->sp_expire == -1) { 68126274Sdes debug3("account expiration disabled"); 69126274Sdes } else if (daysleft < 0) { 70126274Sdes logit("Account %.100s has expired", spw->sp_namp); 71126274Sdes return 1; 72126274Sdes } else if (daysleft <= spw->sp_warn) { 73126274Sdes debug3("account will expire in %d days", daysleft); 74126274Sdes snprintf(buf, sizeof(buf), 75126274Sdes "Your account will expire in %d day%s.\n", daysleft, 76126274Sdes daysleft == 1 ? "" : "s"); 77126274Sdes buffer_append(&loginmsg, buf, strlen(buf)); 78126274Sdes } 79126274Sdes 80126274Sdes return 0; 81126274Sdes} 82126274Sdes 83126274Sdes/* 84126274Sdes * Checks password expiry for platforms that use shadow passwd files. 85126274Sdes * Returns: 1 = password expired, 0 = password not expired 86126274Sdes */ 87126274Sdesint 88126274Sdesauth_shadow_pwexpired(Authctxt *ctxt) 89126274Sdes{ 90126274Sdes struct spwd *spw = NULL; 91126274Sdes const char *user = ctxt->pw->pw_name; 92126274Sdes char buf[256]; 93126274Sdes time_t today; 94126274Sdes int daysleft, disabled = 0; 95126274Sdes 96126274Sdes if ((spw = getspnam((char *)user)) == NULL) { 97126274Sdes error("Could not get shadow information for %.100s", user); 98126274Sdes return 0; 99126274Sdes } 100126274Sdes 101126274Sdes today = time(NULL) / DAY; 102126274Sdes debug3("%s: today %d sp_lstchg %d sp_max %d", __func__, (int)today, 103126274Sdes (int)spw->sp_lstchg, (int)spw->sp_max); 104126274Sdes 105126274Sdes#if defined(__hpux) && !defined(HAVE_SECUREWARE) 106126274Sdes if (iscomsec()) { 107126274Sdes struct pr_passwd *pr; 108149749Sdes 109126274Sdes pr = getprpwnam((char *)user); 110126274Sdes 111126274Sdes /* Test for Trusted Mode expiry disabled */ 112126274Sdes if (pr != NULL && pr->ufld.fd_min == 0 && 113126274Sdes pr->ufld.fd_lifetime == 0 && pr->ufld.fd_expire == 0 && 114126274Sdes pr->ufld.fd_pw_expire_warning == 0 && 115126274Sdes pr->ufld.fd_schange != 0) 116126274Sdes disabled = 1; 117126274Sdes } 118126274Sdes#endif 119126274Sdes 120126274Sdes /* TODO: check sp_inact */ 121126274Sdes daysleft = spw->sp_lstchg + spw->sp_max - today; 122126274Sdes if (disabled) { 123126274Sdes debug3("password expiration disabled"); 124126274Sdes } else if (spw->sp_lstchg == 0) { 125126274Sdes logit("User %.100s password has expired (root forced)", user); 126126274Sdes return 1; 127126274Sdes } else if (spw->sp_max == -1) { 128126274Sdes debug3("password expiration disabled"); 129126274Sdes } else if (daysleft < 0) { 130126274Sdes logit("User %.100s password has expired (password aged)", user); 131126274Sdes return 1; 132126274Sdes } else if (daysleft <= spw->sp_warn) { 133126274Sdes debug3("password will expire in %d days", daysleft); 134126274Sdes snprintf(buf, sizeof(buf), 135126274Sdes "Your password will expire in %d day%s.\n", daysleft, 136126274Sdes daysleft == 1 ? "" : "s"); 137126274Sdes buffer_append(&loginmsg, buf, strlen(buf)); 138126274Sdes } 139126274Sdes 140126274Sdes return 0; 141126274Sdes} 142126274Sdes#endif /* USE_SHADOW && HAS_SHADOW_EXPIRE */ 143