aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-09-14 17:03:18 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-09-14 17:03:18 +0000
commit50776c99c95cbab8d018d025ed8558b9a3bfb1d4 (patch)
tree405572e1feb682ca498c5556173f168f58817242
parent866893937a18228b1913f63178bb0c819198adac (diff)
downloadbusybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.tar.gz
busybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.tar.bz2
busybox-w32-50776c99c95cbab8d018d025ed8558b9a3bfb1d4.zip
login: eliminate forward decls and #ifdefs
git-svn-id: svn://busybox.net/trunk/busybox@16123 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--loginutils/login.c357
1 files changed, 166 insertions, 191 deletions
diff --git a/loginutils/login.c b/loginutils/login.c
index 2c23a8d50..78a2ba117 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -15,13 +15,6 @@
15#include <errno.h> 15#include <errno.h>
16#endif 16#endif
17 17
18/* import from utmp.c
19 * XXX: FIXME: provide empty bodies if ENABLE_FEATURE_UTMP == 0
20 */
21static struct utmp utent;
22static void read_or_build_utent(int);
23static void write_utent(const char *);
24
25enum { 18enum {
26 TIMEOUT = 60, 19 TIMEOUT = 60,
27 EMPTY_USERNAME_COUNT = 10, 20 EMPTY_USERNAME_COUNT = 10,
@@ -29,16 +22,176 @@ enum {
29 TTYNAME_SIZE = 32, 22 TTYNAME_SIZE = 32,
30}; 23};
31 24
32static void die_if_nologin_and_non_root(int amroot); 25static char full_tty[TTYNAME_SIZE];
26static char* short_tty = full_tty;
27
28#if ENABLE_FEATURE_UTMP
29/* vv Taken from tinylogin utmp.c vv */
30/*
31 * read_or_build_utent - see if utmp file is correct for this process
32 *
33 * System V is very picky about the contents of the utmp file
34 * and requires that a slot for the current process exist.
35 * The utmp file is scanned for an entry with the same process
36 * ID. If no entry exists the process exits with a message.
37 *
38 * The "picky" flag is for network and other logins that may
39 * use special flags. It allows the pid checks to be overridden.
40 * This means that getty should never invoke login with any
41 * command line flags.
42 */
43static struct utmp utent;
44static void read_or_build_utent(int picky)
45{
46 struct utmp *ut;
47 pid_t pid = getpid();
48
49 setutent();
50
51 /* First, try to find a valid utmp entry for this process. */
52 while ((ut = getutent()))
53 if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
54 (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS))
55 break;
56
57 /* If there is one, just use it, otherwise create a new one. */
58 if (ut) {
59 utent = *ut;
60 } else {
61 if (picky)
62 bb_error_msg_and_die("no utmp entry found");
63
64 memset(&utent, 0, sizeof(utent));
65 utent.ut_type = LOGIN_PROCESS;
66 utent.ut_pid = pid;
67 strncpy(utent.ut_line, short_tty, sizeof(utent.ut_line));
68 /* This one is only 4 chars wide. Try to fit something
69 * remotely meaningful by skipping "tty"... */
70 strncpy(utent.ut_id, short_tty + 3, sizeof(utent.ut_id));
71 strncpy(utent.ut_user, "LOGIN", sizeof(utent.ut_user));
72 utent.ut_time = time(NULL);
73 }
74 if (!picky) /* root login */
75 memset(utent.ut_host, 0, sizeof(utent.ut_host));
76}
77
78/*
79 * write_utent - put a USER_PROCESS entry in the utmp file
80 *
81 * write_utent changes the type of the current utmp entry to
82 * USER_PROCESS. the wtmp file will be updated as well.
83 */
84static void write_utent(const char *username)
85{
86 utent.ut_type = USER_PROCESS;
87 strncpy(utent.ut_user, username, sizeof(utent.ut_user));
88 utent.ut_time = time(NULL);
89 /* other fields already filled in by read_or_build_utent above */
90 setutent();
91 pututline(&utent);
92 endutent();
93#if ENABLE_FEATURE_WTMP
94 if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
95 close(creat(bb_path_wtmp_file, 0664));
96 }
97 updwtmp(bb_path_wtmp_file, &utent);
98#endif
99}
100#else /* !CONFIG_FEATURE_UTMP */
101static inline void read_or_build_utent(int) {}
102static inline void write_utent(const char *) {}
103#endif /* !CONFIG_FEATURE_UTMP */
104
105static void die_if_nologin_and_non_root(int amroot)
106{
107 FILE *fp;
108 int c;
109
110 if (access(bb_path_nologin_file, F_OK))
111 return;
112
113 fp = fopen(bb_path_nologin_file, "r");
114 if (fp) {
115 while ((c = getc(fp)) != EOF)
116 putchar((c=='\n') ? '\r' : c);
117 fflush(stdout);
118 fclose(fp);
119 } else
120 puts("\r\nSystem closed for routine maintenance\r");
121 if (!amroot)
122 exit(1);
123 puts("\r\n[Disconnect bypassed -- root login allowed.]\r");
124}
33 125
34#if ENABLE_FEATURE_SECURETTY 126#if ENABLE_FEATURE_SECURETTY
35static int check_securetty(void); 127static int check_securetty(void)
128{
129 FILE *fp;
130 int i;
131 char buf[BUFSIZ];
132
133 fp = fopen(bb_path_securetty_file, "r");
134 if (!fp) {
135 /* A missing securetty file is not an error. */
136 return 1;
137 }
138 while (fgets(buf, sizeof(buf)-1, fp)) {
139 for(i = strlen(buf)-1; i>=0; --i) {
140 if (!isspace(buf[i]))
141 break;
142 }
143 buf[++i] = '\0';
144 if ((buf[0]=='\0') || (buf[0]=='#'))
145 continue;
146 if (strcmp(buf, short_tty) == 0) {
147 fclose(fp);
148 return 1;
149 }
150 }
151 fclose(fp);
152 return 0;
153}
36#else 154#else
37static inline int check_securetty(void) { return 1; } 155static inline int check_securetty(void) { return 1; }
38#endif 156#endif
39 157
40static void get_username_or_die(char *buf, int size_buf); 158static void get_username_or_die(char *buf, int size_buf)
41static void motd(void); 159{
160 int c, cntdown;
161 cntdown = EMPTY_USERNAME_COUNT;
162prompt:
163 /* skip whitespace */
164 print_login_prompt();
165 do {
166 c = getchar();
167 if (c == EOF) exit(1);
168 if (c == '\n') {
169 if (!--cntdown) exit(1);
170 goto prompt;
171 }
172 } while (isspace(c));
173
174 *buf++ = c;
175 if (!fgets(buf, size_buf-2, stdin))
176 exit(1);
177 if (!strchr(buf, '\n'))
178 exit(1);
179 while (isgraph(*buf)) buf++;
180 *buf = '\0';
181}
182
183static void motd(void)
184{
185 FILE *fp;
186 int c;
187
188 fp = fopen(bb_path_motd_file, "r");
189 if (fp) {
190 while ((c = getc(fp)) != EOF)
191 putchar(c);
192 fclose(fp);
193 }
194}
42 195
43static void nonblock(int fd) 196static void nonblock(int fd)
44{ 197{
@@ -56,11 +209,6 @@ static void alarm_handler(int sig ATTRIBUTE_UNUSED)
56 exit(EXIT_SUCCESS); 209 exit(EXIT_SUCCESS);
57} 210}
58 211
59
60static char full_tty[TTYNAME_SIZE];
61static char* short_tty = full_tty;
62
63
64int login_main(int argc, char **argv) 212int login_main(int argc, char **argv)
65{ 213{
66 char fromhost[512]; 214 char fromhost[512];
@@ -122,11 +270,7 @@ int login_main(int argc, char **argv)
122 short_tty = full_tty + 5; 270 short_tty = full_tty + 5;
123 } 271 }
124 272
125 if (ENABLE_FEATURE_UTMP) { 273 read_or_build_utent(!amroot);
126 read_or_build_utent(!amroot);
127 if (amroot)
128 memset(utent.ut_host, 0, sizeof(utent.ut_host));
129 }
130 274
131 if (opt_host) { 275 if (opt_host) {
132 if (ENABLE_FEATURE_UTMP) 276 if (ENABLE_FEATURE_UTMP)
@@ -183,8 +327,7 @@ auth_failed:
183 alarm(0); 327 alarm(0);
184 die_if_nologin_and_non_root(pw->pw_uid == 0); 328 die_if_nologin_and_non_root(pw->pw_uid == 0);
185 329
186 if (ENABLE_FEATURE_UTMP) 330 write_utent(username);
187 write_utent(username);
188 331
189#ifdef CONFIG_SELINUX 332#ifdef CONFIG_SELINUX
190 if (is_selinux_enabled()) { 333 if (is_selinux_enabled()) {
@@ -255,171 +398,3 @@ auth_failed:
255 398
256 return EXIT_FAILURE; 399 return EXIT_FAILURE;
257} 400}
258
259
260static void get_username_or_die(char *buf, int size_buf)
261{
262 int c, cntdown;
263 cntdown = EMPTY_USERNAME_COUNT;
264prompt:
265 /* skip whitespace */
266 print_login_prompt();
267 do {
268 c = getchar();
269 if (c == EOF) exit(1);
270 if (c == '\n') {
271 if (!--cntdown) exit(1);
272 goto prompt;
273 }
274 } while (isspace(c));
275
276 *buf++ = c;
277 if (!fgets(buf, size_buf-2, stdin))
278 exit(1);
279 if (!strchr(buf, '\n'))
280 exit(1);
281 while (isgraph(*buf)) buf++;
282 *buf = '\0';
283}
284
285
286static void die_if_nologin_and_non_root(int amroot)
287{
288 FILE *fp;
289 int c;
290
291 if (access(bb_path_nologin_file, F_OK))
292 return;
293
294 fp = fopen(bb_path_nologin_file, "r");
295 if (fp) {
296 while ((c = getc(fp)) != EOF)
297 putchar((c=='\n') ? '\r' : c);
298 fflush(stdout);
299 fclose(fp);
300 } else
301 puts("\r\nSystem closed for routine maintenance\r");
302 if (!amroot)
303 exit(1);
304 puts("\r\n[Disconnect bypassed -- root login allowed.]\r");
305}
306
307#if ENABLE_FEATURE_SECURETTY
308
309static int check_securetty(void)
310{
311 FILE *fp;
312 int i;
313 char buf[BUFSIZ];
314
315 fp = fopen(bb_path_securetty_file, "r");
316 if (!fp) {
317 /* A missing securetty file is not an error. */
318 return 1;
319 }
320 while (fgets(buf, sizeof(buf)-1, fp)) {
321 for(i = strlen(buf)-1; i>=0; --i) {
322 if (!isspace(buf[i]))
323 break;
324 }
325 buf[++i] = '\0';
326 if ((buf[0]=='\0') || (buf[0]=='#'))
327 continue;
328 if (strcmp(buf, short_tty) == 0) {
329 fclose(fp);
330 return 1;
331 }
332 }
333 fclose(fp);
334 return 0;
335}
336
337#endif
338
339static void motd(void)
340{
341 FILE *fp;
342 int c;
343
344 fp = fopen(bb_path_motd_file, "r");
345 if (fp) {
346 while ((c = getc(fp)) != EOF)
347 putchar(c);
348 fclose(fp);
349 }
350}
351
352
353#if ENABLE_FEATURE_UTMP
354/* vv Taken from tinylogin utmp.c vv */
355
356/*
357 * read_or_build_utent - see if utmp file is correct for this process
358 *
359 * System V is very picky about the contents of the utmp file
360 * and requires that a slot for the current process exist.
361 * The utmp file is scanned for an entry with the same process
362 * ID. If no entry exists the process exits with a message.
363 *
364 * The "picky" flag is for network and other logins that may
365 * use special flags. It allows the pid checks to be overridden.
366 * This means that getty should never invoke login with any
367 * command line flags.
368 */
369
370static void read_or_build_utent(int picky)
371{
372 struct utmp *ut;
373 pid_t pid = getpid();
374
375 setutent();
376
377 /* First, try to find a valid utmp entry for this process. */
378 while ((ut = getutent()))
379 if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
380 (ut->ut_type == LOGIN_PROCESS || ut->ut_type == USER_PROCESS))
381 break;
382
383 /* If there is one, just use it, otherwise create a new one. */
384 if (ut) {
385 utent = *ut;
386 } else {
387 if (picky)
388 bb_error_msg_and_die("no utmp entry found");
389
390 memset(&utent, 0, sizeof(utent));
391 utent.ut_type = LOGIN_PROCESS;
392 utent.ut_pid = pid;
393 strncpy(utent.ut_line, short_tty, sizeof(utent.ut_line));
394 /* This one is only 4 chars wide. Try to fit something
395 * remotely meaningful by skipping "tty"... */
396 strncpy(utent.ut_id, short_tty + 3, sizeof(utent.ut_id));
397 strncpy(utent.ut_user, "LOGIN", sizeof(utent.ut_user));
398 utent.ut_time = time(NULL);
399 }
400}
401
402/*
403 * write_utent - put a USER_PROCESS entry in the utmp file
404 *
405 * write_utent changes the type of the current utmp entry to
406 * USER_PROCESS. the wtmp file will be updated as well.
407 */
408
409static void write_utent(const char *username)
410{
411 utent.ut_type = USER_PROCESS;
412 strncpy(utent.ut_user, username, sizeof(utent.ut_user));
413 utent.ut_time = time(NULL);
414 /* other fields already filled in by read_or_build_utent above */
415 setutent();
416 pututline(&utent);
417 endutent();
418#if ENABLE_FEATURE_WTMP
419 if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
420 close(creat(bb_path_wtmp_file, 0664));
421 }
422 updwtmp(bb_path_wtmp_file, &utent);
423#endif
424}
425#endif /* CONFIG_FEATURE_UTMP */