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 17static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y"; 18 19void 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 129void 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 */ 140static 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 155int 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