BSD 1 development
[unix-history] / s8 / login.c
CommitLineData
bcc34e0d
BJ
1#
2/*
3 * login [ name ]
4 */
5
6struct {
7 char name[8];
8 char tty;
9 char ifill;
10 int time[2];
11 int uuid;
12} utmp, xtmp;
13
14struct {
15 int speeds;
16 char erase, kill;
17 int tflags;
18} ttyb;
19
20struct {
21 int junk[5];
22 int size;
23 int more[12];
24} statb;
25
26extern htmp;
27struct {
28 int l_tty;
29 int l_time[2];
30} last;
31
32char mailfile[] "/usr/mail/xxxxxxxx";
33char kickoff[] "/etc/kickoff";
34char lastlog[] "/usr/adm/lastlog/XXXX";
35
36char *ttyx;
37
38#define ECHO 010
39
40main(argc, argv)
41char **argv;
42{
43 char pbuf[128];
44 register char *namep, *np, *mp;
45 int quiet;
46 char pwbuf[9], *cp, *ll;
47 int t, sflags, f, c, uid, gid, badname;
48
49 alarm(300); /* 5 minutes to log in */
50 signal(3, 1);
51 signal(2, 1);
52 nice(-2);
53 ttyx = "/dev/ttyx";
54 if ((utmp.tty=ttyn(0)) == 'x') {
55 write(1, "Sorry.\n", 7);
56 exit();
57 }
58 ttyx[8] = utmp.tty;
59 loop:
60 badname = 0;
61 namep = utmp.name;
62 mp = &mailfile[10];
63 if (argc>1) {
64 np = argv[1];
65 while (namep<utmp.name+8 && *np) {
66 *mp++ = *np;
67 *namep++ = *np++;
68 }
69 argc = 0;
70 } else {
71 write(1, "Name: ", 7);
72 while ((c = getchar()) != '\n') {
73 if (c <= 0)
74 exit();
75 if (namep < utmp.name+8) {
76 *mp++ = c;
77 *namep++ = c;
78 }
79 }
80 if(namep == utmp.name)
81 goto loop;
82 }
83 while (namep < utmp.name+8)
84 *namep++ = ' ';
85 *mp = '\0';
86 if (getpwentry(utmp.name, pbuf, "/etc/passwdf")) {
87 badname++;
88 goto askpw;
89 }
90 mp = np = colon(pbuf);
91 if (*np!=':') {
92 askpw:
93 gtty(0, &ttyb);
94 sflags = ttyb.tflags;
95 ttyb.tflags =& ~ ECHO;
96 stty(0, &ttyb);
97 write(1, "Password: ", 10);
98 namep = pwbuf;
99 while ((c=getchar()) != '\n') {
100 if (c <= 0)
101 exit();
102 if (namep<pwbuf+8)
103 *namep++ = c;
104 }
105 *namep++ = '\0';
106 ttyb.tflags = sflags;
107 stty(0, &ttyb);
108 write(1, "\n", 1);
109 namep = crypt(pwbuf);
110 while (*namep++ == *np++);
111 if (*--namep== '\0' && *--np ==':')
112 goto good;
113 namep = crypt(pwbuf);
114 np = mp;
115 while (*namep++ == *np++);
116 if (*--namep!= '\0' || *--np !=':' || badname)
117 goto bad;
118good: ;
119 }
120 if (getpwentry(utmp.name, pbuf, "/etc/passwd"))
121 goto bad;
122 np = colon(pbuf);
123 np = colon(np);
124 uid = 0;
125 while (*np != ':')
126 uid = uid*10 + *np++ - '0';
127 np++;
128 ll = &lastlog[17];
129 gid = 0;
130 while (*np != ':') {
131 *ll++ = *np;
132 gid = gid*10 + *np++ - '0';
133 }
134 *ll = 0;
135 np++;
136 np = colon(np);
137 namep = np;
138 np = colon(np);
139 time(utmp.time);
140 utmp.uuid = (gid<<8)|uid;
141 if ((f = open("/etc/utmp", 1)) >= 0) {
142 t = utmp.tty;
143 seek(f, (t&0177)*16, 0);
144 write(f, &utmp, 16);
145 close(f);
146 }
147 if ((f = open("/usr/adm/wtmp", 1)) >= 0) {
148 seek(f, 0, 2);
149 write(f, &utmp, 16);
150 close(f);
151 }
152 f = gid<<8 | uid;
153 if (f == 0)
154 if (utmp.tty!='5' && utmp.tty!='8' && utmp.tty!='t')
155 goto bad;
156 if ((f=open(lastlog, 2)) < 0) {
157 if ((f=creat(lastlog, 0600)) < 0)
158 goto cont;
159 close(f);
160 if ((f=open(lastlog, 2)) < 0)
161 goto cont;
162 }
163 seek(f, uid*6, 0);
164 if (read(f, &last.l_tty, 6) == 6) {
165 if (last.l_time[0]) {
166 ll = ctime(last.l_time);
167 c = ' ';
168 if (last.l_tty < 033) {
169 c = last.l_tty - 1 + 'a';
170 last.l_tty = '^';
171 }
172 printf("Last login: %.16s on tty%c%c\n", ll, last.l_tty, c);
173 }
174 }
175 seek(f, uid*6, 0);
176 write(f, &utmp.tty, 6);
177 close(f);
178 cont:
179 quiet = 0;
180 if(utmp.name[0] >= 'A' && utmp.name[0] <= 'Z')
181 quiet++;
182 if(!quiet)
183 if ((f = open("/etc/motd", 0)) >= 0) {
184 while ((t=read(f, &xtmp, sizeof xtmp)) > 0)
185 write(1, &xtmp, t);
186 close(f);
187 }
188 if(!quiet)
189 if(stat(mailfile, &statb) >= 0 && statb.size)
190 write(1, "You have mail.\n", 15);
191 chown(ttyx, gid<<8|uid);
192 hsetuid(gid << 8 | uid);
193 hsethome(namep);
194 hsettype(typeof(utmp.tty));
195 hput(utmp.tty);
196 setuid(gid<<8 | uid);
197 f = 0;
198 if (fork() == 0) {
199 execl(kickoff, "kickoff", 0);
200 exit();
201 } else {
202 if (gid || uid) {
203 wait(&f);
204 if (f>>8 != 0) {
205 printf("priority too low to log in\n");
206 exit();
207 }
208 }
209 }
210 for (;;) {
211 if (*namep == '\0')
212 break;
213 cp = namep++;
214 for (; *namep != '/' && *namep != '\0'; namep++);
215 if (*namep == '/')
216 *namep++ = '\0';
217 if (chdir(cp)<0) {
218 write(1, "No directory\n", 13);
219 exit();
220 }
221 alarm(0);
222 if(!quiet)
223 if ((f = open(".reminder", 0)) >= 0) {
224 while ((t=read(f, &utmp, sizeof utmp)) > 0)
225 write(1, &utmp, t);
226 close(f);
227 }
228 }
229 nice(0);
230 if (*np == '\0')
231 np = "/bin/sh";
232 if (stat(".start_up", &statb) >= 0 && statb.size)
233 if (fork() == 0) {
234 execl("/bin/sh", "-", ".start_up", 0);
235 exit();
236 } else
237 wait(&f);
238 execl(np, "-", 0);
239 write(1, "No shell.\n", 9);
240 exit();
241bad:
242 write(1, "Login incorrect.\n", 17);
243 goto loop;
244}
245
246getpwentry(name, buf, fname)
247char *name, *buf;
248{
249 extern fin;
250 int fi, r, c;
251 register char *gnp, *rnp;
252
253 fi = fin;
254 r = 1;
255 if((fin = open(fname, 0)) < 0)
256 goto ret;
257loop:
258 gnp = name;
259 rnp = buf;
260 while((c=getchar()) != '\n') {
261 if(c <= 0)
262 goto ret;
263 *rnp++ = c;
264 }
265 *rnp++ = '\0';
266 rnp = buf;
267 while (*gnp++ == *rnp++);
268 if ((*--gnp!=' ' && gnp<name+8) || *--rnp!=':')
269 goto loop;
270 r = 0;
271ret:
272 close(fin);
273 fin = 0;
274 (&fin)[1] = 0;
275 (&fin)[2] = 0;
276 return(r);
277}
278
279colon(p)
280char *p;
281{
282 register char *rp;
283
284 rp = p;
285 while (*rp != ':') {
286 if (*rp++ == '\0') {
287 write(1, "Bad /etc/passwd\n", 16);
288 exit();
289 }
290 }
291 *rp++ = '\0';
292 return(rp);
293}