id.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Mini id implementation for busybox
  4. *
  5. * Copyright (C) 2000 by Randolph Chung <tausq@debian.org>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  8. */
  9. /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
  10. /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
  11. * be more similar to GNU id.
  12. * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
  13. */
  14. #include "libbb.h"
  15. #define PRINT_REAL 1
  16. #define NAME_NOT_NUMBER 2
  17. #define JUST_USER 4
  18. #define JUST_GROUP 8
  19. #if ENABLE_SELINUX
  20. #define JUST_CONTEXT 16
  21. #endif
  22. static int printf_full(unsigned int id, const char *arg, const char prefix)
  23. {
  24. const char *fmt = "%cid=%u";
  25. int status = EXIT_FAILURE;
  26. if (arg) {
  27. fmt = "%cid=%u(%s)";
  28. status = EXIT_SUCCESS;
  29. }
  30. printf(fmt, prefix, id, arg);
  31. return status;
  32. }
  33. int id_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  34. int id_main(int argc UNUSED_PARAM, char **argv)
  35. {
  36. struct passwd *p;
  37. uid_t uid;
  38. gid_t gid;
  39. unsigned long flags;
  40. short status;
  41. #if ENABLE_SELINUX
  42. security_context_t scontext;
  43. #endif
  44. /* Don't allow -n -r -nr -ug -rug -nug -rnug */
  45. /* Don't allow more than one username */
  46. opt_complementary = "?1:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g");
  47. flags = getopt32(argv, "rnug" USE_SELINUX("Z"));
  48. /* This values could be overwritten later */
  49. uid = geteuid();
  50. gid = getegid();
  51. if (flags & PRINT_REAL) {
  52. uid = getuid();
  53. gid = getgid();
  54. }
  55. if (argv[optind]) {
  56. p = getpwnam(argv[optind]);
  57. /* xuname2uid is needed because it exits on failure */
  58. uid = xuname2uid(argv[optind]);
  59. gid = p->pw_gid;
  60. /* in this case PRINT_REAL is the same */
  61. }
  62. if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
  63. /* JUST_GROUP and JUST_USER are mutually exclusive */
  64. if (flags & NAME_NOT_NUMBER) {
  65. /* bb_getXXXid(-1) exit on failure, puts cannot segfault */
  66. puts((flags & JUST_USER) ? bb_getpwuid(NULL, -1, uid) : bb_getgrgid(NULL, -1, gid));
  67. } else {
  68. if (flags & JUST_USER) {
  69. printf("%u\n", uid);
  70. }
  71. if (flags & JUST_GROUP) {
  72. printf("%u\n", gid);
  73. }
  74. }
  75. #if ENABLE_SELINUX
  76. if (flags & JUST_CONTEXT) {
  77. selinux_or_die();
  78. if (argc - optind == 1) {
  79. bb_error_msg_and_die("user name can't be passed with -Z");
  80. }
  81. if (getcon(&scontext)) {
  82. bb_error_msg_and_die("can't get process context");
  83. }
  84. puts(scontext);
  85. }
  86. #endif
  87. /* exit */
  88. fflush_stdout_and_exit(EXIT_SUCCESS);
  89. }
  90. /* Print full info like GNU id */
  91. /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */
  92. status = printf_full(uid, bb_getpwuid(NULL, 0, uid), 'u');
  93. bb_putchar(' ');
  94. status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), 'g');
  95. #if ENABLE_SELINUX
  96. if (is_selinux_enabled()) {
  97. security_context_t mysid;
  98. const char *context;
  99. context = "unknown";
  100. getcon(&mysid);
  101. if (mysid) {
  102. context = alloca(strlen(mysid) + 1);
  103. strcpy((char*)context, mysid);
  104. freecon(mysid);
  105. }
  106. printf(" context=%s", context);
  107. }
  108. #endif
  109. bb_putchar('\n');
  110. fflush_stdout_and_exit(status);
  111. }