1 /* vi: set sw=4 ts=4: */
2 /*
3 * issue.c: issue printing code
4 *
5 * Copyright (C) 2003 Bastian Blank <waldi@tuxbox.org>
6 *
7 * Optimize and correcting OCRNL by Vladimir Oleynik <dzo@simtreas.ru>
8 *
9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
10 */
11 #include "libbb.h"
12 /* After libbb.h, since it needs sys/types.h on some systems */
13 #include <sys/utsname.h>
14
15 #define LOGIN " login: "
16
17 static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y";
18
print_login_issue(const char * issue_file,const char * tty)19 void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
20 {
21 FILE *fp;
22 int c;
23 char buf[256+1];
24 const char *outbuf;
25 time_t t;
26 struct utsname uts;
27
28 time(&t);
29 uname(&uts);
30
31 puts("\r"); /* start a new line */
32
33 fp = fopen_for_read(issue_file);
34 if (!fp)
35 return;
36 while ((c = fgetc(fp)) != EOF) {
37 outbuf = buf;
38 buf[0] = c;
39 buf[1] = '\0';
40 if (c == '\n') {
41 buf[1] = '\r';
42 buf[2] = '\0';
43 }
44 if (c == '\\' || c == '%') {
45 c = fgetc(fp);
46 switch (c) {
47 //From getty manpage (* - supported by us)
48 //========================================
49 //4 or 4{interface}
50 // Insert the IPv4 address of the network interface (example: \4{eth0}).
51 // If the interface argument is not specified, then select the first
52 // fully configured (UP, non-LOOPBACK, RUNNING) interface.
53 //6 or 6{interface} -- The same as \4 but for IPv6.
54 //b -- Insert the baudrate of the current line.
55 //*d -- Insert the current date.
56 //*t -- Insert the current time.
57 //e or e{name}
58 // Translate the human-readable name to an escape sequence and insert it
59 // (for example: \e{red}Alert text.\e{reset}). If the name argument
60 // is not specified, then insert \033. The currently supported names are:
61 // black, blink, blue, bold, brown, cyan, darkgray, gray, green, halfbright,
62 // lightblue, lightcyan, lightgray, lightgreen, lightmagenta, lightred,
63 // magenta, red, reset, reverse, and yellow. Unknown names are ignored.
64 //*s
65 // Insert the system name (the name of the operating system - `uname -s`)
66 //*S or S{VARIABLE}
67 // Insert the VARIABLE data from /etc/os-release.
68 // If the VARIABLE argument is not specified, use PRETTY_NAME.
69 // If PRETTY_NAME is not in /etc/os-release, \S is the same as \s.
70 //*l -- Insert the name of the current tty line.
71 //*m -- Insert the architecture identifier of the machine: `uname -m`.
72 //*n -- Insert the nodename of the machine: `uname -n`.
73 //*o -- Insert the NIS domainname of the machine. Same as `hostname -d'.
74 //*O -- Insert the DNS domainname of the machine.
75 //*r -- Insert the release number of the OS: `uname -r`.
76 //u -- Insert the number of current users logged in.
77 //U -- Insert the string "1 user" or "N users" (current users logged in).
78 //*v -- Insert the version of the OS, e.g. the build-date etc: `uname -v`.
79 //We also implement:
80 //*D -- same as \O "DNS domainname"
81 //*h -- same as \n "nodename"
82
83 case 'S':
84 /* minimal implementation, not reading /etc/os-release */
85 /*FALLTHROUGH*/
86 case 's':
87 outbuf = uts.sysname;
88 break;
89 case 'n':
90 case 'h':
91 outbuf = uts.nodename;
92 break;
93 case 'r':
94 outbuf = uts.release;
95 break;
96 case 'v':
97 outbuf = uts.version;
98 break;
99 case 'm':
100 outbuf = uts.machine;
101 break;
102 /* The field domainname of struct utsname is Linux specific. */
103 #if defined(__linux__)
104 case 'D':
105 case 'o':
106 case 'O':
107 outbuf = uts.domainname;
108 break;
109 #endif
110 case 'd':
111 strftime(buf, sizeof(buf), fmtstr_d, localtime(&t));
112 break;
113 case 't':
114 strftime_HHMMSS(buf, sizeof(buf), &t);
115 break;
116 case 'l':
117 outbuf = tty;
118 break;
119 default:
120 buf[0] = c;
121 }
122 }
123 fputs_stdout(outbuf);
124 }
125 fclose(fp);
126 fflush_all();
127 }
128
print_login_prompt(void)129 void FAST_FUNC print_login_prompt(void)
130 {
131 char *hostname = safe_gethostname();
132
133 fputs_stdout(hostname);
134 fputs_stdout(LOGIN);
135 fflush_all();
136 free(hostname);
137 }
138
139 /* Clear dangerous stuff, set PATH */
140 static const char forbid[] ALIGN1 =
141 "ENV" "\0"
142 "BASH_ENV" "\0"
143 "HOME" "\0"
144 "IFS" "\0"
145 "SHELL" "\0"
146 "LD_LIBRARY_PATH" "\0"
147 "LD_PRELOAD" "\0"
148 "LD_TRACE_LOADED_OBJECTS" "\0"
149 "LD_BIND_NOW" "\0"
150 "LD_AOUT_LIBRARY_PATH" "\0"
151 "LD_AOUT_PRELOAD" "\0"
152 "LD_NOWARN" "\0"
153 "LD_KEEPDIR" "\0";
154
sanitize_env_if_suid(void)155 int FAST_FUNC sanitize_env_if_suid(void)
156 {
157 const char *p;
158
159 if (getuid() == geteuid())
160 return 0;
161
162 p = forbid;
163 do {
164 unsetenv(p);
165 p += strlen(p) + 1;
166 } while (*p);
167 putenv((char*)bb_PATH_root_path);
168
169 return 1; /* we indeed were run by different user! */
170 }
171