From be8dbeb22e9317ab2801c682fdd4c0049972deef Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 19 Feb 2015 20:28:02 -0700 Subject: [PATCH] Avoid using HOST_NAME_MAX directly and use sysconf(_SC_HOST_NAME_MAX) instead. --- MANIFEST | 1 + config.h.in | 8 ----- configure | 31 ----------------- configure.ac | 8 +---- include/sudo_compat.h | 8 ----- include/sudo_util.h | 4 +++ lib/util/Makefile.in | 8 +++-- lib/util/gethostname.c | 64 +++++++++++++++++++++++++++++++++++ lib/util/util.exp.in | 1 + plugins/sudoers/match.c | 51 ++++++++++++++++++---------- plugins/sudoers/testsudoers.c | 5 +-- plugins/sudoers/visudo.c | 7 ++-- src/sudo.c | 10 +++--- 13 files changed, 118 insertions(+), 88 deletions(-) create mode 100644 lib/util/gethostname.c diff --git a/MANIFEST b/MANIFEST index 6146e70a5..f58ea9ce0 100644 --- a/MANIFEST +++ b/MANIFEST @@ -91,6 +91,7 @@ lib/util/fnmatch.c lib/util/getaddrinfo.c lib/util/getcwd.c lib/util/getgrouplist.c +lib/util/gethostname.c lib/util/getline.c lib/util/getopt_long.c lib/util/gidlist.c diff --git a/config.h.in b/config.h.in index 5d36f60d6..4177fef13 100644 --- a/config.h.in +++ b/config.h.in @@ -97,10 +97,6 @@ don't. */ #undef HAVE_DECL_GETRESUID -/* Define to 1 if you have the declaration of `HOST_NAME_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_HOST_NAME_MAX - /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO @@ -173,10 +169,6 @@ don't. */ #undef HAVE_DECL__INNETGR -/* Define to 1 if you have the declaration of `_POSIX_HOST_NAME_MAX', and to 0 - if you don't. */ -#undef HAVE_DECL__POSIX_HOST_NAME_MAX - /* Define to 1 if you have the declaration of `_POSIX_PATH_MAX', and to 0 if you don't. */ #undef HAVE_DECL__POSIX_PATH_MAX diff --git a/configure b/configure index b12ca34bf..1aa63d801 100755 --- a/configure +++ b/configure @@ -21337,20 +21337,6 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PATH_MAX $ac_have_decl _ACEOF -ac_fn_c_check_decl "$LINENO" "HOST_NAME_MAX" "ac_cv_have_decl_HOST_NAME_MAX" " -#include -#include - -" -if test "x$ac_cv_have_decl_HOST_NAME_MAX" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_HOST_NAME_MAX $ac_have_decl -_ACEOF ac_fn_c_check_decl "$LINENO" "SIZE_MAX" "ac_cv_have_decl_SIZE_MAX" " #include @@ -21457,23 +21443,6 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL__POSIX_PATH_MAX $ac_have_decl _ACEOF -fi -if test "$ac_cv_have_decl_HOST_NAME_MAX" != "yes"; then - ac_fn_c_check_decl "$LINENO" "_POSIX_HOST_NAME_MAX" "ac_cv_have_decl__POSIX_HOST_NAME_MAX" " -#include -#include - -" -if test "x$ac_cv_have_decl__POSIX_HOST_NAME_MAX" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL__POSIX_HOST_NAME_MAX $ac_have_decl -_ACEOF - fi for ac_func in strsignal diff --git a/configure.ac b/configure.ac index e0a4063cd..81b14a357 100644 --- a/configure.ac +++ b/configure.ac @@ -3010,7 +3010,7 @@ dnl We need to add OSDEFS to CFLAGS to expose LLONG_MAX et al on glibc. dnl _CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $OSDEFS" -AC_CHECK_DECLS([LLONG_MAX, LLONG_MIN, ULLONG_MAX, PATH_MAX, HOST_NAME_MAX], [], [], [ +AC_CHECK_DECLS([LLONG_MAX, LLONG_MIN, ULLONG_MAX, PATH_MAX], [], [], [ #include #include ]) @@ -3057,12 +3057,6 @@ if test "$ac_cv_have_decl_PATH_MAX" != "yes"; then #include ]]) fi -if test "$ac_cv_have_decl_HOST_NAME_MAX" != "yes"; then - AC_CHECK_DECLS([_POSIX_HOST_NAME_MAX], [], [], [[ -#include -#include - ]]) -fi dnl dnl Check for strsignal() or sys_siglist diff --git a/include/sudo_compat.h b/include/sudo_compat.h index 0f649e9c5..097e6b6ba 100644 --- a/include/sudo_compat.h +++ b/include/sudo_compat.h @@ -160,14 +160,6 @@ # endif #endif -#if defined(HAVE_DECL_HOST_NAME_MAX) && !HAVE_DECL_HOST_NAME_MAX -# if defined(HAVE_DECL__POSIX_HOST_NAME_MAX) && HAVE_DECL__POSIX_HOST_NAME_MAX -# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX -# else -# define HOST_NAME_MAX 255 -# endif -#endif - /* * Posix versions for those without... */ diff --git a/include/sudo_util.h b/include/sudo_util.h index 124407819..3237c9e7d 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -144,6 +144,10 @@ __dso_public int aix_restoreauthdb_v1(void); __dso_public int aix_setauthdb_v1(char *user); #define aix_setauthdb(_a) aix_setauthdb_v1((_a)) +/* gethostname.c */ +__dso_public char *sudo_gethostname_v1(void); +#define sudo_gethostname() sudo_gethostname_v1() + /* gidlist.c */ __dso_public int sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp); #define sudo_parse_gids(_a, _b, _c) sudo_parse_gids_v1((_a), (_b), (_c)) diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index d66dd1cb2..c6649cfd5 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -96,8 +96,8 @@ DEVEL = @DEVEL@ SHELL = @SHELL@ -LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gidlist.lo lbuf.lo \ - locking.lo parseln.lo progname.lo secure_path.lo setgroups.lo \ +LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gethostname.lo gidlist.lo \ + lbuf.lo locking.lo parseln.lo progname.lo secure_path.lo setgroups.lo \ strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo \ sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@ @@ -361,6 +361,10 @@ getgrouplist.lo: $(srcdir)/getgrouplist.c $(incdir)/compat/nss_dbdefs.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_util.h $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getgrouplist.c +gethostname.lo: $(srcdir)/gethostname.c $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h + $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gethostname.c getline.lo: $(srcdir)/getline.c $(incdir)/sudo_compat.h $(top_builddir)/config.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getline.c getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \ diff --git a/lib/util/gethostname.c b/lib/util/gethostname.c new file mode 100644 index 000000000..2d240e0fe --- /dev/null +++ b/lib/util/gethostname.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 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. + */ + +#include + +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) +# include +#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ +#include + +#include "sudo_compat.h" +#include "sudo_util.h" + +/* + * Return a malloc()ed copy of the system hostname, or NULL if + * malloc() or gethostname() fails. + */ +char * +sudo_gethostname_v1(void) +{ + char *hname; + size_t host_name_max; + +#ifdef _SC_HOST_NAME_MAX + host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX); + if (host_name_max == (size_t)-1) +#endif + host_name_max = 255; /* POSIX and historic BSD */ + + hname = malloc(host_name_max + 1); + if (hname != NULL) { + if (gethostname(hname, host_name_max + 1) == 0) { + /* Old gethostname() may not NUL-terminate if there is no room. */ + hname[host_name_max] = '\0'; + } else { + free(hname); + hname = NULL; + } + } + return hname; +} diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index c75abcf58..170ebdd6f 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -65,6 +65,7 @@ sudo_fatal_callback_register_v1 sudo_fatal_nodebug_v1 sudo_fatalx_nodebug_v1 sudo_get_ttysize_v1 +sudo_gethostname_v1 sudo_lbuf_append_quoted_v1 sudo_lbuf_append_v1 sudo_lbuf_destroy_v1 diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index 59b1bfbbe..ef666bbff 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -911,40 +911,57 @@ done: /* * Get NIS-style domain name and copy from static storage or NULL if none. */ +#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN) const char * sudo_getdomainname(void) { - char *domain = NULL; -#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN) - static char buf[HOST_NAME_MAX + 1]; + static char *domain; static bool initialized; + debug_decl(sudo_getdomainname, SUDOERS_DEBUG_MATCH) if (!initialized) { + size_t host_name_max; int rval; +# ifdef _SC_HOST_NAME_MAX + host_name_max = (size_t)sysconf(_SC_HOST_NAME_MAX); + if (host_name_max == (size_t)-1) +# endif + host_name_max = 255; /* POSIX and historic BSD */ + + domain = malloc(host_name_max + 1); + if (domain != NULL) { # ifdef SI_SRPC_DOMAIN - buf[0] = '\0'; - rval = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf)); + domain[0] = '\0'; + rval = sysinfo(SI_SRPC_DOMAIN, domain, host_name_max + 1); # else - rval = getdomainname(buf, sizeof(buf)); + rval = getdomainname(domain, host_name_max + 1); # endif - if (rval != -1 && buf[0] != '\0') { - char *cp; - - domain = buf; - for (cp = buf; *cp != '\0'; cp++) { - /* Check for illegal characters, Linux may use "(none)". */ - if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ') { - domain = NULL; - break; + if (rval != -1 && domain[0] != '\0') { + const char *cp; + + for (cp = domain; *cp != '\0'; cp++) { + /* Check for illegal characters, Linux may use "(none)". */ + if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ') { + sudo_efree(domain); + domain = NULL; + break; + } } } } initialized = true; } -#endif /* HAVE_GETDOMAINNAME || SI_SRPC_DOMAIN */ - return domain; + debug_return_str(domain); } +#else +const char * +sudo_getdomainname(void) +{ + debug_decl(sudo_getdomainname, SUDOERS_DEBUG_MATCH) + debug_return_ptr(NULL); +} +#endif /* HAVE_GETDOMAINNAME || SI_SRPC_DOMAIN */ /* * Returns true if "host" and "user" belong to the netgroup "netgr", diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index ab7740085..2b6a5f26b 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -119,7 +119,6 @@ main(int argc, char *argv[]) struct privilege *priv; struct userspec *us; char *p, *grfile, *pwfile; - char hbuf[HOST_NAME_MAX + 1]; const char *errstr; int match, host_match, runas_match, cmnd_match; int ch, dflag, exitcode = 0; @@ -212,10 +211,8 @@ main(int argc, char *argv[]) sudo_fatalx(U_("unknown user: %s"), user_name); if (user_host == NULL) { - if (gethostname(hbuf, sizeof(hbuf)) != 0) + if ((user_host = sudo_gethostname()) == NULL) sudo_fatal("gethostname"); - hbuf[sizeof(hbuf) - 1] = '\0'; - user_host = hbuf; } if ((p = strchr(user_host, '.'))) { *p = '\0'; diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index 417b4e476..c5270af35 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -1062,13 +1062,10 @@ get_args(char *cmnd) static void get_hostname(void) { - char *p, thost[HOST_NAME_MAX + 1]; + char *p; debug_decl(get_hostname, SUDOERS_DEBUG_UTIL) - if (gethostname(thost, sizeof(thost)) != -1) { - thost[sizeof(thost) - 1] = '\0'; - user_host = sudo_estrdup(thost); - + if ((user_host = sudo_gethostname()) != NULL) { if ((p = strchr(user_host, '.'))) { *p = '\0'; user_shost = sudo_estrdup(user_host); diff --git a/src/sudo.c b/src/sudo.c index fdcb941f2..ada1805df 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -447,7 +447,7 @@ get_user_groups(struct user_details *ud) static char ** get_user_info(struct user_details *ud) { - char *cp, **user_info, cwd[PATH_MAX], host[HOST_NAME_MAX + 1]; + char *cp, **user_info, cwd[PATH_MAX]; struct passwd *pw; int fd, i = 0; debug_decl(get_user_info, SUDO_DEBUG_UTIL) @@ -515,14 +515,12 @@ get_user_info(struct user_details *ud) sudo_efree(cp); } - if (gethostname(host, sizeof(host)) == 0) - host[sizeof(host) - 1] = '\0'; - else - strlcpy(host, "localhost", sizeof(host)); - user_info[++i] = sudo_new_key_val("host", host); + cp = sudo_gethostname(); + user_info[++i] = sudo_new_key_val("host", cp ? cp : "localhost"); if (user_info[i] == NULL) sudo_fatal(NULL); ud->host = user_info[i] + sizeof("host=") - 1; + sudo_efree(cp); sudo_get_ttysize(&ud->ts_lines, &ud->ts_cols); sudo_easprintf(&user_info[++i], "lines=%d", ud->ts_lines); -- 2.40.0