From: Todd C. Miller Date: Sun, 18 Nov 2018 14:45:43 +0000 (-0700) Subject: Add support for utmps as found in HP-UX. X-Git-Tag: SUDO_1_8_27^2~30 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ecd968881867890d91750893d759f57a83b6c6db;p=sudo Add support for utmps as found in HP-UX. --- diff --git a/config.h.in b/config.h.in index 8e0f429c9..9b83b1290 100644 --- a/config.h.in +++ b/config.h.in @@ -340,6 +340,9 @@ /* Define to 1 if you have the `getutid' function. */ #undef HAVE_GETUTID +/* Define to 1 if you have the `getutsid' function. */ +#undef HAVE_GETUTSID + /* Define to 1 if you have the `getutxid' function. */ #undef HAVE_GETUTXID @@ -763,27 +766,6 @@ /* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_GMTOFF -/* Define to 1 if `ut_exit' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_EXIT - -/* Define to 1 if `ut_exit.e_termination' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_EXIT_E_TERMINATION - -/* Define to 1 if `ut_exit.__e_termination' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_EXIT___E_TERMINATION - -/* Define to 1 if `ut_id' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_ID - -/* Define to 1 if `ut_pid' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_PID - -/* Define to 1 if `ut_tv' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_TV - -/* Define to 1 if `ut_type' is a member of `struct utmpx'. */ -#undef HAVE_STRUCT_UTMPX_UT_TYPE - /* Define to 1 if `ut_exit' is a member of `struct utmp'. */ #undef HAVE_STRUCT_UTMP_UT_EXIT @@ -894,6 +876,9 @@ /* Define to 1 if you have the `utimes' function. */ #undef HAVE_UTIMES +/* Define to 1 if you have the header file. */ +#undef HAVE_UTMPS_H + /* Define to 1 if you have the header file. */ #undef HAVE_UTMPX_H diff --git a/configure b/configure index cb51705f9..68c0be5f5 100755 --- a/configure +++ b/configure @@ -2867,7 +2867,6 @@ as_fn_append ac_header_list " sys/types.h" as_fn_append ac_header_list " netgroup.h" as_fn_append ac_header_list " paths.h" as_fn_append ac_header_list " spawn.h" -as_fn_append ac_header_list " utmpx.h" as_fn_append ac_header_list " wordexp.h" as_fn_append ac_header_list " sys/sockio.h" as_fn_append ac_header_list " sys/bsdtypes.h" @@ -17737,7 +17736,18 @@ fi +for ac_header in utmps.h utmpx.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + break +fi +done for ac_header in endian.h sys/endian.h machine/endian.h do : @@ -18686,72 +18696,195 @@ cat >>confdefs.h <<_ACEOF _ACEOF -if test $ac_cv_header_utmpx_h = "yes"; then - ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_id" "ac_cv_member_struct_utmpx_ut_id" " +if test $ac_cv_header_utmps_h = "yes"; then + + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_id" "ac_cv_member_struct_utmps_ut_id" " # include -# include +# include " -if test "x$ac_cv_member_struct_utmpx_ut_id" = xyes; then : +if test "x$ac_cv_member_struct_utmps_ut_id" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_pid" "ac_cv_member_struct_utmps_ut_pid" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmps_ut_pid" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_tv" "ac_cv_member_struct_utmps_ut_tv" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmps_ut_tv" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_type" "ac_cv_member_struct_utmps_ut_type" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmps_ut_type" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h + + +fi + + if test "utmps" = "utmp"; then + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmp_ut_user" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_ID 1 +#define HAVE_STRUCT_UTMP_UT_USER 1 _ACEOF fi -ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_pid" "ac_cv_member_struct_utmpx_ut_pid" " + + fi + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_exit.__e_termination" "ac_cv_member_struct_utmps_ut_exit___e_termination" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmps_ut_exit___e_termination" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h + + +else + + ac_fn_c_check_member "$LINENO" "struct utmps" "ut_exit.e_termination" "ac_cv_member_struct_utmps_ut_exit_e_termination" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmps_ut_exit_e_termination" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h + + +fi + + +fi + + +elif test $ac_cv_header_utmpx_h = "yes"; then + + ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_id" "ac_cv_member_struct_utmpx_ut_id" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmpx_ut_id" = xyes; then : + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h + + +fi + + ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_pid" "ac_cv_member_struct_utmpx_ut_pid" " # include # include " if test "x$ac_cv_member_struct_utmpx_ut_pid" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_PID 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_tv" "ac_cv_member_struct_utmpx_ut_tv" " + + ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_tv" "ac_cv_member_struct_utmpx_ut_tv" " # include # include " if test "x$ac_cv_member_struct_utmpx_ut_tv" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_TV 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_type" "ac_cv_member_struct_utmpx_ut_type" " + + ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_type" "ac_cv_member_struct_utmpx_ut_type" " # include # include " if test "x$ac_cv_member_struct_utmpx_ut_type" = xyes; then : + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h + + +fi + + if test "utmpx" = "utmp"; then + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" " +# include +# include + +" +if test "x$ac_cv_member_struct_utmp_ut_user" = xyes; then : + cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_TYPE 1 +#define HAVE_STRUCT_UTMP_UT_USER 1 _ACEOF fi - ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_exit.__e_termination" "ac_cv_member_struct_utmpx_ut_exit___e_termination" " + fi + ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_exit.__e_termination" "ac_cv_member_struct_utmpx_ut_exit___e_termination" " # include # include " if test "x$ac_cv_member_struct_utmpx_ut_exit___e_termination" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_EXIT___E_TERMINATION 1 -_ACEOF -$as_echo "#define HAVE_STRUCT_UTMPX_UT_EXIT 1" >>confdefs.h +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h + else @@ -18762,71 +18895,75 @@ else " if test "x$ac_cv_member_struct_utmpx_ut_exit_e_termination" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMPX_UT_EXIT_E_TERMINATION 1 -_ACEOF -$as_echo "#define HAVE_STRUCT_UTMPX_UT_EXIT 1" >>confdefs.h +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h + fi fi + else - ac_fn_c_check_member "$LINENO" "struct utmp" "ut_id" "ac_cv_member_struct_utmp_ut_id" " + + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_id" "ac_cv_member_struct_utmp_ut_id" " # include # include " if test "x$ac_cv_member_struct_utmp_ut_id" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_ID 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_ID 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmp" "ut_pid" "ac_cv_member_struct_utmp_ut_pid" " + + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_pid" "ac_cv_member_struct_utmp_ut_pid" " # include # include " if test "x$ac_cv_member_struct_utmp_ut_pid" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_PID 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_PID 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmp" "ut_tv" "ac_cv_member_struct_utmp_ut_tv" " + + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_tv" "ac_cv_member_struct_utmp_ut_tv" " # include # include " if test "x$ac_cv_member_struct_utmp_ut_tv" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_TV 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TV 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmp" "ut_type" "ac_cv_member_struct_utmp_ut_type" " + + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_type" "ac_cv_member_struct_utmp_ut_type" " # include # include " if test "x$ac_cv_member_struct_utmp_ut_type" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_TYPE 1 -_ACEOF + +$as_echo "#define HAVE_STRUCT_UTMP_UT_TYPE 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" " + + if test "utmp" = "utmp"; then + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_user" "ac_cv_member_struct_utmp_ut_user" " # include # include @@ -18840,19 +18977,21 @@ _ACEOF fi - ac_fn_c_check_member "$LINENO" "struct utmp" "ut_exit.__e_termination" "ac_cv_member_struct_utmp_ut_exit___e_termination" " + fi + ac_fn_c_check_member "$LINENO" "struct utmp" "ut_exit.__e_termination" "ac_cv_member_struct_utmp_ut_exit___e_termination" " # include # include " if test "x$ac_cv_member_struct_utmp_ut_exit___e_termination" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1 -_ACEOF $as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION 1" >>confdefs.h + + else ac_fn_c_check_member "$LINENO" "struct utmp" "ut_exit.e_termination" "ac_cv_member_struct_utmp_ut_exit_e_termination" " @@ -18862,17 +19001,19 @@ else " if test "x$ac_cv_member_struct_utmp_ut_exit_e_termination" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1 -_ACEOF $as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT 1" >>confdefs.h + +$as_echo "#define HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION 1" >>confdefs.h + + fi fi + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5 @@ -19443,7 +19584,7 @@ done utmp_style=LEGACY -for ac_func in getutxid getutid +for ac_func in getutsid getutxid getutid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -29148,8 +29289,6 @@ fi - - diff --git a/configure.ac b/configure.ac index 660a206d7..b8797d173 100644 --- a/configure.ac +++ b/configure.ac @@ -2396,7 +2396,8 @@ dnl AC_HEADER_DIRENT AC_HEADER_STDBOOL AC_HEADER_MAJOR -AC_CHECK_HEADERS_ONCE([netgroup.h paths.h spawn.h utmpx.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h sys/syscall.h sys/statvfs.h]) +AC_CHECK_HEADERS_ONCE([netgroup.h paths.h spawn.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h sys/syscall.h sys/statvfs.h]) +AC_CHECK_HEADERS([utmps.h] [utmpx.h], [break]) AC_CHECK_HEADERS([endian.h] [sys/endian.h] [machine/endian.h], [break]) AC_CHECK_HEADERS([procfs.h] [sys/procfs.h], [AC_CHECK_MEMBERS(struct psinfo.pr_ttydev, [AC_CHECK_FUNCS([_ttyname_dev])], [], [AC_INCLUDES_DEFAULT #ifdef HAVE_PROCFS_H @@ -2491,45 +2492,12 @@ SUDO_SOCK_SIN_LEN AC_CHECK_SIZEOF([id_t]) AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([time_t]) -dnl -dnl Check for utmp/utmpx struct members. -dnl We need to have already defined _GNU_SOURCE on glibc which only has -dnl __e_termination visible when _GNU_SOURCE is *not* defined. -dnl -if test $ac_cv_header_utmpx_h = "yes"; then - AC_CHECK_MEMBERS([struct utmpx.ut_id, struct utmpx.ut_pid, struct utmpx.ut_tv, struct utmpx.ut_type], [], [], [ -# include -# include - ]) - dnl - dnl Check for ut_exit.__e_termination first, then ut_exit.e_termination - dnl - AC_CHECK_MEMBERS([struct utmpx.ut_exit.__e_termination], [AC_DEFINE(HAVE_STRUCT_UTMPX_UT_EXIT)], [ - AC_CHECK_MEMBERS([struct utmpx.ut_exit.e_termination], [AC_DEFINE(HAVE_STRUCT_UTMPX_UT_EXIT)], [], [ -# include -# include - ]) - ], [ -# include -# include - ]) +if test $ac_cv_header_utmps_h = "yes"; then + SUDO_CHECK_UTMP_MEMBERS([utmps]) +elif test $ac_cv_header_utmpx_h = "yes"; then + SUDO_CHECK_UTMP_MEMBERS([utmpx]) else - AC_CHECK_MEMBERS([struct utmp.ut_id, struct utmp.ut_pid, struct utmp.ut_tv, struct utmp.ut_type, struct utmp.ut_user], [], [], [ -# include -# include - ]) - dnl - dnl Check for ut_exit.__e_termination first, then ut_exit.e_termination - dnl - AC_CHECK_MEMBERS([struct utmp.ut_exit.__e_termination], [AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT)], [ - AC_CHECK_MEMBERS([struct utmp.ut_exit.e_termination], [AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT)], [], [ -# include -# include - ]) - ], [ -# include -# include - ]) + SUDO_CHECK_UTMP_MEMBERS([utmp]) fi dnl @@ -2616,7 +2584,7 @@ AC_CHECK_FUNCS([arc4random_uniform], [], [ ]) utmp_style=LEGACY -AC_CHECK_FUNCS([getutxid getutid], [utmp_style=POSIX; break]) +AC_CHECK_FUNCS([getutsid getutxid getutid], [utmp_style=POSIX; break]) if test "$utmp_style" = "LEGACY"; then AC_CHECK_FUNCS([getttyent ttyslot], [break]) AC_CHECK_FUNCS([fseeko]) @@ -4614,8 +4582,6 @@ AH_TEMPLATE(WITHOUT_PASSWD, [Define to avoid using the passwd/shadow file for au AH_TEMPLATE(clockid_t, [Define to `int' if does not define.]) AH_TEMPLATE(sig_atomic_t, [Define to `int' if does not define.]) AH_TEMPLATE(socklen_t, [Define to `unsigned int' if doesn't define.]) -AH_TEMPLATE(HAVE_STRUCT_UTMP_UT_EXIT, [Define to 1 if `ut_exit' is a member of `struct utmp'.]) -AH_TEMPLATE(HAVE_STRUCT_UTMPX_UT_EXIT, [Define to 1 if `ut_exit' is a member of `struct utmpx'.]) AH_TEMPLATE(HAVE___FUNC__, [Define to 1 if the compiler supports the C99 __func__ variable.]) AH_TEMPLATE(HAVE___INTERPOSE, [Define to 1 if you have dyld with __interpose attribute support.]) AH_TEMPLATE(SUDO_KRB5_INSTANCE, [An instance string to append to the username (separated by a slash) for Kerberos V authentication.]) diff --git a/m4/sudo.m4 b/m4/sudo.m4 index df8966026..f67ee56c1 100644 --- a/m4/sudo.m4 +++ b/m4/sudo.m4 @@ -361,6 +361,69 @@ AC_MSG_RESULT($sudo_cv_uid_t_len) AC_DEFINE_UNQUOTED(MAX_UID_T_LEN, $sudo_cv_uid_t_len, [Define to the max length of a uid_t in string context (excluding the NUL).]) ]) +dnl +dnl There are three different utmp variants we need to check for. +dnl SUDO_CHECK_UTMP_MEMBERS(utmp_type) +dnl +AC_DEFUN([SUDO_CHECK_UTMP_MEMBERS], [ + dnl + dnl Check for utmp/utmpx/utmps struct members. + dnl + AC_CHECK_MEMBER([struct $1.ut_id], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_ID, 1, [Define to 1 if `ut_id' is a member of `struct utmp'.]) + ], [], [ +# include +# include <$1.h> + ]) + AC_CHECK_MEMBER([struct $1.ut_pid], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_PID, 1, [Define to 1 if `ut_pid' is a member of `struct utmp'.]) + ], [], [ +# include +# include <$1.h> + ]) + AC_CHECK_MEMBER([struct $1.ut_tv], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_TV, 1, [Define to 1 if `ut_tv' is a member of `struct utmp'.]) + ], [], [ +# include +# include <$1.h> + ]) + AC_CHECK_MEMBER([struct $1.ut_type], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_TYPE, 1, [Define to 1 if `ut_type' is a member of `struct utmp'.]) + ], [], [ +# include +# include <$1.h> + ]) + dnl + dnl Older struct utmp has ut_name instead of ut_user + dnl + if test "$1" = "utmp"; then + AC_CHECK_MEMBERS([struct utmp.ut_user], [], [], [ +# include +# include <$1.h> + ]) + fi + dnl + dnl Check for ut_exit.__e_termination first, then ut_exit.e_termination + dnl We need to have already defined _GNU_SOURCE on glibc which only has + dnl __e_termination visible when _GNU_SOURCE is *not* defined. + dnl + AC_CHECK_MEMBER([struct $1.ut_exit.__e_termination], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT, 1, [Define to 1 if `ut_exit' is a member of `struct utmp'.]) + AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT___E_TERMINATION, 1, [Define to 1 if `ut_exit.__e_termination' is a member of `struct utmp'.]) + ], [ + AC_CHECK_MEMBER([struct $1.ut_exit.e_termination], [ + AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT, 1, [Define to 1 if `ut_exit' is a member of `struct utmp'.]) + AC_DEFINE(HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION, 1, [Define to 1 if `ut_exit.e_termination' is a member of `struct utmp'.]) + ], [], [ +# include +# include <$1.h> + ]) + ], [ +# include +# include <$1.h> + ]) +]) + dnl dnl Append a libpath to an LDFLAGS style variable if not already present. dnl Also appends to the _R version unless rpath is disabled. diff --git a/src/utmp.c b/src/utmp.c index ecaabe9b6..b371bbf2a 100644 --- a/src/utmp.c +++ b/src/utmp.c @@ -34,11 +34,13 @@ #endif /* HAVE_STRINGS_H */ #include #include -#ifdef HAVE_UTMPX_H +#if defined(HAVE_UTMPS_H) +# include +#elif defined(HAVE_UTMPX_H) # include #else # include -#endif /* HAVE_UTMPX_H */ +#endif /* HAVE_UTMPS_H */ #ifdef HAVE_GETTTYENT # include #endif @@ -49,34 +51,46 @@ #include "sudo_exec.h" /* - * Simplify handling of utmp vs. utmpx + * Simplify handling of different utmp types. */ -#if !defined(HAVE_GETUTXID) && defined(HAVE_GETUTID) -# define getutxline(u) getutline(u) -# define pututxline(u) pututline(u) -# define setutxent() setutent() -# define endutxent() endutent() -#endif /* !HAVE_GETUTXID && HAVE_GETUTID */ - -#ifdef HAVE_GETUTXID +#if defined(HAVE_GETUTSID) +# define sudo_getutline(u) GETUTSLINE(u) +# define sudo_pututline(u) PUTUTSLINE(u) +# define sudo_setutent() SETUTSENT() +# define sudo_endutent() ENDUTSENT() +#elif defined(HAVE_GETUTXID) +# define sudo_getutline(u) getutxline(u) +# define sudo_pututline(u) pututxline(u) +# define sudo_setutent() setutxent() +# define sudo_endutent() endutxent() +#elif defined(HAVE_GETUTID) +# define sudo_getutline(u) getutline(u) +# define sudo_pututline(u) pututline(u) +# define sudo_setutent() setutent() +# define sudo_endutent() endutent() +#endif + +#if defined(HAVE_GETUTSID) +typedef struct utmps sudo_utmp_t; +#elif defined(HAVE_GETUTXID) typedef struct utmpx sudo_utmp_t; #else typedef struct utmp sudo_utmp_t; -/* Older systems have ut_name, not us_user */ +/* Older systems have ut_name, not ut_user */ # if !defined(HAVE_STRUCT_UTMP_UT_USER) && !defined(ut_user) # define ut_user ut_name # endif #endif -/* HP-UX has __e_termination and __e_exit, others lack the __ */ -#if defined(HAVE_STRUCT_UTMPX_UT_EXIT_E_TERMINATION) || defined(HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION) +/* HP-UX has __e_termination and __e_exit, others may lack the __ */ +#if defined(HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION) # undef __e_termination # define __e_termination e_termination # undef __e_exit # define __e_exit e_exit #endif -#if defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) +#if defined(HAVE_GETUTSID) || defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) /* * Create ut_id from the new ut_line and the old ut_id. */ @@ -108,7 +122,7 @@ utmp_setid(sudo_utmp_t *old, sudo_utmp_t *new) debug_return; } -#endif /* HAVE_GETUTXID || HAVE_GETUTID */ +#endif /* HAVE_GETUTSID || HAVE_GETUTXID || HAVE_GETUTID */ /* * Store time in utmp structure. @@ -120,7 +134,7 @@ utmp_settime(sudo_utmp_t *ut) debug_decl(utmp_settime, SUDO_DEBUG_UTMP) if (gettimeofday(&tv, NULL) == 0) { -#if defined(HAVE_STRUCT_UTMP_UT_TV) || defined(HAVE_STRUCT_UTMPX_UT_TV) +#if defined(HAVE_STRUCT_UTMP_UT_TV) ut->ut_tv.tv_sec = tv.tv_sec; ut->ut_tv.tv_usec = tv.tv_usec; #else @@ -152,14 +166,14 @@ utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old, if (user != NULL) strncpy(ut_new->ut_user, user, sizeof(ut_new->ut_user)); strncpy(ut_new->ut_line, line, sizeof(ut_new->ut_line)); -#if defined(HAVE_STRUCT_UTMPX_UT_ID) || defined(HAVE_STRUCT_UTMP_UT_ID) +#if defined(HAVE_STRUCT_UTMP_UT_ID) utmp_setid(ut_old, ut_new); #endif -#if defined(HAVE_STRUCT_UTMPX_UT_PID) || defined(HAVE_STRUCT_UTMP_UT_PID) +#if defined(HAVE_STRUCT_UTMP_UT_PID) ut_new->ut_pid = getpid(); #endif utmp_settime(ut_new); -#if defined(HAVE_STRUCT_UTMPX_UT_TYPE) || defined(HAVE_STRUCT_UTMP_UT_TYPE) +#if defined(HAVE_STRUCT_UTMP_UT_TYPE) ut_new->ut_type = USER_PROCESS; #endif debug_return; @@ -169,11 +183,11 @@ utmp_fill(const char *line, const char *user, sudo_utmp_t *ut_old, * There are two basic utmp file types: * * POSIX: sequential access with new entries appended to the end. - * Manipulated via {get,put}utent()/{get,put}getutxent(). + * Manipulated via {get,put}[sx]?utent() * * Legacy: sparse file indexed by ttyslot() * sizeof(struct utmp) */ -#if defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) +#if defined(HAVE_GETUTSID) || defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) bool utmp_login(const char *from_line, const char *to_line, int ttyfd, const char *user) @@ -185,7 +199,7 @@ utmp_login(const char *from_line, const char *to_line, int ttyfd, /* Strip off /dev/ prefix from line as needed. */ if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) to_line += sizeof(_PATH_DEV) - 1; - setutxent(); + sudo_setutent(); if (from_line != NULL) { if (strncmp(from_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) from_line += sizeof(_PATH_DEV) - 1; @@ -193,12 +207,12 @@ utmp_login(const char *from_line, const char *to_line, int ttyfd, /* Lookup old line. */ memset(&utbuf, 0, sizeof(utbuf)); strncpy(utbuf.ut_line, from_line, sizeof(utbuf.ut_line)); - ut_old = getutxline(&utbuf); + ut_old = sudo_getutline(&utbuf); } utmp_fill(to_line, user, ut_old, &utbuf); - if (pututxline(&utbuf) != NULL) + if (sudo_pututline(&utbuf) != NULL) ret = true; - endutxent(); + sudo_endutent(); debug_return_bool(ret); } @@ -216,23 +230,23 @@ utmp_logout(const char *line, int status) memset(&utbuf, 0, sizeof(utbuf)); strncpy(utbuf.ut_line, line, sizeof(utbuf.ut_line)); - if ((ut = getutxline(&utbuf)) != NULL) { + if ((ut = sudo_getutline(&utbuf)) != NULL) { memset(ut->ut_user, 0, sizeof(ut->ut_user)); -# if defined(HAVE_STRUCT_UTMPX_UT_TYPE) || defined(HAVE_STRUCT_UTMP_UT_TYPE) +# if defined(HAVE_STRUCT_UTMP_UT_TYPE) ut->ut_type = DEAD_PROCESS; # endif -# if defined(HAVE_STRUCT_UTMPX_UT_EXIT) || defined(HAVE_STRUCT_UTMP_UT_EXIT) +# if defined(HAVE_STRUCT_UTMP_UT_EXIT) ut->ut_exit.__e_termination = WIFSIGNALED(status) ? WTERMSIG(status) : 0; ut->ut_exit.__e_exit = WIFEXITED(status) ? WEXITSTATUS(status) : 0; # endif utmp_settime(ut); - if (pututxline(ut) != NULL) + if (sudo_pututline(ut) != NULL) ret = true; } debug_return_bool(ret); } -#else /* !HAVE_GETUTXID && !HAVE_GETUTID */ +#else /* !HAVE_GETUTSID && !HAVE_GETUTXID && !HAVE_GETUTID */ /* * Find the slot for the specified line (tty name and file descriptor). @@ -320,11 +334,11 @@ utmp_login(const char *from_line, const char *to_line, int ttyfd, } } utmp_fill(to_line, user, ut_old, &utbuf); -#ifdef HAVE_FSEEKO +# ifdef HAVE_FSEEKO if (fseeko(fp, slot * (off_t)sizeof(utbuf), SEEK_SET) == 0) { -#else +# else if (fseek(fp, slot * (long)sizeof(utbuf), SEEK_SET) == 0) { -#endif +# endif if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1) ret = true; } @@ -357,11 +371,11 @@ utmp_logout(const char *line, int status) # endif utmp_settime(&utbuf); /* Back up and overwrite record. */ -#ifdef HAVE_FSEEKO +# ifdef HAVE_FSEEKO if (fseeko(fp, (off_t)0 - (off_t)sizeof(utbuf), SEEK_CUR) == 0) { -#else +# else if (fseek(fp, 0L - (long)sizeof(utbuf), SEEK_CUR) == 0) { -#endif +# endif if (fwrite(&utbuf, sizeof(utbuf), 1, fp) == 1) ret = true; } @@ -372,4 +386,4 @@ utmp_logout(const char *line, int status) debug_return_bool(ret); } -#endif /* HAVE_GETUTXID || HAVE_GETUTID */ +#endif /* HAVE_GETUTSID || HAVE_GETUTXID || HAVE_GETUTID */