aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/test.c20
-rw-r--r--include/libbb.h5
-rw-r--r--libbb/bb_getgroups.c20
3 files changed, 26 insertions, 19 deletions
diff --git a/coreutils/test.c b/coreutils/test.c
index c02c92745..874285704 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -637,32 +637,14 @@ static int binop(void)
637 /*return 1; - NOTREACHED */ 637 /*return 1; - NOTREACHED */
638} 638}
639 639
640static void initialize_group_array(void)
641{
642 group_array = bb_getgroups(&ngroups, NULL);
643}
644
645/* Return non-zero if GID is one that we have in our groups list. */ 640/* Return non-zero if GID is one that we have in our groups list. */
646//XXX: FIXME: duplicate of existing libbb function?
647// see toplevel TODO file:
648// possible code duplication ingroup() and is_a_group_member()
649static int is_a_group_member(gid_t gid) 641static int is_a_group_member(gid_t gid)
650{ 642{
651 int i;
652
653 /* Short-circuit if possible, maybe saving a call to getgroups(). */ 643 /* Short-circuit if possible, maybe saving a call to getgroups(). */
654 if (gid == getgid() || gid == getegid()) 644 if (gid == getgid() || gid == getegid())
655 return 1; 645 return 1;
656 646
657 if (ngroups == 0) 647 return is_in_supplementary_groups(&ngroups, &group_array, gid);
658 initialize_group_array();
659
660 /* Search through the list looking for GID. */
661 for (i = 0; i < ngroups; i++)
662 if (gid == group_array[i])
663 return 1;
664
665 return 0;
666} 648}
667 649
668/* 650/*
diff --git a/include/libbb.h b/include/libbb.h
index 67e7bf7b9..e06aef08e 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1201,6 +1201,11 @@ void die_if_bad_username(const char* name) FAST_FUNC;
1201 * Dies on errors (on Linux, only xrealloc can cause this, not internal getgroups call). 1201 * Dies on errors (on Linux, only xrealloc can cause this, not internal getgroups call).
1202 */ 1202 */
1203gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC; 1203gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC;
1204/*
1205 * True if GID is in our getgroups() result.
1206 * getgroups() is cached in group_array[], to makse successive calls faster.
1207 */
1208int FAST_FUNC is_in_supplementary_groups(int *pngroups, gid_t **pgroup_array, gid_t gid);
1204 1209
1205#if ENABLE_FEATURE_UTMP 1210#if ENABLE_FEATURE_UTMP
1206void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); 1211void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
diff --git a/libbb/bb_getgroups.c b/libbb/bb_getgroups.c
index 5d83c729a..f030d5eac 100644
--- a/libbb/bb_getgroups.c
+++ b/libbb/bb_getgroups.c
@@ -45,3 +45,23 @@ gid_t* FAST_FUNC bb_getgroups(int *ngroups, gid_t *group_array)
45 *ngroups = n; 45 *ngroups = n;
46 return group_array; 46 return group_array;
47} 47}
48
49/* Return non-zero if GID is in our supplementary group list. */
50int FAST_FUNC is_in_supplementary_groups(int *pngroups, gid_t **pgroup_array, gid_t gid)
51{
52 int i;
53 int ngroups;
54 gid_t *group_array;
55
56 if (*pngroups == 0)
57 *pgroup_array = bb_getgroups(pngroups, NULL);
58 ngroups = *pngroups;
59 group_array = *pgroup_array;
60
61 /* Search through the list looking for GID. */
62 for (i = 0; i < ngroups; i++)
63 if (gid == group_array[i])
64 return 1;
65
66 return 0;
67}