diff options
-rw-r--r-- | coreutils/test.c | 20 | ||||
-rw-r--r-- | include/libbb.h | 5 | ||||
-rw-r--r-- | libbb/bb_getgroups.c | 20 |
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 | ||
640 | static 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() | ||
649 | static int is_a_group_member(gid_t gid) | 641 | static 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 | */ |
1203 | gid_t *bb_getgroups(int *ngroups, gid_t *group_array) FAST_FUNC; | 1203 | gid_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 | */ | ||
1208 | int 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 |
1206 | void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname); | 1211 | void 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. */ | ||
50 | int 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 | } | ||