Skip to content

Commit

Permalink
mod_authz_unixgroup: Use getgrouplist() instead of gr_mem for sssd co…
Browse files Browse the repository at this point in the history
…mpatibility

Some services, like sssd, can optimize away grp->gr_mem which makes this
module fail group lookup.

Use getgrouplist(3) instead and gid_from_group(3bsd) which uses libbsd,
link with -lbsd.
This avoids the problematic getgrgid()/getgrnam() functions.
  • Loading branch information
joakim-tjernlund authored and bimimicah committed Nov 23, 2024
1 parent 4c97c04 commit e430131
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 16 deletions.
21 changes: 13 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,29 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: install apache (ubuntu)
- name: install apache and libbsd (ubuntu)
if: runner.os == 'Linux'
run: sudo apt-get install apache2 apache2-dev
- name: install apache (macos)
run: sudo apt-get install apache2 apache2-dev libbsd-dev

- name: install apache and libbsd (macos)
if: runner.os == 'macOS'
run: brew install httpd

run: |
# use latest master, not stable (until libbsd mac version is in stable)
brew developer on
# grab master version of libbsd with mac support
brew update
brew install httpd libbsd
- name: make mod_authnz_external (POSIX-GCC)
if: runner.os != 'Windows'
run: make
working-directory: ./mod_authnz_external

- name: make mod_authz_unixgroup (POSIX-GCC)
if: runner.os != 'Windows'
run: make
working-directory: ./mod_authz_unixgroup

- name: nmake (MSVC)
if: runner.os == 'Windows'
run: |
Expand Down
1 change: 1 addition & 0 deletions mod_authz_unixgroup/CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ mod_authz_unixgroup is based on code from the following sources:
David Homborg
klemens/ka7
Micah Andersen/Baptist International Missions, Inc. ([email protected])
Joakim Tjernlund/joakim-tjernlund ([email protected])
15 changes: 10 additions & 5 deletions mod_authz_unixgroup/INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,17 @@ Step 2:
Compile the module using the following command in the
mod_authz_unixgroup distribution directory:

apxs -c mod_authz_unixgroup.c
apxs -c mod_authz_unixgroup.c -lbsd

'Apxs' is the Apache extension tool. It is part of the standard
Apache installation. If you don't have it, then your Apache server
is probably not set up for handling dynamically loaded modules.
This should create a file named 'mod_authz_unixgroup.so'.
* Build using just POSIX group interfaces:
apxs -c mod_authz_unixgroup.c -DUSE_POSIX_GRP
NOTE that some group providers (e.g sssd) can optionally omit gr_mem
in struct grp which will break POSIX API (in addition to being slower)

* 'Apxs' is the Apache extension tool. It is part of the standard
Apache installation. If you don't have it, then your Apache server
is probably not set up for handling dynamically loaded modules.
This should create a file named 'mod_authz_unixgroup.so'.

Step 3:
Install the module. Apxs can do this for you too. Do the following
Expand Down
12 changes: 10 additions & 2 deletions mod_authz_unixgroup/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#APXS=apxs2
APXS=apxs

ifneq ($(OS),Windows_NT)
OS := $(shell uname -s)
endif

TAR= README INSTALL NOTICE CHANGES CONTRIBUTORS LICENSE \
mod_authz_unixgroup.c Makefile Makefile.win

Expand All @@ -14,13 +18,17 @@ install: mod_authz_unixgroup.la
build: mod_authz_unixgroup.la

mod_authz_unixgroup.la: mod_authz_unixgroup.c
$(APXS) -c mod_authz_unixgroup.c
$(info REMINDER: This project requires libbsd and associated headers to compile and run. Please install any necessary development packages for your platform if you have not already. macOS users should install libbsd via homebrew.)
ifeq ($(OS),Darwin)
$(APXS) -I/opt/homebrew/opt/libbsd/include -c mod_authz_unixgroup.c
else
$(APXS) -c mod_authz_unixgroup.c -lbsd
endif

clean:
rm -rf mod_authz_unixgroup.so mod_authz_unixgroup.o \
mod_authz_unixgroup.la mod_authz_unixgroup.slo \
mod_authz_unixgroup.lo .libs
-ls -a .*.swp

tar: mod_authz_unixgroup.tar

Expand Down
86 changes: 85 additions & 1 deletion mod_authz_unixgroup/mod_authz_unixgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
#include <pwd.h>
#endif
#if HAVE_GRP_H
#ifdef USE_POSIX_GRP
#include <grp.h>
#else
#include <bsd/grp.h>
#endif
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h>
Expand All @@ -41,7 +45,7 @@ APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r));
* can either be unix group names or numeric group id numbers. There must
* be a unix login corresponding to the named user.
*/

#ifdef USE_POSIX_GRP
static int check_unix_group(request_rec *r, const char *grouplist)
{
char **p;
Expand Down Expand Up @@ -112,6 +116,86 @@ static int check_unix_group(request_rec *r, const char *grouplist)
if (at != NULL) *at= '@';
return 0;
}
#else
#define MAX_USER_GRPS (4*1024)
static int check_unix_group(request_rec *r, const char *grouplist)
{
char *user = r->user;
char *w, *at;
static gid_t groups[MAX_USER_GRPS], gid;
int ngroups = MAX_USER_GRPS, i;

/* Strip @ sign and anything following it from the username. Some
* authentication modules, like mod_auth_kerb like appending such
* stuff to user names, but an @ sign is never legal in a unix login
* name, so it should be safe to always discard such stuff.
*/
if ((at = strchr(user, '@')) != NULL) *at = '\0';

/* Get info about login */
struct passwd *pwd = getpwnam(user);
if (pwd == NULL)
{
/* No such user - forget it */
if (at != NULL) *at = '@';
return 0;
}

if (getgrouplist(user, pwd->pw_gid, groups, &ngroups) < 0)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"Authorization of user %s to access %s failed. "
" getgrouplist(errno:%s).",
r->user, r->uri, strerror(errno));
if (at != NULL) *at = '@';
return 0;
}
/* Loop through list of allowed groups passed in */
while (*grouplist != '\0')
{
w = ap_getword_conf(r->pool, &grouplist);
if (apr_isdigit(w[0]))
{
/* Numeric group id */
gid = atoi(w);
}
else
{
/* Get gid and list of group members for group name */
/* from libbsd */
if (gid_from_group(w, &gid) < 0)
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"Authorization of user %s to access %s failed. "
" gid_from_group(errno:%s).",
r->user, r->uri, strerror(errno));
if (at != NULL) *at = '@';
return 0;
}
}
/* Check if the user's primary group matches allowed group(s) */
if (gid == pwd->pw_gid)
{
if (at != NULL) *at = '@';
return 1;
}

/* Walk through list of user's group(s), seeing if any match allowed group(s) */
for (i = 0; i < ngroups; i++)
{
if (gid == groups[i])
{
if (at != NULL) *at = '@';
return 1;
}
}
}

/* Didn't find any matches, flunk him */
if (at != NULL) *at = '@';
return 0;
}
#endif

static authz_status unixgroup_check_authorization(request_rec *r,
const char *require_args, const void *parsed_require_args)
Expand Down

0 comments on commit e430131

Please sign in to comment.