From 533a78f02c3117da84337aee2bcdc52adf072919 Mon Sep 17 00:00:00 2001 From: dtucker Date: Thu, 28 Feb 2008 12:16:04 +0000 Subject: [PATCH] - (dtucker) [configure.ac openbsd-compat/port-aix.{c,h}] Bug #1081: Implement getgrouplist via getgrset on AIX, rather than iterating over getgrent. This allows, eg, Match and AllowGroups directives to work with NIS and LDAP groups. --- ChangeLog | 4 +++ configure.ac | 2 +- openbsd-compat/port-aix.c | 56 ++++++++++++++++++++++++++++++++++++++- openbsd-compat/port-aix.h | 14 +++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2007e87..376d8a82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ SSLeay_add_all_algorithms as a macro already. - (dtucker) [key.c defines.h openbsd-compat/openssl-compat.h] Move old OpenSSL compat glue into openssl-compat.h. + - (dtucker) [configure.ac openbsd-compat/port-aix.{c,h}] Bug #1081: Implement + getgrouplist via getgrset on AIX, rather than iterating over getgrent. + This allows, eg, Match and AllowGroups directives to work with NIS and + LDAP groups. 20080225 - (dtucker) [openbsd-compat/fake-rfc2553.h] rename ssh_gai_strerror hack diff --git a/configure.ac b/configure.ac index 2f6c7ebb..8b2d152d 100644 --- a/configure.ac +++ b/configure.ac @@ -357,7 +357,7 @@ int main(void) { exit(0); } [], [#include ] ) - AC_CHECK_FUNCS(setauthdb) + AC_CHECK_FUNCS(getgrset setauthdb) AC_CHECK_DECL(F_CLOSEM, AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]), [], diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index 94faec67..b19d2296 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -1,7 +1,7 @@ /* * * Copyright (c) 2001 Gert Doering. All rights reserved. - * Copyright (c) 2003,2004,2005 Darren Tucker. All rights reserved. + * Copyright (c) 2003,2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -394,4 +394,58 @@ sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, } # endif /* AIX_GETNAMEINFO_HACK */ +# if defined(USE_GETGRSET) +# include +int +getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt) +{ + char *cp, *grplist, *grp; + gid_t gid; + int ret = 0, ngroups = 0, maxgroups; + long l; + + maxgroups = *grpcnt; + + if ((cp = grplist = getgrset(user)) == NULL) + return -1; + + /* handle zero-length case */ + if (maxgroups <= 0) { + *grpcnt = 0; + return -1; + } + + /* copy primary group */ + groups[ngroups++] = pgid; + + /* copy each entry from getgrset into group list */ + while ((grp = strsep(&grplist, ",")) != NULL) { + l = strtol(grp, NULL, 10); + if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { + ret = -1; + goto out; + } + gid = (gid_t)l; + if (gid == pgid) + continue; /* we have already added primary gid */ + groups[ngroups++] = gid; + } +out: + free(cp); + *grpcnt = ngroups; + return ret; +} + +int +ssh_initgroups(const char *user, gid_t group) +{ + gid_t grps[NGROUPS_MAX]; + int grpcnt = NGROUPS_MAX; + + if (getgrouplist(user, group, grps, &grpcnt) == -1) + return -1; + return setgroups(grpcnt, grps); +} +# endif /* USE_GETGRSET */ + #endif /* _AIX */ diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index eae82a9e..cd1c2c2e 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -3,7 +3,7 @@ /* * * Copyright (c) 2001 Gert Doering. All rights reserved. - * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * Copyright (c) 2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -103,4 +103,16 @@ int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) #endif +/* + * We use getgrset in preference to multiple getgrent calls for efficiency + * plus it supports NIS and LDAP groups. + */ +#if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET) +# define HAVE_GETGROUPLIST +# define USE_GETGRSET +int getgrouplist(const char *, gid_t, gid_t *, int *); +int ssh_initgroups(const char *, gid_t); +# define initgroups(a, b) ssh_initgroups((a), (b)) +#endif + #endif /* _AIX */ -- 2.45.2