xref: /original-bsd/usr.bin/chpass/util.c (revision fbcc2ded)
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