blob: f72a027fa945450f26a608806a09f3f39842e5b8 [file] [log] [blame]
Erik Andersen94f5e0b2000-05-01 19:10:52 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini id implementation for busybox
4 *
Erik Andersen94f5e0b2000-05-01 19:10:52 +00005 * Copyright (C) 2000 by Randolph Chung <tausq@debian.org>
6 *
Bernhard Reutner-Fischerb1629b12006-05-19 19:29:19 +00007 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Erik Andersen94f5e0b2000-05-01 19:10:52 +00008 */
9
Manuel Novoa III cad53642003-03-19 09:13:01 +000010/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
Eric Andersen7eb79ff2004-09-02 22:21:41 +000011/* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000012 * be more similar to GNU id.
Denis Vlasenko49622d72007-03-10 16:58:49 +000013 * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
Eric Andersen7eb79ff2004-09-02 22:21:41 +000014 */
Manuel Novoa III cad53642003-03-19 09:13:01 +000015
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000016#include "libbb.h"
Eric Andersen7eb79ff2004-09-02 22:21:41 +000017
Eric Andersen7eb79ff2004-09-02 22:21:41 +000018#define PRINT_REAL 1
19#define NAME_NOT_NUMBER 2
20#define JUST_USER 4
21#define JUST_GROUP 8
Denis Vlasenko49622d72007-03-10 16:58:49 +000022#if ENABLE_SELINUX
Denis Vlasenko3734b942007-07-27 11:20:10 +000023#define JUST_CONTEXT 16
Denis Vlasenko49622d72007-03-10 16:58:49 +000024#endif
Eric Andersen7eb79ff2004-09-02 22:21:41 +000025
Denis Vlasenko3734b942007-07-27 11:20:10 +000026static int printf_full(unsigned int id, const char *arg, const char prefix)
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000027{
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000028 const char *fmt = "%cid=%u";
Denis Vlasenko3734b942007-07-27 11:20:10 +000029 int status = EXIT_FAILURE;
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000030
Denis Vlasenkode59c0f2006-10-05 22:50:22 +000031 if (arg) {
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000032 fmt = "%cid=%u(%s)";
Denis Vlasenkode59c0f2006-10-05 22:50:22 +000033 status = EXIT_SUCCESS;
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000034 }
Denis Vlasenkof0ed3762006-10-26 23:21:47 +000035 printf(fmt, prefix, id, arg);
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000036 return status;
Eric Andersen7eb79ff2004-09-02 22:21:41 +000037}
Manuel Novoa III cad53642003-03-19 09:13:01 +000038
Denis Vlasenko06af2162007-02-03 17:28:39 +000039int id_main(int argc, char **argv);
Rob Landleydfba7412006-03-06 20:47:33 +000040int id_main(int argc, char **argv)
Erik Andersen94f5e0b2000-05-01 19:10:52 +000041{
Eric Andersen7eb79ff2004-09-02 22:21:41 +000042 struct passwd *p;
Eric Andersen7eb79ff2004-09-02 22:21:41 +000043 uid_t uid;
44 gid_t gid;
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000045 unsigned long flags;
46 short status;
Denis Vlasenko49622d72007-03-10 16:58:49 +000047#if ENABLE_SELINUX
Denis Vlasenkoc86e0522007-03-20 11:30:28 +000048 security_context_t scontext;
Denis Vlasenko49622d72007-03-10 16:58:49 +000049#endif
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000050 /* Don't allow -n -r -nr -ug -rug -nug -rnug */
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000051 /* Don't allow more than one username */
Denis Vlasenko09196572007-07-21 13:27:44 +000052 opt_complementary = "?1:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g");
Denis Vlasenkofe7cd642007-08-18 15:32:12 +000053 flags = getopt32(argv, "rnug" USE_SELINUX("Z"));
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000054
Eric Andersen7eb79ff2004-09-02 22:21:41 +000055 /* This values could be overwritten later */
56 uid = geteuid();
57 gid = getegid();
58 if (flags & PRINT_REAL) {
59 uid = getuid();
60 gid = getgid();
Erik Andersen94f5e0b2000-05-01 19:10:52 +000061 }
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000062
Denis Vlasenkode59c0f2006-10-05 22:50:22 +000063 if (argv[optind]) {
64 p = getpwnam(argv[optind]);
Denis Vlasenko9a44c4f2006-12-28 05:44:47 +000065 /* xuname2uid is needed because it exits on failure */
66 uid = xuname2uid(argv[optind]);
Eric Andersen7eb79ff2004-09-02 22:21:41 +000067 gid = p->pw_gid;
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000068 /* in this case PRINT_REAL is the same */
Erik Andersen94f5e0b2000-05-01 19:10:52 +000069 }
70
Denis Vlasenko49622d72007-03-10 16:58:49 +000071 if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000072 /* JUST_GROUP and JUST_USER are mutually exclusive */
Denis Vlasenkode59c0f2006-10-05 22:50:22 +000073 if (flags & NAME_NOT_NUMBER) {
Denis Vlasenko3734b942007-07-27 11:20:10 +000074 /* bb_getXXXid(-1) exit on failure, puts cannot segfault */
75 puts((flags & JUST_USER) ? bb_getpwuid(NULL, -1, uid) : bb_getgrgid(NULL, -1, gid));
Glenn L McGrathf15dfc52004-09-15 03:04:08 +000076 } else {
Denis Vlasenko49622d72007-03-10 16:58:49 +000077 if (flags & JUST_USER) {
Denis Vlasenkoc86e0522007-03-20 11:30:28 +000078 printf("%u\n", uid);
79 }
80 if (flags & JUST_GROUP) {
81 printf("%u\n", gid);
82 }
83 }
84
Denis Vlasenko49622d72007-03-10 16:58:49 +000085#if ENABLE_SELINUX
Denis Vlasenkoc86e0522007-03-20 11:30:28 +000086 if (flags & JUST_CONTEXT) {
Denis Vlasenko49622d72007-03-10 16:58:49 +000087 selinux_or_die();
Denis Vlasenkoc86e0522007-03-20 11:30:28 +000088 if (argc - optind == 1) {
89 bb_error_msg_and_die("user name can't be passed with -Z");
90 }
91
92 if (getcon(&scontext)) {
93 bb_error_msg_and_die("can't get process context");
94 }
Denis Vlasenkofeb7ae72007-10-01 12:05:12 +000095 puts(scontext);
Denis Vlasenkoc86e0522007-03-20 11:30:28 +000096 }
97#endif
"Vladimir N. Oleynik"064f04e2005-10-11 14:38:01 +000098 /* exit */
Denis Vlasenkof0ed3762006-10-26 23:21:47 +000099 fflush_stdout_and_exit(EXIT_SUCCESS);
Eric Andersenc1b8f122001-01-25 05:12:02 +0000100 }
Glenn L McGrathf15dfc52004-09-15 03:04:08 +0000101
Eric Andersen7eb79ff2004-09-02 22:21:41 +0000102 /* Print full info like GNU id */
Denis Vlasenko3734b942007-07-27 11:20:10 +0000103 /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */
104 status = printf_full(uid, bb_getpwuid(NULL, 0, uid), 'u');
Denis Vlasenko4daad902007-09-27 10:20:47 +0000105 bb_putchar(' ');
Denis Vlasenko3734b942007-07-27 11:20:10 +0000106 status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), 'g');
Rob Landley60158cb2005-05-03 06:25:50 +0000107
Denis Vlasenko49622d72007-03-10 16:58:49 +0000108#if ENABLE_SELINUX
Denis Vlasenkode59c0f2006-10-05 22:50:22 +0000109 if (is_selinux_enabled()) {
Denis Vlasenko7fa0fca2006-12-28 21:33:30 +0000110 security_context_t mysid;
111 const char *context;
Rob Landley60158cb2005-05-03 06:25:50 +0000112
Denis Vlasenko7fa0fca2006-12-28 21:33:30 +0000113 context = "unknown";
114 getcon(&mysid);
115 if (mysid) {
116 context = alloca(strlen(mysid) + 1);
117 strcpy((char*)context, mysid);
118 freecon(mysid);
119 }
Denis Vlasenkof0ed3762006-10-26 23:21:47 +0000120 printf(" context=%s", context);
Eric Andersen7eb79ff2004-09-02 22:21:41 +0000121 }
122#endif
Rob Landley60158cb2005-05-03 06:25:50 +0000123
Denis Vlasenko4daad902007-09-27 10:20:47 +0000124 bb_putchar('\n');
Denis Vlasenkof0ed3762006-10-26 23:21:47 +0000125 fflush_stdout_and_exit(status);
Erik Andersen94f5e0b2000-05-01 19:10:52 +0000126}