2 * Copyright (c) 1989 - 1994, Julianne Frances Haugh
3 * Copyright (c) 1996 - 1998, Marek Michałkiewicz
4 * Copyright (c) 2001 - 2006, Tomasz Kłoczko
5 * Copyright (c) 2008 , Nicolas François
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the copyright holders or contributors may not be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/types.h>
39 #include "prototypes.h"
41 #include "exitcodes.h"
47 #ifndef PASSWD_PROGRAM
48 #define PASSWD_PROGRAM "/bin/passwd"
51 * expire - force password change if password expired
53 * expire() calls /bin/passwd to change the user's password
56 int expire (const struct passwd *pw, const struct spwd *sp)
63 sp = pwd_to_spwd (pw);
67 * See if the user's password has expired, and if so
68 * force them to change their password.
71 status = isexpired (pw, sp);
76 (void) fputs (_("Your password has expired."), stdout);
79 (void) fputs (_("Your password is inactive."), stdout);
82 (void) fputs (_("Your login has expired."), stdout);
87 * Setting the maximum valid period to less than the minimum
88 * valid period means that the minimum period will never
89 * occur while the password is valid, so the user can never
90 * change that password.
93 if ((status > 1) || (sp->sp_max < sp->sp_min)) {
94 (void) puts (_(" Contact the system administrator."));
97 (void) puts (_(" Choose a new password."));
98 (void) fflush (stdout);
101 * Close all the files so that unauthorized access won't
102 * occur. This needs to be done anyway because those files
103 * might become stale after "passwd" is executed.
114 * Execute the /bin/passwd command. The exit status will be
115 * examined to see what the result is. If there are any
116 * errors the routine will exit. This forces the user to
117 * change their password before being able to use the account.
125 * Set the UID to be that of the user. This causes
126 * passwd to work just like it would had they executed
127 * it from the command line while logged in.
129 if (setup_uid_gid (pw, 0) != 0) {
133 execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
135 perror ("Can't execute " PASSWD_PROGRAM);
136 _exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
137 } else if ((pid_t) -1 == pid) {
142 while (((child = wait (&status)) != pid) && (child != (pid_t)-1));
144 if ((child == pid) && (0 == status)) {
152 * agecheck - see if warning is needed for password expiration
154 * agecheck sees how many days until the user's password is going
155 * to expire and warns the user of the pending password expiration.
158 void agecheck (const struct passwd *pw, const struct spwd *sp)
160 long now = (long) time ((time_t *) 0) / SCALE;
164 sp = pwd_to_spwd (pw);
168 * The last, max, and warn fields must be supported or the
169 * warning period cannot be calculated.
172 if ( (-1 == sp->sp_lstchg)
173 || (-1 == sp->sp_max)
174 || (-1 == sp->sp_warn)) {
177 remain = sp->sp_lstchg + sp->sp_max - now;
178 if (remain <= sp->sp_warn) {
179 remain /= DAY / SCALE;
181 (void) printf (_("Your password will expire in %ld days.\n"),
183 } else if (1 == remain) {
184 (void) puts (_("Your password will expire tomorrow."));
185 } else if (remain == 0) {
186 (void) puts (_("Your password will expire today."));