Fix wrapping of libc getpwnam/getpwuid/getgrnam/getgrgid on NetBSD.

This commit is contained in:
Todd C. Miller
2023-07-04 14:14:07 -06:00
parent bfb6132d9c
commit f1d9063477
7 changed files with 67 additions and 24 deletions

View File

@@ -1163,6 +1163,7 @@ plugins/sudoers/sudoers_version.h
plugins/sudoers/sudoreplay.c
plugins/sudoers/testsudoers.c
plugins/sudoers/testsudoers_pwutil.c
plugins/sudoers/testsudoers_pwutil.h
plugins/sudoers/timeout.c
plugins/sudoers/timestamp.c
plugins/sudoers/timestr.c

View File

@@ -3102,8 +3102,8 @@ testsudoers_pwutil.o: $(srcdir)/testsudoers_pwutil.c $(devdir)/def_data.h \
$(srcdir)/parse.h $(srcdir)/pwutil.h \
$(srcdir)/pwutil_impl.c $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(srcdir)/tsgetgrpw.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(srcdir)/testsudoers_pwutil.h $(srcdir)/tsgetgrpw.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/testsudoers_pwutil.c
testsudoers_pwutil.i: $(srcdir)/testsudoers_pwutil.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
@@ -3115,8 +3115,8 @@ testsudoers_pwutil.i: $(srcdir)/testsudoers_pwutil.c $(devdir)/def_data.h \
$(srcdir)/parse.h $(srcdir)/pwutil.h \
$(srcdir)/pwutil_impl.c $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(srcdir)/tsgetgrpw.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(srcdir)/testsudoers_pwutil.h $(srcdir)/tsgetgrpw.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -E -o $@ $(CPPFLAGS) $<
testsudoers_pwutil.plog: testsudoers_pwutil.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/testsudoers_pwutil.c --i-file $< --output-file $@

View File

@@ -49,6 +49,20 @@
# endif
#endif /* LOGIN_NAME_MAX */
/*
* For testsudoers and cvtsudoers need to support building with a different
* function prefix and using custom getpwnam/getpwuid/getgrnam/getgrgid.
*/
#define EXPAND(p, f) p ## _ ## f
#define WRAP(p, f) EXPAND(p, f)
#ifdef PWUTIL_PREFIX
# define CALL(x) WRAP(PWUTIL_PREFIX, x)
# define PREFIX(x) WRAP(PWUTIL_PREFIX, x)
#else
# define CALL(x) x
# define PREFIX(x) WRAP(sudo, x)
#endif
#define FIELD_SIZE(src, name, size) \
do { \
if (src->name) { \
@@ -76,7 +90,7 @@ do { \
* to ENOMEM or ENOENT respectively.
*/
struct cache_item *
sudo_make_pwitem(uid_t uid, const char *name)
PREFIX(make_pwitem)(uid_t uid, const char *name)
{
char *cp;
const char *pw_shell;
@@ -89,7 +103,7 @@ sudo_make_pwitem(uid_t uid, const char *name)
debug_decl(sudo_make_pwitem, SUDOERS_DEBUG_NSS);
/* Look up by name or uid. */
pw = name ? getpwnam(name) : getpwuid(uid);
pw = name ? CALL(getpwnam)(name) : CALL(getpwuid)(uid);
if (pw == NULL) {
errno = ENOENT;
debug_return_ptr(NULL);
@@ -161,7 +175,7 @@ sudo_make_pwitem(uid_t uid, const char *name)
* to ENOMEM or ENOENT respectively.
*/
struct cache_item *
sudo_make_gritem(gid_t gid, const char *name)
PREFIX(make_gritem)(gid_t gid, const char *name)
{
char *cp;
size_t nsize, psize, total, len, nmem = 0;
@@ -170,7 +184,7 @@ sudo_make_gritem(gid_t gid, const char *name)
debug_decl(sudo_make_gritem, SUDOERS_DEBUG_NSS);
/* Look up by name or gid. */
gr = name ? getgrnam(name) : getgrgid(gid);
gr = name ? CALL(getgrnam)(name) : CALL(getgrgid)(gid);
if (gr == NULL) {
errno = ENOENT;
debug_return_ptr(NULL);
@@ -235,7 +249,7 @@ sudo_make_gritem(gid_t gid, const char *name)
* elements. Fills in datum from user_gids or from sudo_getgrouplist2(3).
*/
struct cache_item *
sudo_make_gidlist_item(const struct passwd *pw, char * const *gidstrs,
PREFIX(make_gidlist_item)(const struct passwd *pw, char * const *gidstrs,
unsigned int type)
{
char *cp;
@@ -294,11 +308,11 @@ sudo_make_gidlist_item(const struct passwd *pw, char * const *gidstrs,
debug_return_ptr(NULL);
}
/* Clamp to max_groups if insufficient space for all groups. */
if (sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1)
if (PREFIX(getgrouplist2)(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1)
ngids = sudo_user.max_groups;
} else {
gids = NULL;
if (sudo_getgrouplist2(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1) {
if (PREFIX(getgrouplist2)(pw->pw_name, pw->pw_gid, &gids, &ngids) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory");
debug_return_ptr(NULL);
@@ -356,7 +370,7 @@ sudo_make_gidlist_item(const struct passwd *pw, char * const *gidstrs,
* elements. Fills in group names from a call to sudo_get_gidlist().
*/
struct cache_item *
sudo_make_grlist_item(const struct passwd *pw, char * const *unused1)
PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
{
char *cp;
size_t groupname_len, len, ngroups, nsize, total;

View File

@@ -1,14 +1,10 @@
/* Use custom passwd/group functions with the normal pwutil_impl.c */
#define sudo_make_pwitem testsudoers_make_pwitem
#define sudo_make_gritem testsudoers_make_gritem
#define sudo_make_gidlist_item testsudoers_make_gidlist_item
#define sudo_make_grlist_item testsudoers_make_grlist_item
/*
* Build pwutil_impl.c with a function prefix of "testsudoers_" instead
* of "sudo_" and call our custom getpwnam/getpwuid/getgrnam/getgrgid.
*/
#define getpwnam testsudoers_getpwnam
#define getpwuid testsudoers_getpwuid
#define getgrnam testsudoers_getgrnam
#define getgrgid testsudoers_getgrgid
#define sudo_getgrouplist2_v1 testsudoers_getgrouplist2_v1
#define PWUTIL_PREFIX testsudoers
#include "testsudoers_pwutil.h"
#include "tsgetgrpw.h"
#include "pwutil_impl.c"

View File

@@ -0,0 +1,32 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2023 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef TESTSUDOERS_PWUTIL_H
#define TESTSUDOERS_PWUTIL_H
#include <config.h>
#include <grp.h>
#include <pwd.h>
struct cache_item *testsudoers_make_gritem(gid_t gid, const char *group);
struct cache_item *testsudoers_make_grlist_item(const struct passwd *pw, char * const *groups);
struct cache_item *testsudoers_make_gidlist_item(const struct passwd *pw, char * const *gids, unsigned int type);
struct cache_item *testsudoers_make_pwitem(uid_t uid, const char *user);
#endif /* TESTSUDOERS_PWUTIL_H */

View File

@@ -346,7 +346,7 @@ testsudoers_getgrgid(gid_t gid)
* Copied from getgrouplist.c
*/
int
testsudoers_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
testsudoers_getgrouplist2(const char *name, GETGROUPS_T basegid,
GETGROUPS_T **groupsp, int *ngroupsp)
{
GETGROUPS_T *groups = *groupsp;

View File

@@ -43,5 +43,5 @@ struct passwd *testsudoers_getpwent(void);
struct passwd *testsudoers_getpwnam(const char *);
struct passwd *testsudoers_getpwuid(uid_t);
int testsudoers_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
int testsudoers_getgrouplist2(const char *name, GETGROUPS_T basegid,
GETGROUPS_T **groupsp, int *ngroupsp);