sudo.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2014 K. Lange
  5. *
  6. * sudo
  7. *
  8. */
  9. #include <stdio.h>
  10. #include <stdint.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <time.h>
  15. #include <signal.h>
  16. #include <termios.h>
  17. #include <errno.h>
  18. #include <sys/wait.h>
  19. #include <sys/utsname.h>
  20. #include <toaru/auth.h>
  21. uint32_t child = 0;
  22. void usage(int argc, char * argv[]) {
  23. fprintf(stderr, "usage: %s [command]\n", argv[0]);
  24. }
  25. int main(int argc, char ** argv) {
  26. int fails = 0;
  27. if (argc < 2) {
  28. usage(argc, argv);
  29. return 1;
  30. }
  31. while (1) {
  32. /*
  33. * This is not very secure, but I'm lazy and just want this to exist.
  34. * It's not like we have file system permissions or anything like
  35. * that sitting around anyway... So, XXX: make this not dumb.
  36. */
  37. char * username = getenv("USER");
  38. char * password = malloc(sizeof(char) * 1024);
  39. fprintf(stderr, "[%s] password for %s: ", argv[0], username);
  40. fflush(stderr);
  41. /* Disable echo */
  42. struct termios old, new;
  43. tcgetattr(fileno(stdin), &old);
  44. new = old;
  45. new.c_lflag &= (~ECHO);
  46. tcsetattr(fileno(stdin), TCSAFLUSH, &new);
  47. fgets(password, 1024, stdin);
  48. password[strlen(password)-1] = '\0';
  49. tcsetattr(fileno(stdin), TCSAFLUSH, &old);
  50. fprintf(stderr, "\n");
  51. int uid = toaru_auth_check_pass(username, password);
  52. if (uid < 0) {
  53. fails++;
  54. if (fails == 3) {
  55. fprintf(stderr, "%s: %d incorrect password attempts\n", argv[0], fails);
  56. break;
  57. }
  58. fprintf(stderr, "Sorry, try again.\n");
  59. continue;
  60. }
  61. /* Set username to root */
  62. putenv("USER=root");
  63. if (!strcmp(argv[1], "-s")) {
  64. argv[1] = getenv("SHELL");
  65. }
  66. char ** args = &argv[1];
  67. execvp(args[0], args);
  68. /* XXX: There are other things that can cause an exec to fail. */
  69. fprintf(stderr, "%s: %s: command not found\n", argv[0], args[0]);
  70. return 1;
  71. }
  72. return 1;
  73. }