login.c 4.3 KB

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