diff --git a/MANIFEST b/MANIFEST index b320aabe9..2addbc633 100644 --- a/MANIFEST +++ b/MANIFEST @@ -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 diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index 40f759bf5..8aaf40a73 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -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 $@ diff --git a/plugins/sudoers/pwutil_impl.c b/plugins/sudoers/pwutil_impl.c index 199cb5e71..ab2cb2e38 100644 --- a/plugins/sudoers/pwutil_impl.c +++ b/plugins/sudoers/pwutil_impl.c @@ -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; diff --git a/plugins/sudoers/testsudoers_pwutil.c b/plugins/sudoers/testsudoers_pwutil.c index 759b23f22..bc64d30f7 100644 --- a/plugins/sudoers/testsudoers_pwutil.c +++ b/plugins/sudoers/testsudoers_pwutil.c @@ -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" diff --git a/plugins/sudoers/testsudoers_pwutil.h b/plugins/sudoers/testsudoers_pwutil.h new file mode 100644 index 000000000..d50527734 --- /dev/null +++ b/plugins/sudoers/testsudoers_pwutil.h @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2023 Todd C. Miller + * + * 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 + +#include +#include + +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 */ diff --git a/plugins/sudoers/tsgetgrpw.c b/plugins/sudoers/tsgetgrpw.c index f9843ace0..435c7dd06 100644 --- a/plugins/sudoers/tsgetgrpw.c +++ b/plugins/sudoers/tsgetgrpw.c @@ -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; diff --git a/plugins/sudoers/tsgetgrpw.h b/plugins/sudoers/tsgetgrpw.h index 7662e02f9..0a649670b 100644 --- a/plugins/sudoers/tsgetgrpw.h +++ b/plugins/sudoers/tsgetgrpw.h @@ -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);