2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

sudoers_sethost: refactor code to set host names in sudoers_context.

The sudoers_sethost() function can be shared by the sudoers plugin,
visudo, cvtsudoers and testsudoers.
This commit is contained in:
Todd C. Miller 2023-09-02 15:25:58 -06:00
parent 0c9ca88f5b
commit 956de5cbbc
10 changed files with 137 additions and 110 deletions

View File

@ -1149,6 +1149,7 @@ plugins/sudoers/regress/visudo/test9.out.ok
plugins/sudoers/regress/visudo/test9.sh
plugins/sudoers/serialize_list.c
plugins/sudoers/set_perms.c
plugins/sudoers/sethost.c
plugins/sudoers/solaris_audit.c
plugins/sudoers/solaris_audit.h
plugins/sudoers/sssd.c

View File

@ -189,22 +189,23 @@ SUDOERS_OBJS = $(AUTH_OBJS) audit.lo boottime.lo callbacks.lo check.lo \
gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
iolog_path_escapes.lo locale.lo log_client.lo logging.lo \
lookup.lo pivot.lo policy.lo prompt.lo serialize_list.lo \
set_perms.lo starttime.lo strlcpy_unesc.lo strvec_join.lo \
sudo_nss.lo sudoers.lo sudoers_ctx_free.lo timestamp.lo \
unesc_str.lo @SUDOERS_OBJS@
set_perms.lo sethost.lo starttime.lo strlcpy_unesc.lo \
strvec_join.lo sudo_nss.lo sudoers.lo sudoers_ctx_free.lo \
timestamp.lo unesc_str.lo @SUDOERS_OBJS@
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
VISUDO_OBJS = check_aliases.o editor.lo find_path.lo gc.lo goodpath.lo \
locale.lo stubs.o sudo_printf.o sudoers_ctx_free.lo visudo.o
locale.lo sethost.lo stubs.o sudo_printf.o sudoers_ctx_free.lo \
visudo.o
VISUDO_IOBJS = sudo_printf.i visudo.i
CVTSUDOERS_OBJS = b64_encode.o cvtsudoers.o cvtsudoers_json.o cvtsudoers_csv.o \
cvtsudoers_ldif.o cvtsudoers_merge.o cvtsudoers_pwutil.o \
fmtsudoers.lo fmtsudoers_cvt.lo locale.lo parse_ldif.o \
stubs.o sudo_printf.o sudoers_ctx_free.lo ldap_util.lo \
testsudoers_pwutil.o tsgetgrpw.o
sethost.lo stubs.o sudo_printf.o sudoers_ctx_free.lo \
ldap_util.lo testsudoers_pwutil.o tsgetgrpw.o
CVTSUDOERS_IOBJS = cvtsudoers.i cvtsudoers_csv.i cvtsudoers_json.i \
cvtsudoers_ldif.i cvtsudoers_merge.i cvtsudoers_pwutil.i
@ -215,8 +216,8 @@ REPLAY_IOBJS = $(REPLAY_OBJS:.o=.i)
TEST_OBJS = check_util.lo fmtsudoers.lo fmtsudoers_cvt.lo group_plugin.lo \
interfaces.lo ldap_util.lo locale.lo lookup.lo net_ifs.o \
parse_ldif.o sudo_printf.o sudoers_ctx_free.lo testsudoers.o \
testsudoers_pwutil.o tsgetgrpw.o
parse_ldif.o sethost.lo sudo_printf.o sudoers_ctx_free.lo \
testsudoers.o testsudoers_pwutil.o tsgetgrpw.o
IOBJS = $(LIBPARSESUDOERS_IOBJS) $(SUDOERS_IOBJS) $(VISUDO_IOBJS) \
$(CVTSUDOERS_IOBJS) $(REPLAY_IOBJS)
@ -258,7 +259,7 @@ CHECK_SERIALIZE_LIST_OBJS = check_serialize_list.lo serialize_list.lo \
FUZZ_POLICY_OBJS = callbacks.lo editor.lo env.lo env_pattern.lo fuzz_policy.o \
fuzz_stubs.o gc.lo iolog_path_escapes.lo locale.lo \
policy.lo serialize_list.lo strlcpy_unesc.lo \
policy.lo sethost.lo serialize_list.lo strlcpy_unesc.lo \
strvec_join.lo sudoers.lo sudoers_ctx_free.lo \
sudoers_hooks.lo
@ -2771,6 +2772,28 @@ set_perms.i: $(srcdir)/set_perms.c $(devdir)/def_data.h \
$(CC) -E -o $@ $(CPPFLAGS) $<
set_perms.plog: set_perms.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/set_perms.c --i-file $< --output-file $@
sethost.lo: $(srcdir)/sethost.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sethost.c
sethost.i: $(srcdir)/sethost.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -E -o $@ $(CPPFLAGS) $<
sethost.plog: sethost.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sethost.c --i-file $< --output-file $@
sia.lo: $(authdir)/sia.c $(authdir)/sudo_auth.h $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_eventlog.h \

View File

@ -357,7 +357,8 @@ main(int argc, char *argv[])
}
/* We may need the hostname to resolve %h escapes in include files. */
get_hostname(&ctx);
if (!sudoers_sethost(&ctx, NULL, NULL))
goto done;
do {
char *lhost = NULL, *shost = NULL;

View File

@ -107,7 +107,4 @@ struct cache_item *cvtsudoers_make_gritem(gid_t gid, const char *name);
struct cache_item *cvtsudoers_make_gidlist_item(const struct passwd *pw, int unusued1, GETGROUPS_T *unused2, char * const *unused3, unsigned int type);
struct cache_item *cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1);
/* stubs.c */
void get_hostname(struct sudoers_context *ctx);
#endif /* SUDOERS_CVTSUDOERS_H */

View File

@ -98,6 +98,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v,
const char *p, *errstr, *groups = NULL;
struct sudoers_open_info *info = v;
unsigned int flags = MODE_UPDATE_TICKET;
const char *host = NULL;
const char *remhost = NULL;
unsigned char uuid[16];
char * const *cur;
@ -464,18 +465,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v,
}
if (MATCHES(*cur, "host=")) {
CHECK(*cur, "host=");
if (ctx->user.shost != ctx->user.host)
free(ctx->user.shost);
free(ctx->user.host);
if ((ctx->user.host = strdup(*cur + sizeof("host=") - 1)) == NULL)
goto oom;
if ((p = strchr(ctx->user.host, '.')) != NULL) {
ctx->user.shost = strndup(ctx->user.host, (size_t)(p - ctx->user.host));
if (ctx->user.shost == NULL)
goto oom;
} else {
ctx->user.shost = ctx->user.host;
}
host = *cur + sizeof("host=") - 1;
continue;
}
if (MATCHES(*cur, "lines=")) {
@ -538,26 +528,14 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v,
sudo_warnx("%s", U_("group-ID not set by sudo front-end"));
goto bad;
}
if (ctx->user.host == NULL) {
if (host == NULL) {
sudo_warnx("%s", U_("host name not set by sudo front-end"));
goto bad;
}
if (ctx->runas.shost != ctx->runas.host)
free(ctx->runas.shost);
free(ctx->runas.host);
if ((ctx->runas.host = strdup(remhost ? remhost : ctx->user.host)) == NULL)
goto oom;
if ((p = strchr(ctx->runas.host, '.')) != NULL) {
ctx->runas.shost = strndup(ctx->runas.host, (size_t)(p - ctx->runas.host));
if (ctx->runas.shost == NULL)
goto oom;
} else {
ctx->runas.shost = ctx->runas.host;
}
if (ctx->user.cwd == NULL) {
if ((ctx->user.cwd = strdup("unknown")) == NULL)
goto oom;
if (!sudoers_sethost(ctx, host, remhost)) {
/* sudoers_sethost() will print a warning on error. */
goto bad;
}
if (ctx->user.tty == NULL) {
if ((ctx->user.tty = strdup("unknown")) == NULL)

87
plugins/sudoers/sethost.c Normal file
View File

@ -0,0 +1,87 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2018-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.
*/
/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sudoers.h"
/*
* Set ctx->user.host. ctx->user.shost, ctx->runas.host and ctx->runas.shost
* based on the local and remote host names. If host is NULL, the local
* host name is used. If remhost is NULL, the same value as host is used.
*/
bool
sudoers_sethost(struct sudoers_context *ctx, const char *host,
const char *remhost)
{
char *cp;
debug_decl(sudoers_sethost, SUDOERS_DEBUG_UTIL);
if (ctx->user.shost != ctx->user.host)
free(ctx->user.shost);
free(ctx->user.host);
ctx->user.host = NULL;
ctx->user.shost = NULL;
if (host == NULL)
ctx->user.host = sudo_gethostname();
else
ctx->user.host = strdup(host);
if (ctx->user.host == NULL)
goto oom;
if ((cp = strchr(ctx->user.host, '.')) != NULL) {
ctx->user.shost = strndup(ctx->user.host,
(size_t)(cp - ctx->user.host));
if (ctx->user.shost == NULL)
goto oom;
} else {
ctx->user.shost = ctx->user.host;
}
if (ctx->runas.shost != ctx->runas.host)
free(ctx->runas.shost);
free(ctx->runas.host);
ctx->runas.host = NULL;
ctx->runas.shost = NULL;
ctx->runas.host = strdup(remhost ? remhost : ctx->user.host);
if (ctx->runas.host == NULL)
goto oom;
if ((cp = strchr(ctx->runas.host, '.')) != NULL) {
ctx->runas.shost = strndup(ctx->runas.host,
(size_t)(cp - ctx->runas.host));
if (ctx->runas.shost == NULL)
goto oom;
} else {
ctx->runas.shost = ctx->runas.host;
}
debug_return_bool(true);
oom:
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_bool(false);
}

View File

@ -109,42 +109,3 @@ unpivot_root(int fds[2])
{
return true;
}
/*
* Look up the hostname and set ctx->user.host and ctx->user.shost.
*/
void
get_hostname(struct sudoers_context *ctx)
{
char *cp;
debug_decl(get_hostname, SUDOERS_DEBUG_UTIL);
if ((ctx->user.host = sudo_gethostname()) != NULL) {
if ((cp = strchr(ctx->user.host, '.'))) {
*cp = '\0';
if ((ctx->user.shost = strdup(ctx->user.host)) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
*cp = '.';
} else {
ctx->user.shost = ctx->user.host;
}
} else {
ctx->user.host = ctx->user.shost = strdup("localhost");
if (ctx->user.host == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
}
ctx->runas.host = strdup(ctx->user.host);
if (ctx->runas.host == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
if ((cp = strchr(ctx->runas.host, '.'))) {
*cp = '\0';
if ((ctx->runas.shost = strdup(ctx->runas.host)) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
*cp = '.';
} else {
ctx->runas.shost = ctx->runas.host;
}
debug_return;
}

View File

@ -490,4 +490,7 @@ char *serialize_list(const char *varname, struct list_members *members);
bool pivot_root(const char *new_root, int fds[2]);
bool unpivot_root(int fds[2]);
/* sethost.c */
bool sudoers_sethost(struct sudoers_context *ctx, const char *host, const char *remhost);
#endif /* SUDOERS_SUDOERS_H */

View File

@ -96,6 +96,7 @@ main(int argc, char *argv[])
enum sudoers_formats input_format = format_sudoers;
struct sudo_nss testsudoers_nss;
char *p, *grfile, *pwfile;
const char *host = NULL;
const char *errstr;
int ch, dflag, exitcode = EXIT_FAILURE;
unsigned int validated;
@ -150,11 +151,7 @@ main(int argc, char *argv[])
SET(test_ctx.settings.flags, RUNAS_GROUP_SPECIFIED);
break;
case 'h':
test_ctx.user.host = strdup(optarg);
if (test_ctx.user.host == NULL) {
sudo_fatalx(U_("%s: %s"), __func__,
U_("unable to allocate memory"));
}
host = optarg;
break;
case 'i':
if (strcasecmp(optarg, "ldif") == 0) {
@ -284,28 +281,8 @@ main(int argc, char *argv[])
test_ctx.user.uid = test_ctx.user.pw->pw_uid;
test_ctx.user.gid = test_ctx.user.pw->pw_gid;
if (test_ctx.user.host == NULL) {
if ((test_ctx.user.host = sudo_gethostname()) == NULL)
sudo_fatal("gethostname");
}
if ((p = strchr(test_ctx.user.host, '.'))) {
*p = '\0';
if ((test_ctx.user.shost = strdup(test_ctx.user.host)) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
*p = '.';
} else {
test_ctx.user.shost = test_ctx.user.host;
}
if ((test_ctx.runas.host = strdup(test_ctx.user.host)) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
if ((p = strchr(test_ctx.runas.host, '.'))) {
*p = '\0';
if ((test_ctx.runas.shost = strdup(test_ctx.runas.host)) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
*p = '.';
} else {
test_ctx.runas.shost = test_ctx.runas.host;
}
if (!sudoers_sethost(&test_ctx, host, NULL))
goto done;
/* Fill in test_ctx.user.cmnd_args from argv. */
if (argc > 0) {

View File

@ -103,8 +103,6 @@ sudo_noreturn static void export_sudoers(const char *infile, const char *outfile
sudo_noreturn static void help(void);
sudo_noreturn static void usage(void);
extern void get_hostname(struct sudoers_context *ctx);
/*
* Globals
*/
@ -269,7 +267,8 @@ main(int argc, char *argv[])
if ((ctx.user.pw = sudo_getpwuid(getuid())) == NULL)
sudo_fatalx(U_("you do not exist in the %s database"), "passwd");
}
get_hostname(&ctx);
if (!sudoers_sethost(&ctx, NULL, NULL))
return EXIT_FAILURE;
/* Hook the sudoers parser to track files with parse errors. */
sudoers_error_hook = visudo_track_error;