Subject: id(1) flag to get group members
To: None <tech-userlevel@netbsd.org>
From: Jan Schaumann <jschauma@netmeister.org>
List: tech-userlevel
Date: 06/17/2006 18:38:03
--8vCeF2GUdMpe9ZbK
Content-Type: multipart/mixed; boundary="tEFtbjk+mNEviIIX"
Content-Disposition: inline
--tEFtbjk+mNEviIIX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Hi,
I've on occasion had the need for a tool that tells me the users in a
given group. Sure, I could manually look at /etc/group or the NIS
database, but it seemed to me like id(1) should be able to do that.
The attached patch provides a flag for id(1) to get a groups members.
(This only lists users who are in the supplementary group, not where the
group is the primary group of a user.)
Does this make sense?
-Jan
--=20
Free Speech Online - Stop Internet Censorship
--- Electronic Frontier Foundation -- http://www.eff.org ---
--tEFtbjk+mNEviIIX
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="id.diff"
Content-Transfer-Encoding: quoted-printable
Index: id.1
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/id/id.1,v
retrieving revision 1.12
diff -b -u -r1.12 id.1
--- id.1 19 Nov 2004 14:18:01 -0000 1.12
+++ id.1 17 Jun 2006 22:18:45 -0000
@@ -32,7 +32,7 @@
.\"
.\" @(#)id.1 8.2 (Berkeley) 5/5/94
.\"
-.Dd May 5, 1994
+.Dd June 12, 2006
.Dt ID 1
.Os
.Sh NAME
@@ -51,6 +51,9 @@
.Fl p
.Op Ar user
.Nm
+.Fl s Op Fl n
+.Ar group
+.Nm
.Fl u Op Fl nr
.Op Ar user
.Sh DESCRIPTION
@@ -105,6 +108,11 @@
and
.Fl u
options instead of the effective ID.
+.It Fl s
+Display the users that are listed as members of the given group (ie
+supplementary group membership).
+Note that this does not list users that have the given group as their prim=
ary
+group.
.It Fl u
Display the effective user ID as a number.
.El
Index: id.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/id/id.c,v
retrieving revision 1.27
diff -b -u -r1.27 id.c
--- id.c 7 Jun 2006 13:09:56 -0000 1.27
+++ id.c 17 Jun 2006 22:18:45 -0000
@@ -55,9 +55,11 @@
static void current(void);
static void pretty(struct passwd *);
static void group(struct passwd *, int);
+static void sgroup(struct group *, int);
static void usage(void);
static void user(struct passwd *);
static struct passwd *who(char *);
+static struct group *gwho(char *);
=20
static int maxgroups;
static gid_t *groups;
@@ -68,9 +70,12 @@
struct group *gr;
struct passwd *pw;
int ch, id;
- int Gflag, gflag, nflag, pflag, rflag, uflag;
+ int Gflag, gflag, nflag, pflag, rflag, sflag, uflag;
=20
- Gflag =3D gflag =3D nflag =3D pflag =3D rflag =3D uflag =3D 0;
+ Gflag =3D gflag =3D nflag =3D pflag =3D rflag =3D sflag =3D uflag =3D 0;
+
+ gr =3D NULL;
+ pw =3D NULL;
=20
if (strcmp(getprogname(), "groups") =3D=3D 0) {
Gflag =3D 1;
@@ -80,7 +85,7 @@
nflag =3D 1;
}
=20
- while ((ch =3D getopt(argc, argv, "Ggnpru")) !=3D -1)
+ while ((ch =3D getopt(argc, argv, "Ggnprsu")) !=3D -1)
switch (ch) {
case 'G':
Gflag =3D 1;
@@ -97,6 +102,9 @@
case 'r':
rflag =3D 1;
break;
+ case 's':
+ sflag =3D 1;
+ break;
case 'u':
uflag =3D 1;
break;
@@ -107,7 +115,7 @@
argc -=3D optind;
argv +=3D optind;
=20
- switch (Gflag + gflag + pflag + uflag) {
+ switch (Gflag + gflag + pflag + uflag + sflag) {
case 1:
break;
case 0:
@@ -118,6 +126,9 @@
usage();
}
=20
+ if (sflag)
+ gr =3D gwho(*argv);
+ else
pw =3D *argv ? who(*argv) : NULL;
=20
maxgroups =3D sysconf(_SC_NGROUPS_MAX);
@@ -152,6 +163,11 @@
goto done;
}
=20
+ if (sflag) {
+ sgroup(gr, nflag);
+ goto done;
+ }
+
if (pw)
user(pw);
else
@@ -318,6 +334,62 @@
free(glist);
}
=20
+static void
+sgroup(struct group *gr, int nflag)
+{
+ char **gr_mem;
+ struct passwd *pw;
+ int cnt;
+
+ cnt =3D 0;
+
+ for ((gr_mem =3D gr->gr_mem); *gr_mem; ) {
+ cnt++;
+ if (!nflag) {
+ if ((pw =3D getpwnam(*gr_mem)) =3D=3D NULL) {
+ warnx("Nonexistent user '%s' in group '%s'",
+ *gr_mem, gr->gr_name);
+ gr_mem++;
+ continue;
+ }
+
+ (void)printf("%u", pw->pw_uid);
+ =09
+ } else=20
+ (void)printf("%s", *gr_mem);
+
+ if (*++gr_mem)
+ (void)printf(" ");
+ }
+ if (cnt)
+ (void)printf("\n");
+}
+
+static struct group *
+gwho(char *g)
+{
+ struct group *gr;
+ long id;
+ char *ep;
+
+ if (!g)
+ usage();
+ /* NOTREACHED */
+
+ /*
+ * Translate user argument into a gr pointer. First, try to
+ * get it as specified. If that fails, try it as a number.
+ */
+ if ((gr =3D getgrnam(g)) !=3D NULL)
+ return gr;
+ id =3D strtol(g, &ep, 10);
+ if (*g && !*ep && (gr =3D getgrgid(id)))
+ return gr;
+ errx(1, "%s: No such group", g);
+ /* NOTREACHED */
+ return NULL;
+}
+
static struct passwd *
who(char *u)
{
@@ -353,6 +425,7 @@
(void)fprintf(stderr, " id -g [-nr] [user]\n");
(void)fprintf(stderr, " id -p [user]\n");
(void)fprintf(stderr, " id -u [-nr] [user]\n");
+ (void)fprintf(stderr, " id -s [-n] group\n");
}
exit(1);
}
--tEFtbjk+mNEviIIX--
--8vCeF2GUdMpe9ZbK
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (NetBSD)
iD8DBQFElIRLfFtkr68iakwRAmFBAJ9u5Ip7KGnRJ0MmV/2oT9QpVBi2TwCgqyQH
XDnPY1hvImzbFsJhGOMXMcg=
=pRqc
-----END PGP SIGNATURE-----
--8vCeF2GUdMpe9ZbK--