date and time created 80/10/01 17:29:40 by bill
[unix-history] / usr / src / usr.bin / login / login.c
CommitLineData
88a01c09
BJ
1static char *sccsid = "@(#)login.c 4.1 (Berkeley) %G%";
2/*
3 * login [ name ]
4 */
5
6#include <sys/types.h>
7#include <sgtty.h>
8#include <utmp.h>
9#include <signal.h>
10#include <pwd.h>
11#include <stdio.h>
12#include <sys/stat.h>
13#include <lastlog.h>
14#define SCPYN(a, b) strncpy(a, b, sizeof(a))
15
16#define NMAX sizeof(utmp.ut_name)
17#define LMAX sizeof(utmp.ut_line)
18
19char user[20];
20char maildir[30] = "/usr/spool/mail/";
21char lastlog[] = "/usr/adm/lastlog";
22struct passwd nouser = {"", "nope"};
23struct sgttyb ttyb;
24struct utmp utmp;
25char minusnam[16] = "-";
26char homedir[64] = "HOME=";
27char shell[64] = "SHELL=";
28char term[64] = "TERM=";
29char *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0};
30struct passwd *pwd;
31
32struct passwd *getpwnam();
33char *strcat();
34int setpwent();
35char *ttyname();
36char *crypt();
37char *getpass();
38char *rindex();
39char *stypeof();
40extern char **environ;
41
42main(argc, argv)
43char **argv;
44{
45 register char *namep;
46 int t, f, c;
47 char *ttyn;
48 int ldisc = 0;
49
50 alarm(60);
51 signal(SIGQUIT, SIG_IGN);
52 signal(SIGINT, SIG_IGN);
53 nice(-100);
54 nice(20);
55 nice(0);
56 ioctl(0, TIOCLSET, 0);
57 ioctl(0, TIOCNXCL, 0);
58 gtty(0, &ttyb);
59 ttyb.sg_erase = '#';
60 ttyb.sg_kill = '@';
61 stty(0, &ttyb);
62 for (t=3; t<20; t++)
63 close(t);
64 ttyn = ttyname(0);
65 if (ttyn==0)
66 ttyn = "/dev/tty??";
67
68 loop:
69 ldisc = 0;
70 ioctl(0, TIOCSETD, &ldisc);
71 SCPYN(utmp.ut_name, "");
72 if (argc>1) {
73 SCPYN(utmp.ut_name, argv[1]);
74 argc = 0;
75 }
76 while (utmp.ut_name[0] == '\0') {
77 namep = utmp.ut_name;
78 printf("login: ");
79 while ((c = getchar()) != '\n') {
80 if(c == ' ')
81 c = '_';
82 if (c == EOF)
83 exit(0);
84 if (namep < utmp.ut_name+NMAX)
85 *namep++ = c;
86 }
87 }
88 setpwent();
89 if ((pwd = getpwnam(utmp.ut_name)) == NULL)
90 pwd = &nouser;
91 endpwent();
92 if (!strcmp(pwd->pw_shell, "/bin/csh")) {
93 ldisc = NTTYDISC;
94 ioctl(0, TIOCSETD, &ldisc);
95 }
96 if (*pwd->pw_passwd != '\0') {
97 nice(-4);
98 namep = crypt(getpass("Password:"),pwd->pw_passwd);
99 nice(4);
100 if (strcmp(namep, pwd->pw_passwd)) {
101bad:
102 printf("Login incorrect\n");
103 if (ttyn[LMAX] == 'd') {
104 FILE *console = fopen("/dev/console", "w");
105 if (console != NULL) {
106 fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name);
107 fclose(console);
108 }
109 }
110 goto loop;
111 }
112 }
113 sprintf(user, "USER=%.*s", NMAX, pwd->pw_name);
114 if (pwd->pw_uid == 0 && ttyn[5] != 'c')
115 goto bad;
116 if (ttyn[LMAX] == 'd') {
117 FILE *console = fopen("/dev/console", "w");
118 if (console != NULL) {
119 fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name);
120 fclose(console);
121 }
122 }
123 if((f = open(lastlog, 2)) >= 0) {
124 struct lastlog ll;
125
126 lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0);
127 if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) {
128 register char *ep = (char *) ctime(&ll.ll_time);
129 printf("Last login: ");
130 ep[24 - 5] = 0;
131 printf("%s on %.*s\n", ep, LMAX, ll.ll_line);
132 }
133 lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0);
134 time(&ll.ll_time);
135 strcpyn(ll.ll_line, ttyn+5, LMAX);
136 write(f, (char *) &ll, sizeof ll);
137 close(f);
138 }
139 if(chdir(pwd->pw_dir) < 0) {
140 printf("No directory\n");
141 goto loop;
142 }
143 time(&utmp.ut_time);
144 t = ttyslot();
145 if (t>0 && (f = open("/etc/utmp", 1)) >= 0) {
146 lseek(f, (long)(t*sizeof(utmp)), 0);
147 SCPYN(utmp.ut_line, rindex(ttyn, '/')+1);
148 write(f, (char *)&utmp, sizeof(utmp));
149 close(f);
150 }
151 if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
152 lseek(f, 0L, 2);
153 write(f, (char *)&utmp, sizeof(utmp));
154 close(f);
155 }
156 chown(ttyn, pwd->pw_uid, pwd->pw_gid);
157 setgid(pwd->pw_gid);
158 setuid(pwd->pw_uid);
159 if (*pwd->pw_shell == '\0')
160 pwd->pw_shell = "/bin/sh";
161 environ = envinit;
162 strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
163 strncat(shell, pwd->pw_shell, sizeof(shell)-7);
164 strncat(term, stypeof(ttyn), sizeof(term)-6);
165 if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
166 namep = pwd->pw_shell;
167 else
168 namep++;
169 strcat(minusnam, namep);
170 alarm(0);
171 umask(022);
172 showmotd();
173 strcat(maildir, pwd->pw_name);
174 if(access(maildir,4)==0) {
175 struct stat statb;
176 stat(maildir, &statb);
177 if (statb.st_size)
178 printf("You have mail.\n");
179 }
180 signal(SIGQUIT, SIG_DFL);
181 signal(SIGINT, SIG_DFL);
182 execlp(pwd->pw_shell, minusnam, 0);
183 printf("No shell\n");
184 exit(0);
185}
186
187int stopmotd;
188catch()
189{
190 signal(SIGINT, SIG_IGN);
191 stopmotd++;
192}
193
194showmotd()
195{
196 FILE *mf;
197 register c;
198
199 signal(SIGINT, catch);
200 if((mf = fopen("/etc/motd","r")) != NULL) {
201 while((c = getc(mf)) != EOF && stopmotd == 0)
202 putchar(c);
203 fclose(mf);
204 }
205 signal(SIGINT, SIG_IGN);
206}
207
208#define UNKNOWN "su"
209
210char *
211stypeof(ttyid)
212char *ttyid;
213{
214 static char typebuf[16];
215 char buf[50];
216 register FILE *f;
217 register char *p, *t, *q;
218
219 if (ttyid == NULL)
220 return (UNKNOWN);
221 f = fopen("/etc/ttytype", "r");
222 if (f == NULL)
223 return (UNKNOWN);
224 /* split off end of name */
225 for (p = q = ttyid; *p != 0; p++)
226 if (*p == '/')
227 q = p + 1;
228
229 /* scan the file */
230 while (fgets(buf, sizeof buf, f) != NULL)
231 {
232 for (t=buf; *t!=' '; t++)
233 ;
234 *t++ = 0;
235 for (p=t; *p>' '; p++)
236 ;
237 *p = 0;
238 if (strcmp(q,t)==0) {
239 strcpy(typebuf, buf);
240 fclose(f);
241 return (typebuf);
242 }
243 }
244 fclose (f);
245 return (UNKNOWN);
246}