blob: 3dadae0ce21c297bf85ee6861dd97630ebae3313 [file] [log] [blame]
Index: coreutils/Config.in
===================================================================
RCS file: /var/cvs/busybox/coreutils/Config.in,v
retrieving revision 1.24
diff -u -r1.24 Config.in
--- a/coreutils/Config.in 15 Mar 2004 08:28:19 -0000 1.24
+++ b/coreutils/Config.in 1 May 2004 11:39:04 -0000
@@ -218,6 +218,14 @@
help
id displays the current user and group ID names.
+config CONFIG_FEATURE_ID_GROUPS_ALIAS
+ bool " Support 'groups' as alias to 'id -Gn'"
+ default y
+ depends on CONFIG_ID
+ help
+ Print the groups a user is in. This is an alias to 'id -Gn' on
+ most systems.
+
config CONFIG_INSTALL
bool "install"
default n
Index: coreutils/id.c
===================================================================
RCS file: /var/cvs/busybox/coreutils/id.c,v
retrieving revision 1.24
diff -u -r1.24 id.c
--- a/coreutils/id.c 15 Mar 2004 08:28:20 -0000 1.24
+++ b/coreutils/id.c 1 May 2004 11:39:05 -0000
@@ -3,6 +3,8 @@
* Mini id implementation for busybox
*
* Copyright (C) 2000 by Randolph Chung <tausq@debian.org>
+ * Copyright (C) 2004 by Tony J. White <tjw@tjw.org>
+ * Copyright (C) 2004 by Glenn McGrath <bug1@iinet.net.au>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +22,6 @@
*
*/
-/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
#include "busybox.h"
#include <stdio.h>
@@ -33,78 +34,153 @@
#include <flask_util.h>
#endif
-#define JUST_USER 1
-#define JUST_GROUP 2
-#define PRINT_REAL 4
-#define NAME_NOT_NUMBER 8
+#define ID_OPT_JUST_USER 1
+#define ID_OPT_JUST_GROUP 2
+#define ID_OPT_ALL_GROUPS 4
+#define ID_OPT_PRINT_REAL 8
+#define ID_OPT_NAME_NOT_NUMBER 16
+
+static void print_groups(unsigned long flags, const char sep)
+{
+ gid_t gids[64];
+ int gid_count;
+ int i;
+
+ gid_count = getgroups(64, gids);
+
+ for (i = 0; i < gid_count; i++) {
+ struct group *tmp_grp;
+
+ if (i != 0) {
+ putchar(sep);
+ }
+ tmp_grp = getgrgid(gids[i]);
+ if (flags & ID_OPT_NAME_NOT_NUMBER) {
+ if (tmp_grp == NULL) {
+ continue;
+ }
+ printf("%s", tmp_grp->gr_name);
+ } else {
+ printf("%u", gids[i]);
+ if (!(flags & ID_OPT_ALL_GROUPS)) {
+ if (tmp_grp == NULL) {
+ continue;
+ }
+ printf("(%s)", tmp_grp->gr_name);
+ }
+ }
+ }
+}
extern int id_main(int argc, char **argv)
{
- char user[9], group[9];
- long pwnam, grnam;
- int uid, gid;
- int flags;
+ struct group *grp;
+ struct passwd *usr;
+ unsigned long flags;
+ uid_t uid;
+ uid_t gid;
+ uid_t euid;
+ uid_t egid;
#ifdef CONFIG_SELINUX
int is_flask_enabled_flag = is_flask_enabled();
#endif
- flags = bb_getopt_ulflags(argc, argv, "ugrn");
+ bb_opt_complementaly = "u~gG:g~uG:G~ug:~n";
+ flags = bb_getopt_ulflags(argc, argv, "ugGrn");
- if (((flags & (JUST_USER | JUST_GROUP)) == (JUST_USER | JUST_GROUP))
- || (argc > optind + 1)
- ) {
+ /* Check one and only one context option was given */
+ if ((flags & 0x80000000UL) ||
+ (flags & (ID_OPT_PRINT_REAL | ID_OPT_ALL_GROUPS)) ||
+ ((flags & (ID_OPT_PRINT_REAL | ID_OPT_NAME_NOT_NUMBER)) ==
+ (ID_OPT_PRINT_REAL | ID_OPT_NAME_NOT_NUMBER))) {
bb_show_usage();
}
+#ifdef CONFIG_FEATURE_ID_GROUPS_ALIAS
+ /* groups command is an alias for 'id -Gn' */
+ if (bb_applet_name[0] == 'g') {
+ flags |= (ID_OPT_ALL_GROUPS + ID_OPT_NAME_NOT_NUMBER);
+ }
+#endif
+
+ uid = getuid();
+ gid = getgid();
+ euid = geteuid();
+ egid = getegid();
+
+ if (flags & ID_OPT_PRINT_REAL) {
+ euid = uid;
+ egid = gid;
+ }
+
if (argv[optind] == NULL) {
- if (flags & PRINT_REAL) {
- uid = getuid();
- gid = getgid();
- } else {
- uid = geteuid();
- gid = getegid();
- }
- my_getpwuid(user, uid);
+ usr = getpwuid(euid);
+ grp = getgrgid(egid);
} else {
- safe_strncpy(user, argv[optind], sizeof(user));
- gid = my_getpwnamegid(user);
+ usr = getpwnam(argv[optind]);
+ grp = getgrnam(argv[optind]);
}
- my_getgrgid(group, gid);
- pwnam=my_getpwnam(user);
- grnam=my_getgrnam(group);
+ if (usr == NULL) {
+ bb_perror_msg_and_die("cannot find user name");
+ }
+ if (grp == NULL) {
+ bb_perror_msg_and_die("cannot find group name");
+ }
- if (flags & (JUST_GROUP | JUST_USER)) {
- char *s = group;
- if (flags & JUST_USER) {
- s = user;
- grnam = pwnam;
+ if (flags & ID_OPT_JUST_USER) {
+ if (flags & ID_OPT_NAME_NOT_NUMBER) {
+ printf("%s", grp->gr_name);
+ } else {
+ printf("%u", euid);
}
- if (flags & NAME_NOT_NUMBER) {
- puts(s);
+ }
+ else if (flags & ID_OPT_JUST_GROUP) {
+ if (flags & ID_OPT_NAME_NOT_NUMBER) {
+ printf("%s", grp->gr_name);
} else {
- printf("%ld\n", grnam);
+ printf("%u", egid);
}
+ }
+ else if (flags & ID_OPT_ALL_GROUPS) {
+ print_groups(flags, ' ');
} else {
-#ifdef CONFIG_SELINUX
- printf("uid=%ld(%s) gid=%ld(%s)", pwnam, user, grnam, group);
- if(is_flask_enabled_flag)
- {
- security_id_t mysid = getsecsid();
- char context[80];
- int len = sizeof(context);
- context[0] = '\0';
- if(security_sid_to_context(mysid, context, &len))
- strcpy(context, "unknown");
- printf(" context=%s\n", context);
- }
- else
- printf("\n");
-#else
- printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group);
-#endif
+ printf("uid=%u(%s) gid=%u(%s)", uid, usr->pw_name, gid, grp->gr_name);
+ if (uid != euid) {
+ struct passwd *eusr;
+ printf(" euid=%u", euid);
+ eusr = getpwuid(euid);
+ if (eusr != NULL) {
+ printf("(%s)", eusr->pw_name);
+ }
+ }
+ if (gid != egid) {
+ struct group *egrp;
+ printf(" egid=%u", egid);
+ egrp = getgrgid(egid);
+ if (egrp != NULL) {
+ printf("(%s)", egrp->gr_name);
+ }
+ }
+ printf(" groups=");
+ print_groups(flags, ',');
+ }
+#ifdef CONFIG_SELINUX
+ if (is_flask_enabled_flag)
+ {
+ security_id_t mysid = getsecsid();
+ char context[80];
+ int len = sizeof(context);
+
+ context[0] = '\0';
+ if (security_sid_to_context(mysid, len, &len)) {
+ strcpy(context, "unknown");
+ }
+ printf(" context=%s", context);
}
+#endif
+ putchar('\n');
bb_fflush_stdout_and_exit(0);
}
Index: include/applets.h
===================================================================
RCS file: /var/cvs/busybox/include/applets.h,v
retrieving revision 1.113
diff -u -r1.113 applets.h
--- a/include/applets.h 6 Apr 2004 16:59:43 -0000 1.113
+++ b/include/applets.h 1 May 2004 11:39:06 -0000
@@ -232,6 +232,9 @@
#ifdef CONFIG_GREP
APPLET(grep, grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
+#if defined(CONFIG_FEATURE_ID_GROUPS_ALIAS)
+ APPLET(groups, id_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
+#endif
#ifdef CONFIG_GUNZIP
APPLET(gunzip, gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
Index: include/usage.h
===================================================================
RCS file: /var/cvs/busybox/include/usage.h,v
retrieving revision 1.207
diff -u -r1.207 usage.h
--- a/include/usage.h 14 Apr 2004 17:59:21 -0000 1.207
+++ b/include/usage.h 1 May 2004 11:39:10 -0000
@@ -800,6 +800,16 @@
"$ grep ^[rR]oo. /etc/passwd\n" \
"root:x:0:0:root:/root:/bin/bash\n"
+#define groups_trivial_usage \
+ " [USERNAME]"
+#define groups_full_usage \
+ "Print all group names that USERNAME is a member of."
+#define groups_example_usage \
+ "$ groups\n" \
+ "andersen users\n" \
+ "$ groups tjw\n" \
+ "tjw users\n"
+
#define gunzip_trivial_usage \
"[OPTION]... FILE"
#define gunzip_full_usage \
@@ -1035,7 +1045,7 @@
#endif
#define id_trivial_usage \
- "[OPTIONS]... [USERNAME]"
+ "[-Ggu[nr]]] [USERNAME]"
#define id_full_usage \
"Print information for USERNAME or the current user\n\n" \
"Options:\n" \
@@ -1043,10 +1053,11 @@
"\t-g\tprints only the group ID\n" \
"\t-u\tprints only the user ID\n" \
"\t-n\tprint a name instead of a number\n" \
- "\t-r\tprints the real user ID instead of the effective ID"
+ "\t-r\tprints the real user ID instead of the effective ID\n" \
+ "\t-G\tprints all groups the user belongs to"
#define id_example_usage \
"$ id\n" \
- "uid=1000(andersen) gid=1000(andersen)\n"
+ "uid=1000(andersen) gid=1000(andersen) groups=1000(andersen),100(users)\n"
#ifdef CONFIG_FEATURE_IFCONFIG_SLIP
#define USAGE_SIOCSKEEPALIVE(a) a