mirror of
https://repo.or.cz/socat.git
synced 2024-12-23 07:52:32 +00:00
Red Hat issue 1021429: getgroupent fails with large number of groups
This commit is contained in:
parent
ab74be65e5
commit
52e8a5ec2b
10 changed files with 83 additions and 14 deletions
4
CHANGES
4
CHANGES
|
@ -58,6 +58,10 @@ porting:
|
||||||
|
|
||||||
Adapted, improved test.sh script
|
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()
|
||||||
|
|
||||||
docu:
|
docu:
|
||||||
libwrap always logs to syslog
|
libwrap always logs to syslog
|
||||||
|
|
||||||
|
|
5
README
5
README
|
@ -132,6 +132,11 @@ the file PORTING.
|
||||||
platform specifics - redhat
|
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
|
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.
|
the krb5-devel package. configure reacts with disabling openssl integration.
|
||||||
To solve this issue, help cpp to find the krb5.h include file:
|
To solve this issue, help cpp to find the krb5.h include file:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: config.h.in */
|
/* source: config.h.in */
|
||||||
/* Copyright Gerhard Rieger 2001-2011 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __config_h_included
|
#ifndef __config_h_included
|
||||||
|
@ -498,6 +498,7 @@
|
||||||
#undef HAVE_SETGRENT
|
#undef HAVE_SETGRENT
|
||||||
#undef HAVE_GETGRENT
|
#undef HAVE_GETGRENT
|
||||||
#undef HAVE_ENDGRENT
|
#undef HAVE_ENDGRENT
|
||||||
|
#undef HAVE_GETGROUPLIST
|
||||||
|
|
||||||
#undef WITH_HELP
|
#undef WITH_HELP
|
||||||
#undef WITH_STDIO
|
#undef WITH_STDIO
|
||||||
|
|
|
@ -82,6 +82,8 @@ AC_CHECK_HEADERS(linux/fs.h linux/ext2_fs.h)
|
||||||
|
|
||||||
dnl Checks for setgrent, getgrent and endgrent.
|
dnl Checks for setgrent, getgrent and endgrent.
|
||||||
AC_CHECK_FUNCS(setgrent getgrent 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)
|
dnl Link libresolv if necessary (for Mac OS X)
|
||||||
AC_SEARCH_LIBS([res_9_init], [resolv])
|
AC_SEARCH_LIBS([res_9_init], [resolv])
|
||||||
|
|
24
sycls.c
24
sycls.c
|
@ -1,5 +1,5 @@
|
||||||
/* source: sycls.c */
|
/* source: sycls.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2009 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* 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
|
/* 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
|
#if HAVE_SETGROUPS
|
||||||
int Setgroups(size_t size, const gid_t *list) {
|
int Setgroups(size_t size, const gid_t *list) {
|
||||||
int result, _errno;
|
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);
|
result = setgroups(size, list);
|
||||||
_errno = errno;
|
_errno = errno;
|
||||||
Debug1("setgroups() -> %d", result);
|
Debug1("setgroups() -> %d", result);
|
||||||
|
@ -285,6 +290,21 @@ int Setgroups(size_t size, const gid_t *list) {
|
||||||
}
|
}
|
||||||
#endif
|
#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 Chdir(const char *path) {
|
||||||
int result, _errno;
|
int result, _errno;
|
||||||
Debug1("chdir(\"%s\")", path);
|
Debug1("chdir(\"%s\")", path);
|
||||||
|
|
4
sycls.h
4
sycls.h
|
@ -1,5 +1,5 @@
|
||||||
/* source: sycls.h */
|
/* source: sycls.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2008 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __sycls_h_included
|
#ifndef __sycls_h_included
|
||||||
|
@ -37,6 +37,7 @@ int Setgid(gid_t gid);
|
||||||
int Initgroups(const char *user, gid_t group);
|
int Initgroups(const char *user, gid_t group);
|
||||||
int Getgroups(int size, gid_t list[]);
|
int Getgroups(int size, gid_t list[]);
|
||||||
int Setgroups(size_t size, const 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 Chdir(const char *path);
|
||||||
int Chroot(const char *path);
|
int Chroot(const char *path);
|
||||||
int Gettimeofday(struct timeval *tv, struct timezone *tz);
|
int Gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||||
|
@ -175,6 +176,7 @@ void Add_history(const char *string);
|
||||||
#define Initgroups(u,g) initgroups(u,g)
|
#define Initgroups(u,g) initgroups(u,g)
|
||||||
#define Getgroups(s,l) getgroups(s,l)
|
#define Getgroups(s,l) getgroups(s,l)
|
||||||
#define Setgroups(s,l) setgroups(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 Chdir(p) chdir(p)
|
||||||
#define Chroot(p) chroot(p)
|
#define Chroot(p) chroot(p)
|
||||||
#define Gettimeofday(tv,tz) gettimeofday(tv,tz)
|
#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 */
|
#endif /* WITH_IP6 */
|
||||||
|
|
||||||
#if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
|
#if HAVE_GETGROUPLIST || (defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT))
|
||||||
/* fill the list with the supplementary group ids of user.
|
/* fills the list with the supplementary group ids of user.
|
||||||
caller passes size of list in ngroups, function returns number of groups in
|
caller passes size of list in ngroups, function returns number of groups in
|
||||||
ngroups.
|
ngroups.
|
||||||
function returns 0 if 0 or more groups were found, or 1 if the list is too
|
function returns 0 if 0 or more groups were found, or 1 if the list is too
|
||||||
short. */
|
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;
|
struct group *grp;
|
||||||
size_t i = 0;
|
int i = 0;
|
||||||
|
|
||||||
setgrent();
|
setgrent();
|
||||||
while (grp = getgrent()) {
|
while (grp = getgrent()) {
|
||||||
|
@ -439,6 +473,7 @@ int getusergroups(const char *user, gid_t *list, size_t *ngroups) {
|
||||||
endgrent();
|
endgrent();
|
||||||
*ngroups = i;
|
*ngroups = i;
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif /* HAVE_SETGRENT... */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: sysutils.h */
|
/* source: sysutils.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2011 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __sysutils_h_included
|
#ifndef __sysutils_h_included
|
||||||
|
@ -74,7 +74,7 @@ extern const char *inet_ntop(int pf, const void *binaddr,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SETGRENT) && defined(HAVE_GETGRENT) && defined(HAVE_ENDGRENT)
|
#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
|
#endif
|
||||||
|
|
||||||
#if !HAVE_HSTRERROR
|
#if !HAVE_HSTRERROR
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: xio-process.c */
|
/* source: xio-process.c */
|
||||||
/* Copyright Gerhard Rieger 2001-2009 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
/* this file handles process related addresses options */
|
/* this file handles process related addresses options */
|
||||||
|
@ -30,7 +30,7 @@ bool delayeduser = false;
|
||||||
uid_t delayeduser_uid; /* numeric user id to switch to */
|
uid_t delayeduser_uid; /* numeric user id to switch to */
|
||||||
gid_t delayeduser_gid; /* numeric group id to switch to */
|
gid_t delayeduser_gid; /* numeric group id to switch to */
|
||||||
gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */
|
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_name; /* name of user to switch to */
|
||||||
char *delayeduser_dir; /* home directory 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 */
|
char *delayeduser_shell; /* login shell of user to switch to */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* source: xio-process.h */
|
/* source: xio-process.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2009 */
|
/* Copyright Gerhard Rieger */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __xio_process_h_included
|
#ifndef __xio_process_h_included
|
||||||
|
@ -24,7 +24,7 @@ extern bool delayeduser;
|
||||||
extern uid_t delayeduser_uid; /* numeric user id to switch to */
|
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_gid; /* numeric group id to switch to */
|
||||||
extern gid_t delayeduser_gids[NGROUPS]; /* num.supplementary group ids */
|
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_name; /* name of user to switch to */
|
||||||
extern char *delayeduser_dir; /* home directory 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 */
|
extern char *delayeduser_shell; /* login shell of user to switch to */
|
||||||
|
|
Loading…
Reference in a new issue