mirror of
https://github.com/sheumann/hush.git
synced 2025-01-11 08:29:54 +00:00
Use alternative code (also from BusyBox) for checking if the user is in a group, avoiding a call to getgroups(), which isn't supported.
This could actually be further simplified, since GNO doesn't really have group-based file permissions, but I'll leave that until later.
This commit is contained in:
parent
a60c64d6c7
commit
7e5a584f0c
@ -390,8 +390,6 @@ struct test_statics {
|
|||||||
/* set only by check_operator(), either to bogus struct
|
/* set only by check_operator(), either to bogus struct
|
||||||
* or points to matching operator_t struct. Never NULL. */
|
* or points to matching operator_t struct. Never NULL. */
|
||||||
const struct operator_t *last_operator;
|
const struct operator_t *last_operator;
|
||||||
gid_t *group_array;
|
|
||||||
int ngroups;
|
|
||||||
jmp_buf leaving;
|
jmp_buf leaving;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -401,8 +399,6 @@ extern struct test_statics *const test_ptr_to_statics;
|
|||||||
#define S (*test_ptr_to_statics)
|
#define S (*test_ptr_to_statics)
|
||||||
#define args (S.args )
|
#define args (S.args )
|
||||||
#define last_operator (S.last_operator)
|
#define last_operator (S.last_operator)
|
||||||
#define group_array (S.group_array )
|
|
||||||
#define ngroups (S.ngroups )
|
|
||||||
#define leaving (S.leaving )
|
#define leaving (S.leaving )
|
||||||
|
|
||||||
#define INIT_S() do { \
|
#define INIT_S() do { \
|
||||||
@ -561,46 +557,14 @@ static int binop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void initialize_group_array(void)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
/* getgroups may be expensive, try to use it only once */
|
|
||||||
ngroups = 32;
|
|
||||||
do {
|
|
||||||
/* FIXME: ash tries so hard to not die on OOM,
|
|
||||||
* and we spoil it with just one xrealloc here */
|
|
||||||
/* We realloc, because test_main can be entered repeatedly by shell.
|
|
||||||
* Testcase (ash): 'while true; do test -x some_file; done'
|
|
||||||
* and watch top. (some_file must have owner != you) */
|
|
||||||
n = ngroups;
|
|
||||||
group_array = xrealloc(group_array, n * sizeof(gid_t));
|
|
||||||
ngroups = getgroups(n, group_array);
|
|
||||||
} while (ngroups > n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return non-zero if GID is one that we have in our groups list. */
|
/* Return non-zero if GID is one that we have in our groups list. */
|
||||||
//XXX: FIXME: duplicate of existing libbb function?
|
|
||||||
// see toplevel TODO file:
|
|
||||||
// possible code duplication ingroup() and is_a_group_member()
|
|
||||||
static int is_a_group_member(gid_t gid)
|
static int is_a_group_member(gid_t gid)
|
||||||
{
|
{
|
||||||
int i;
|
/* Short-circuit if possible */
|
||||||
|
|
||||||
/* Short-circuit if possible, maybe saving a call to getgroups(). */
|
|
||||||
if (gid == getgid() || gid == getegid())
|
if (gid == getgid() || gid == getegid())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (ngroups == 0)
|
return ingroup(getuid(), gid) || ingroup(geteuid(), gid);
|
||||||
initialize_group_array();
|
|
||||||
|
|
||||||
/* Search through the list looking for GID. */
|
|
||||||
for (i = 0; i < ngroups; i++)
|
|
||||||
if (gid == group_array[i])
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -863,16 +827,6 @@ int test_main(int argc, char **argv)
|
|||||||
if (res)
|
if (res)
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
/* resetting ngroups is probably unnecessary. it will
|
|
||||||
* force a new call to getgroups(), which prevents using
|
|
||||||
* group data fetched during a previous call. but the
|
|
||||||
* only way the group data could be stale is if there's
|
|
||||||
* been an intervening call to setgroups(), and this
|
|
||||||
* isn't likely in the case of a shell. paranoia
|
|
||||||
* prevails...
|
|
||||||
*/
|
|
||||||
/*ngroups = 0; - done by INIT_S() */
|
|
||||||
|
|
||||||
argv++;
|
argv++;
|
||||||
args = argv;
|
args = argv;
|
||||||
|
|
||||||
|
@ -841,6 +841,8 @@ void die_if_bad_username(const char* name) FAST_FUNC;
|
|||||||
#define die_if_bad_username(name) ((void)(name))
|
#define die_if_bad_username(name) ((void)(name))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int ingroup(uid_t u, gid_t g);
|
||||||
|
|
||||||
#if ENABLE_FEATURE_UTMP
|
#if ENABLE_FEATURE_UTMP
|
||||||
void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
|
void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
|
||||||
void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
|
void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname);
|
||||||
|
@ -18,3 +18,18 @@ void FAST_FUNC bb_show_usage(void)
|
|||||||
{
|
{
|
||||||
xfunc_die();
|
xfunc_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if u is member of group g */
|
||||||
|
int ingroup(uid_t u, gid_t g)
|
||||||
|
{
|
||||||
|
struct group *grp = getgrgid(g);
|
||||||
|
if (grp) {
|
||||||
|
char **mem;
|
||||||
|
for (mem = grp->gr_mem; *mem; mem++) {
|
||||||
|
struct passwd *pwd = getpwnam(*mem);
|
||||||
|
if (pwd && (pwd->pw_uid == u))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user