1 /*- 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)util.c 5.13 (Berkeley) 06/29/90"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <sys/time.h> 14 #include <tzfile.h> 15 #include <pwd.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include <ctype.h> 19 #include "chpass.h" 20 #include "pathnames.h" 21 22 static int dmsize[] = 23 { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 24 static char *months[] = 25 { "January", "February", "March", "April", "May", "June", 26 "July", "August", "September", "October", "November", 27 "December", NULL }; 28 char * 29 ttoa(tval) 30 time_t tval; 31 { 32 struct tm *tp; 33 static char tbuf[50]; 34 35 if (tval) { 36 tp = localtime(&tval); 37 (void)sprintf(tbuf, "%s %d, 19%d", months[tp->tm_mon], 38 tp->tm_mday, tp->tm_year); 39 } 40 else 41 *tbuf = '\0'; 42 return(tbuf); 43 } 44 45 atot(p, store) 46 char *p; 47 time_t *store; 48 { 49 register char *t, **mp; 50 static struct tm *lt; 51 time_t tval, time(); 52 int day, month, year; 53 54 if (!*p) { 55 *store = 0; 56 return(0); 57 } 58 if (!lt) { 59 unsetenv("TZ"); 60 (void)time(&tval); 61 lt = localtime(&tval); 62 } 63 if (!(t = strtok(p, " \t"))) 64 goto bad; 65 for (mp = months;; ++mp) { 66 if (!*mp) 67 goto bad; 68 if (!strncasecmp(*mp, t, 3)) { 69 month = mp - months + 1; 70 break; 71 } 72 } 73 if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) 74 goto bad; 75 day = atoi(t); 76 if (!(t = strtok((char *)NULL, " \t,")) || !isdigit(*t)) 77 goto bad; 78 year = atoi(t); 79 if (day < 1 || day > 31 || month < 1 || month > 12 || !year) 80 goto bad; 81 if (year < 100) 82 year += TM_YEAR_BASE; 83 if (year <= EPOCH_YEAR) 84 bad: return(1); 85 tval = isleap(year) && month > 2; 86 for (--year; year >= EPOCH_YEAR; --year) 87 tval += isleap(year) ? 88 DAYSPERLYEAR : DAYSPERNYEAR; 89 while (--month) 90 tval += dmsize[month]; 91 tval += day; 92 tval = tval * HOURSPERDAY * MINSPERHOUR * SECSPERMIN; 93 tval -= lt->tm_gmtoff; 94 *store = tval; 95 return(0); 96 } 97 98 /* 99 * print -- 100 * print out the file for the user to edit; strange side-effect: 101 * return if the user is allowed to modify their shell. 102 */ 103 print(fp, pw) 104 FILE *fp; 105 struct passwd *pw; 106 { 107 register char *p; 108 int shellval; 109 char *bp; 110 char *getusershell(), *ok_shell(), *ttoa(); 111 112 shellval = 1; 113 (void)fprintf(fp, "#Changing user database information for %s.\n", 114 pw->pw_name); 115 if (!uid) { 116 (void)fprintf(fp, "Login: %s\n", pw->pw_name); 117 (void)fprintf(fp, "Password: %s\n", pw->pw_passwd); 118 (void)fprintf(fp, "Uid [#]: %d\n", pw->pw_uid); 119 (void)fprintf(fp, "Gid [# or name]: %d\n", pw->pw_gid); 120 (void)fprintf(fp, "Change [month day year]: %s\n", 121 ttoa(pw->pw_change)); 122 (void)fprintf(fp, "Expire [month day year]: %s\n", 123 ttoa(pw->pw_expire)); 124 (void)fprintf(fp, "Class: %s\n", pw->pw_class); 125 (void)fprintf(fp, "Home directory: %s\n", pw->pw_dir); 126 (void)fprintf(fp, "Shell: %s\n", 127 *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); 128 } 129 /* only admin can change "restricted" shells */ 130 else if (ok_shell(pw->pw_shell)) 131 (void)fprintf(fp, "Shell: %s\n", 132 *pw->pw_shell ? pw->pw_shell : _PATH_BSHELL); 133 else 134 shellval = 0; 135 bp = pw->pw_gecos; 136 p = strsep(&bp, ","); 137 (void)fprintf(fp, "Full Name: %s\n", p ? p : ""); 138 p = strsep(&bp, ","); 139 (void)fprintf(fp, "Location: %s\n", p ? p : ""); 140 p = strsep(&bp, ","); 141 (void)fprintf(fp, "Office Phone: %s\n", p ? p : ""); 142 p = strsep(&bp, ","); 143 (void)fprintf(fp, "Home Phone: %s\n", p ? p : ""); 144 return(shellval); 145 } 146 147 char * 148 ok_shell(name) 149 register char *name; 150 { 151 register char *p, *sh; 152 char *getusershell(); 153 154 setusershell(); 155 while (sh = getusershell()) { 156 if (!strcmp(name, sh)) 157 return(name); 158 /* allow just shell name, but use "real" path */ 159 if ((p = rindex(sh, '/')) && !strcmp(name, p + 1)) 160 return(sh); 161 } 162 return(NULL); 163 } 164