/*-1* SPDX-License-Identifier: BSD-4-Clause2*3* Copyright (c) 1988, 1993, 19944* The Regents of the University of California. All rights reserved.5* Copyright (c) 2002 Networks Associates Technology, Inc.6* All rights reserved.7*8* Portions of this software were developed for the FreeBSD Project by9* ThinkSec AS and NAI Labs, the Security Research Division of Network10* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-803511* ("CBOSS"), as part of the DARPA CHATS research program.12*13* Redistribution and use in source and binary forms, with or without14* modification, are permitted provided that the following conditions15* are met:16* 1. Redistributions of source code must retain the above copyright17* notice, this list of conditions and the following disclaimer.18* 2. Redistributions in binary form must reproduce the above copyright19* notice, this list of conditions and the following disclaimer in the20* documentation and/or other materials provided with the distribution.21* 3. All advertising materials mentioning features or use of this software22* must display the following acknowledgement:23* This product includes software developed by the University of24* California, Berkeley and its contributors.25* 4. Neither the name of the University nor the names of its contributors26* may be used to endorse or promote products derived from this software27* without specific prior written permission.28*29* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND30* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE31* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE32* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE33* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL34* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS35* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)36* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT37* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY38* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF39* SUCH DAMAGE.40*/4142#include <sys/types.h>4344#include <ctype.h>45#include <stdint.h>46#include <stdio.h>47#include <stdlib.h>48#include <string.h>49#include <time.h>50#include <unistd.h>5152#include "chpass.h"5354static const char *months[] =55{ "January", "February", "March", "April", "May", "June",56"July", "August", "September", "October", "November",57"December", NULL };5859char *60ttoa(time_t tval)61{62struct tm *tp;63static char tbuf[50];6465if (tval) {66tp = localtime(&tval);67(void)sprintf(tbuf, "%s %d, %d", months[tp->tm_mon],68tp->tm_mday, tp->tm_year + 1900);69}70else71*tbuf = '\0';72return (tbuf);73}7475int76atot(char *p, time_t *store)77{78static struct tm *lt;79char *t;80const char **mp;81time_t tval;82int day, month, year;8384if (!*p) {85*store = 0;86return (0);87}88if (!lt) {89unsetenv("TZ");90(void)time(&tval);91lt = localtime(&tval);92}93if (!(t = strtok(p, " \t")))94goto bad;95if (isdigit(*t)) {96month = atoi(t);97} else {98for (mp = months;; ++mp) {99if (!*mp)100goto bad;101if (!strncasecmp(*mp, t, 3)) {102month = mp - months + 1;103break;104}105}106}107if (!(t = strtok(NULL, " \t,")) || !isdigit(*t))108goto bad;109day = atoi(t);110if (!(t = strtok(NULL, " \t,")) || !isdigit(*t))111goto bad;112year = atoi(t);113if (day < 1 || day > 31 || month < 1 || month > 12)114goto bad;115/* Allow two digit years 1969-2068 */116if (year < 69)117year += 2000;118else if (year < 100)119year += 1900;120if (year < 1969)121bad: return (1);122lt->tm_year = year - 1900;123lt->tm_mon = month - 1;124lt->tm_mday = day;125lt->tm_hour = 0;126lt->tm_min = 0;127lt->tm_sec = 0;128lt->tm_isdst = -1;129if ((tval = mktime(lt)) < 0)130return (1);131#ifndef __i386__132/*133* PR227589: The pwd.db and spwd.db files store the change and expire134* dates as unsigned 32-bit ints which overflow in 2106, so larger135* values must be rejected until the introduction of a v5 password136* database. i386 has 32-bit time_t and so dates beyond y2038 are137* already rejected by mktime above.138*/139if (tval > UINT32_MAX)140return (1);141#endif142*store = tval;143return (0);144}145146int147ok_shell(char *name)148{149char *p, *sh;150151setusershell();152while ((sh = getusershell())) {153if (!strcmp(name, sh)) {154endusershell();155return (1);156}157/* allow just shell name, but use "real" path */158if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) {159endusershell();160return (1);161}162}163endusershell();164return (0);165}166167char *168dup_shell(char *name)169{170char *p, *sh, *ret;171172setusershell();173while ((sh = getusershell())) {174if (!strcmp(name, sh)) {175endusershell();176return (strdup(name));177}178/* allow just shell name, but use "real" path */179if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) {180ret = strdup(sh);181endusershell();182return (ret);183}184}185endusershell();186return (NULL);187}188189190