mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Red Hat issue 1021429: getgroupent fails with large number of groups
This commit is contained in:
parent
d123461127
commit
1d8b6bbb9b
10 changed files with 82 additions and 13 deletions
4
CHANGES
4
CHANGES
|
@ -148,6 +148,10 @@ porting:
|
|||
|
||||
Adapted, improved test.sh script
|
||||
|
||||
Red Hat issue 1021429: getgroupent fails with large number of groups;
|
||||
use getgrouplist() when available instead of sequence of calls to
|
||||
getgrent()
|
||||
|
||||
libwrap always logs to syslog
|
||||
|
||||
added actual text version of GPLv2
|
||||
|
|
5
README
5
README
|
@ -132,6 +132,11 @@ the file PORTING.
|
|||
platform specifics - redhat
|
||||
---------------------------
|
||||
|
||||
Install the following packages before building socat:
|
||||
tcp_wrappers-devel
|
||||
readline-devel
|
||||
openssl-devel
|
||||
|
||||
On RedHat Linux 9.0, including openssl/ssl.h might fail due to problems with
|
||||
the krb5-devel package. configure reacts with disabling openssl integration.
|
||||
To solve this issue, help cpp to find the krb5.h include file:
|
||||
|
|
|
@ -498,6 +498,7 @@
|
|||
#undef HAVE_SETGRENT
|
||||
#undef HAVE_GETGRENT
|
||||
#undef HAVE_ENDGRENT
|
||||
#undef HAVE_GETGROUPLIST
|
||||
|
||||
#undef WITH_HELP
|
||||
#undef WITH_NOP
|
||||
|
|
|
@ -82,6 +82,8 @@ AC_CHECK_HEADERS(linux/fs.h linux/ext2_fs.h)
|
|||
|
||||
dnl Checks for setgrent, getgrent and endgrent.
|
||||
AC_CHECK_FUNCS(setgrent getgrent endgrent)
|
||||
dnl Checks for getgrouplist() /* BSD */
|
||||
AC_CHECK_FUNCS(getgrouplist)
|
||||
|
||||
dnl Link libresolv if necessary (for Mac OS X)
|
||||
AC_SEARCH_LIBS([res_9_init], [resolv])
|
||||
|
|
24
sycls.c
24
sycls.c
|
@ -1,5 +1,5 @@
|
|||
/* source: sycls.c */
|
||||
/* Copyright Gerhard Rieger 2001-2012 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* explicit system call and C library trace function, for those who miss strace
|
||||
|
@ -276,7 +276,12 @@ int Getgroups(int size, gid_t list[]) {
|
|||
#if HAVE_SETGROUPS
|
||||
int Setgroups(size_t size, const gid_t *list) {
|
||||
int result, _errno;
|
||||
Debug2("setgroups("F_Zu", "F_gid",...)", size, list[0]);
|
||||
switch (size) {
|
||||
case 0: Debug1("setgroups("F_Zu", [])", size); break;;
|
||||
case 1: Debug2("setgroups("F_Zu", ["F_gid"])", size, list[0]); break;;
|
||||
case 2: Debug3("setgroups("F_Zu", ["F_gid","F_gid"])", size, list[0], list[1]); break;;
|
||||
default: Debug3("setgroups("F_Zu", ["F_gid","F_gid",...])", size, list[0], list[1]); break;;
|
||||
}
|
||||
result = setgroups(size, list);
|
||||
_errno = errno;
|
||||
Debug1("setgroups() -> %d", result);
|
||||
|
@ -285,6 +290,21 @@ int Setgroups(size_t size, const gid_t *list) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_GETGROUPLIST
|
||||
int Getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups) {
|
||||
int n = *ngroups, result;
|
||||
Debug4("getgrouplist(\"%s\", "F_gid", %p, [%d])", user, group, groups, n);
|
||||
result = getgrouplist(user, group, groups, ngroups);
|
||||
switch (Min(n,*ngroups)) {
|
||||
case 0: Debug2("getgrouplist(,, [], [%d]) -> %d", *ngroups, result); break;
|
||||
case 1: Debug3("getgrouplist(,, ["F_gid"], [%d]) -> %d", groups[0], *ngroups, result); break;
|
||||
case 2: Debug4("getgrouplist(,, ["F_gid","F_gid"], [%d]) -> %d", groups[0], groups[1], *ngroups, result); break;
|
||||
default: Debug4("getgrouplist(,, ["F_gid","F_gid",...], [%d]) -> %d", groups[0], groups[1], *ngroups, result); break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
int Chdir(const char *path) {
|
||||
int result, _errno;
|
||||
Debug1("chdir(\"%s\")", path);
|
||||
|
|
4
sycls.h
4
sycls.h
|
@ -1,5 +1,5 @@
|
|||
/* source: sycls.h */
|
||||
/* Copyright Gerhard Rieger 2001-2008 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __sycls_h_included
|
||||
|
@ -37,6 +37,7 @@ int Setgid(gid_t gid);
|
|||
int Initgroups(const char *user, gid_t group);
|
||||
int Getgroups(int size, gid_t list[]);
|
||||
int Setgroups(size_t size, const gid_t *list);
|
||||
int Getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
|
||||
int Chdir(const char *path);
|
||||
int Chroot(const char *path);
|
||||
int Gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
|
@ -187,6 +188,7 @@ int Gzclose(gzFile file) {
|
|||
#define Initgroups(u,g) initgroups(u,g)
|
||||
#define Getgroups(s,l) getgroups(s,l)
|
||||
#define Setgroups(s,l) setgroups(s,l)
|
||||
#define Getgrouplist(u,g,gs,n) getgrouplist(u,g,gs,n)
|
||||
#define Chdir(p) chdir(p)
|
||||
#define Chroot(p) chroot(p)
|
||||
#define Gettimeofday(tv,tz) gettimeofday(tv,tz)
|
||||
|
|
43
sysutils.c
43
sysutils.c
|
@ -413,15 +413,49 @@ char *sockaddr_inet6_info(const struct sockaddr_in6 *sa, char *buff, size_t blen
|
|||
}
|
||||
#endif /* WITH_IP6 */
|
||||
|
||||
#if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
|
||||
/* fill the list with the supplementary group ids of user.
|
||||
#if HAVE_GETGROUPLIST || (defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT))
|
||||
/* fills the list with the supplementary group ids of user.
|
||||
caller passes size of list in ngroups, function returns number of groups in
|
||||
ngroups.
|
||||
function returns 0 if 0 or more groups were found, or 1 if the list is too
|
||||
short. */
|
||||
int getusergroups(const char *user, gid_t *list, size_t *ngroups) {
|
||||
int getusergroups(const char *user, gid_t *list, int *ngroups) {
|
||||
#if HAVE_GETGROUPLIST
|
||||
/* we prefer getgrouplist because it may be much faster with many groups, but it is not standard */
|
||||
gid_t grp, twogrps[2];
|
||||
int two = 2;
|
||||
/* getgrouplist requires to pass an extra group id, typically the users primary group, that is then added to the supplementary group list. We don't want such an additional group in the result, but there is not "unspecified" gid value available. Thus we try to find an abitrary supplementary group id that we then pass in a second call to getgrouplist. */
|
||||
grp = 0;
|
||||
Getgrouplist(user, grp, twogrps, &two);
|
||||
if (two == 1) {
|
||||
/* either user has just this supp group, or none; we try another id */
|
||||
grp = 1; two = 2;
|
||||
Getgrouplist(user, grp, twogrps, &two);
|
||||
if (two == 1) {
|
||||
/* user has no supp group */
|
||||
*ngroups = 0;
|
||||
return 0;
|
||||
}
|
||||
/* user has just the first tried group */
|
||||
*ngroups = 1; list[0] = grp;
|
||||
return 0;
|
||||
}
|
||||
/* find the first supp group that is not our grp, and use its id */
|
||||
if (twogrps[0] == grp) {
|
||||
grp = twogrps[1];
|
||||
} else {
|
||||
grp = twogrps[0];
|
||||
}
|
||||
if (Getgrouplist(user, grp, list, ngroups) < 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#elif defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
|
||||
/* this is standard (POSIX) but may be slow */
|
||||
|
||||
struct group *grp;
|
||||
size_t i = 0;
|
||||
int i = 0;
|
||||
|
||||
setgrent();
|
||||
while (grp = getgrent()) {
|
||||
|
@ -439,6 +473,7 @@ int getusergroups(const char *user, gid_t *list, size_t *ngroups) {
|
|||
endgrent();
|
||||
*ngroups = i;
|
||||
return 0;
|
||||
#endif /* HAVE_SETGRENT... */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: sysutils.h */
|
||||
/* Copyright Gerhard Rieger 2001-2012 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __sysutils_h_included
|
||||
|
@ -75,7 +75,7 @@ extern const char *inet_ntop(int pf, const void *binaddr,
|
|||
#endif
|
||||
|
||||
#if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
|
||||
extern int getusergroups(const char *user, gid_t *list, size_t *ngroups);
|
||||
extern int getusergroups(const char *user, gid_t *list, int *ngroups);
|
||||
#endif
|
||||
|
||||
#if !HAVE_HSTRERROR
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: xio-process.c */
|
||||
/* Copyright Gerhard Rieger 2001-2012 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file handles process related addresses options */
|
||||
|
@ -30,7 +30,7 @@ bool delayeduser = false;
|
|||
uid_t delayeduser_uid; /* numeric user id to switch to */
|
||||
gid_t delayeduser_gid; /* numeric group id to switch to */
|
||||
gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */
|
||||
size_t delayeduser_ngids; /* number of suppl. gids */
|
||||
int delayeduser_ngids; /* number of suppl. gids */
|
||||
char *delayeduser_name; /* name of user to switch to */
|
||||
char *delayeduser_dir; /* home directory of user to switch to */
|
||||
char *delayeduser_shell; /* login shell of user to switch to */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: xio-process.h */
|
||||
/* Copyright Gerhard Rieger 2001-2012 */
|
||||
/* Copyright Gerhard Rieger */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __xio_process_h_included
|
||||
|
@ -24,7 +24,7 @@ extern bool delayeduser;
|
|||
extern uid_t delayeduser_uid; /* numeric user id to switch to */
|
||||
extern gid_t delayeduser_gid; /* numeric group id to switch to */
|
||||
extern gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */
|
||||
extern size_t delayeduser_ngids; /* number of suppl. gids */
|
||||
extern int delayeduser_ngids; /* number of suppl. gids */
|
||||
extern char *delayeduser_name; /* name of user to switch to */
|
||||
extern char *delayeduser_dir; /* home directory of user to switch to */
|
||||
extern char *delayeduser_shell; /* login shell of user to switch to */
|
||||
|
|
Loading…
Reference in a new issue