1 /*- 2 * Copyright (c) 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 2002 Networks Associates Technology, Inc. 5 * All rights reserved. 6 * 7 * Portions of this software were developed for the FreeBSD Project by 8 * ThinkSec AS and NAI Labs, the Security Research Division of Network 9 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 10 * ("CBOSS"), as part of the DARPA CHATS research program. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)util.c 8.4 (Berkeley) 4/2/94 37 * $FreeBSD: src/usr.bin/chpass/util.c,v 1.13 2004/01/18 21:46:39 charnier Exp $ 38 * $DragonFly: src/usr.bin/chpass/util.c,v 1.3 2003/10/02 17:42:26 hmp Exp $ 39 */ 40 41 #include <sys/types.h> 42 43 #include <ctype.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <time.h> 48 #include <unistd.h> 49 50 #include "chpass.h" 51 52 static const char *months[] = 53 { "January", "February", "March", "April", "May", "June", 54 "July", "August", "September", "October", "November", 55 "December", NULL }; 56 57 char * 58 ttoa(time_t tval) 59 { 60 struct tm *tp; 61 static char tbuf[50]; 62 63 if (tval) { 64 tp = localtime(&tval); 65 sprintf(tbuf, "%s %d, %d", months[tp->tm_mon], 66 tp->tm_mday, tp->tm_year + 1900); 67 } 68 else 69 *tbuf = '\0'; 70 return (tbuf); 71 } 72 73 int 74 atot(char *p, time_t *store) 75 { 76 static struct tm *lt; 77 char *t; 78 const char **mp; 79 time_t tval; 80 int day, month, year; 81 82 if (!*p) { 83 *store = 0; 84 return (0); 85 } 86 if (!lt) { 87 unsetenv("TZ"); 88 time(&tval); 89 lt = localtime(&tval); 90 } 91 if (!(t = strtok(p, " \t"))) 92 goto bad; 93 if (isdigit(*t)) { 94 month = atoi(t); 95 } else { 96 for (mp = months;; ++mp) { 97 if (!*mp) 98 goto bad; 99 if (!strncasecmp(*mp, t, 3)) { 100 month = mp - months + 1; 101 break; 102 } 103 } 104 } 105 if (!(t = strtok(NULL, " \t,")) || !isdigit(*t)) 106 goto bad; 107 day = atoi(t); 108 if (!(t = strtok(NULL, " \t,")) || !isdigit(*t)) 109 goto bad; 110 year = atoi(t); 111 if (day < 1 || day > 31 || month < 1 || month > 12) 112 goto bad; 113 /* Allow two digit years 1969-2068 */ 114 if (year < 69) 115 year += 2000; 116 else if (year < 100) 117 year += 1900; 118 if (year < 1969) 119 bad: return (1); 120 lt->tm_year = year - 1900; 121 lt->tm_mon = month - 1; 122 lt->tm_mday = day; 123 lt->tm_hour = 0; 124 lt->tm_min = 0; 125 lt->tm_sec = 0; 126 lt->tm_isdst = -1; 127 if ((tval = mktime(lt)) < 0) 128 return (1); 129 *store = tval; 130 return (0); 131 } 132 133 int 134 ok_shell(char *name) 135 { 136 char *p, *sh; 137 138 setusershell(); 139 while ((sh = getusershell())) { 140 if (!strcmp(name, sh)) { 141 endusershell(); 142 return (1); 143 } 144 /* allow just shell name, but use "real" path */ 145 if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { 146 endusershell(); 147 return (1); 148 } 149 } 150 endusershell(); 151 return (0); 152 } 153 154 char * 155 dup_shell(char *name) 156 { 157 char *p, *sh, *ret; 158 159 setusershell(); 160 while ((sh = getusershell())) { 161 if (!strcmp(name, sh)) { 162 endusershell(); 163 return (strdup(name)); 164 } 165 /* allow just shell name, but use "real" path */ 166 if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0) { 167 ret = strdup(sh); 168 endusershell(); 169 return (ret); 170 } 171 } 172 endusershell(); 173 return (NULL); 174 } 175