From: Todd C. Miller Date: Mon, 9 Jan 2012 21:08:58 +0000 (-0500) Subject: On newer FreeBSD we can get the parent's tty name via sysctl(). X-Git-Tag: SUDO_1_8_4~67^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=974e50dcf01ef688311874e37c9b6984f62c112e;p=sudo On newer FreeBSD we can get the parent's tty name via sysctl(). --- diff --git a/config.h.in b/config.h.in index 461ac1621..d3cf94246 100644 --- a/config.h.in +++ b/config.h.in @@ -502,6 +502,9 @@ /* Define to 1 if the system has the type `struct in6_addr'. */ #undef HAVE_STRUCT_IN6_ADDR +/* Define if your struct kinfo_proc has a ki_tdev field. */ +#undef HAVE_STRUCT_KINFO_PROC_KI_TDEV + /* Define if your struct sockadr has an sa_len field. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN diff --git a/configure b/configure index 8c1d2f7ee..928da42e3 100755 --- a/configure +++ b/configure @@ -15855,6 +15855,16 @@ $as_echo "#define HAVE_STRUCT_SOCKADDR_SA_LEN 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct kinfo_proc" "ki_tdev" "ac_cv_member_struct_kinfo_proc_ki_tdev" " #include + #include + +" +if test "x$ac_cv_member_struct_kinfo_proc_ki_tdev" = xyes; then : + +$as_echo "#define HAVE_STRUCT_kinfo_proc_KI_TDEV 1" >>confdefs.h + +fi + _CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $OSDEFS" if test $ac_cv_header_utmpx_h = "yes"; then @@ -17070,147 +17080,6 @@ if test -n "$NEED_SNPRINTF"; then ;; esac -fi -found=no -for ac_func in getaddrinfo -do : - ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo" -if test "x$ac_cv_func_getaddrinfo" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETADDRINFO 1 -_ACEOF - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5 -$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; } -if ${ac_cv_lib_socket_getaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getaddrinfo (); -int -main () -{ -return getaddrinfo (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_getaddrinfo=yes -else - ac_cv_lib_socket_getaddrinfo=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo" >&5 -$as_echo "$ac_cv_lib_socket_getaddrinfo" >&6; } -if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then : - NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"; found=yes -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -linet" >&5 -$as_echo_n "checking for getaddrinfo in -linet... " >&6; } -if ${ac_cv_lib_inet_getaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-linet $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getaddrinfo (); -int -main () -{ -return getaddrinfo (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_inet_getaddrinfo=yes -else - ac_cv_lib_inet_getaddrinfo=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_getaddrinfo" >&5 -$as_echo "$ac_cv_lib_inet_getaddrinfo" >&6; } -if test "x$ac_cv_lib_inet_getaddrinfo" = xyes; then : - NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"; found=yes -else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to find getaddrinfo() trying -lsocket -lnsl" >&5 -$as_echo "$as_me: WARNING: unable to find getaddrinfo() trying -lsocket -lnsl" >&2;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5 -$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; } -if ${ac_cv_lib_socket_getaddrinfo_lnsl+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket -lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getaddrinfo (); -int -main () -{ -return getaddrinfo (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_getaddrinfo_lnsl=yes -else - ac_cv_lib_socket_getaddrinfo_lnsl=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo_lnsl" >&5 -$as_echo "$ac_cv_lib_socket_getaddrinfo_lnsl" >&6; } -if test "x$ac_cv_lib_socket_getaddrinfo_lnsl" = xyes; then : - NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"; found=yes -fi - -fi - -fi - -fi -done - -if test X"$found" != X"no"; then - $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" if test "x$ac_cv_func_socket" = xyes; then : @@ -17606,6 +17475,147 @@ fi fi +found=no +for ac_func in getaddrinfo +do : + ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo" +if test "x$ac_cv_func_getaddrinfo" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETADDRINFO 1 +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5 +$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; } +if ${ac_cv_lib_socket_getaddrinfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getaddrinfo (); +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_getaddrinfo=yes +else + ac_cv_lib_socket_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo" >&5 +$as_echo "$ac_cv_lib_socket_getaddrinfo" >&6; } +if test "x$ac_cv_lib_socket_getaddrinfo" = xyes; then : + NET_LIBS="${NET_LIBS} -lsocket"; LIBS="${LIBS} -lsocket"; found=yes +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -linet" >&5 +$as_echo_n "checking for getaddrinfo in -linet... " >&6; } +if ${ac_cv_lib_inet_getaddrinfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getaddrinfo (); +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_inet_getaddrinfo=yes +else + ac_cv_lib_inet_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_getaddrinfo" >&5 +$as_echo "$ac_cv_lib_inet_getaddrinfo" >&6; } +if test "x$ac_cv_lib_inet_getaddrinfo" = xyes; then : + NET_LIBS="${NET_LIBS} -linet"; LIBS="${LIBS} -linet"; found=yes +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to find getaddrinfo() trying -lsocket -lnsl" >&5 +$as_echo "$as_me: WARNING: unable to find getaddrinfo() trying -lsocket -lnsl" >&2;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo in -lsocket" >&5 +$as_echo_n "checking for getaddrinfo in -lsocket... " >&6; } +if ${ac_cv_lib_socket_getaddrinfo_lnsl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket -lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getaddrinfo (); +int +main () +{ +return getaddrinfo (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_getaddrinfo_lnsl=yes +else + ac_cv_lib_socket_getaddrinfo_lnsl=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_getaddrinfo_lnsl" >&5 +$as_echo "$ac_cv_lib_socket_getaddrinfo_lnsl" >&6; } +if test "x$ac_cv_lib_socket_getaddrinfo_lnsl" = xyes; then : + NET_LIBS="${NET_LIBS} -lsocket -lnsl"; LIBS="${LIBS} -lsocket -lnsl"; found=yes +fi + +fi + +fi + +fi +done + +if test X"$found" != X"no"; then + $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h + +fi for ac_func in getprogname do : ac_fn_c_check_func "$LINENO" "getprogname" "ac_cv_func_getprogname" diff --git a/configure.in b/configure.in index b2d4c85b1..116cd893c 100644 --- a/configure.in +++ b/configure.in @@ -2028,6 +2028,12 @@ AC_INCLUDES_DEFAULT #include ]) SUDO_UID_T_LEN SUDO_SOCK_SA_LEN +AC_CHECK_MEMBER([struct kinfo_proc.ki_tdev], + [AC_DEFINE(HAVE_STRUCT_KINFO_PROC_KI_TDEV, 1, [Define if your struct kinfo_proc has a ki_tdev field.])], + [], + [ #include + #include ] +) dnl dnl Check for utmp/utmpx struct members. dnl We need to include OSDEFS for glibc which only has __e_termination diff --git a/src/sudo.c b/src/sudo.c index c20735805..94aeb969a 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -89,6 +89,10 @@ #ifdef HAVE_PRIV_SET # include #endif +#ifdef HAVE_STRUCT_KINFO_PROC_KI_TDEV +# include +# include +#endif #include "sudo.h" #include "sudo_plugin.h" @@ -420,6 +424,44 @@ get_user_groups(struct user_details *ud) debug_return_str(gid_list); } +#ifdef HAVE_STRUCT_KINFO_PROC_KI_TDEV +/* + * Return a string from ttyname() containing the tty to which the process is + * attached or NULL if there is no tty associated with the process (or its + * parent). First tries std{in,out,err} then falls back to the parent's + * entry via sysctl. We could try following the parent all the way to pid 1 + * but that is probably overkill. + */ +static char * +get_process_tty(void) +{ + char *tty = NULL; + struct kinfo_proc *ki_proc = NULL; + size_t size = sizeof(*ki_proc); + int mib[4], rc; + debug_decl(get_process_tty, SUDO_DEBUG_UTIL) + + if ((tty = ttyname(STDIN_FILENO)) == NULL && + (tty = ttyname(STDOUT_FILENO)) == NULL && + (tty = ttyname(STDERR_FILENO)) == NULL) { + /* No tty for child, check the parent via sysctl. */ + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = (int)getppid(); + do { + size += size / 10; + ki_proc = erealloc(ki_proc, size); + rc = sysctl(mib, 4, ki_proc, &size, NULL, 0); + } while (rc == -1 && errno == ENOMEM); + if (rc != -1) + tty = devname(ki_proc->ki_tdev, S_IFCHR); + efree(ki_proc); + } + + debug_return_str(tty); +} +#else /* * Return a string from ttyname() containing the tty to which the process is * attached or NULL if there is no tty associated with the process (or its @@ -452,6 +494,7 @@ get_process_tty(void) debug_return_str(tty); } +#endif /* HAVE_STRUCT_KINFO_PROC_KI_TDEV */ /* * Return user information as an array of name=value pairs.