2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 09:57:41 +00:00

Merge sudo 1.9.16p2 from tip.

--HG--
branch : 1.9
This commit is contained in:
Todd C. Miller 2024-11-25 08:36:28 -07:00
commit 172cbd968e
17 changed files with 134 additions and 65 deletions

15
NEWS
View File

@ -1,3 +1,18 @@
What's new in Sudo 1.9.16p2
* Sudo now passes the terminal device number to the policy plugin
even if it cannot resolve it to a path name. This allows sudo
to run without warnings in a chroot jail when the terminal device
files are not present. GitHub issue #421.
* On Linux systems, sudo will now attempt to use the symbolic links
in /proc/self/fd/{0,1,2} when resolving the terminal device
number. This can allow sudo to map a terminal device to its
path name even when /dev/pts is not mounted in a chroot jail.
* Fixed compilation errors with gcc and clang in C23 mode.
C23 no longer supports functions with unspecified arguments.
What's new in Sudo 1.9.16p1 What's new in Sudo 1.9.16p1
* Fixed the test for cross-compiling when checking for C99 snprintf(). * Fixed the test for cross-compiling when checking for C99 snprintf().

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for sudo 1.9.16p1. # Generated by GNU Autoconf 2.72 for sudo 1.9.16p2.
# #
# Report bugs to <https://bugzilla.sudo.ws/>. # Report bugs to <https://bugzilla.sudo.ws/>.
# #
@ -614,8 +614,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sudo' PACKAGE_NAME='sudo'
PACKAGE_TARNAME='sudo' PACKAGE_TARNAME='sudo'
PACKAGE_VERSION='1.9.16p1' PACKAGE_VERSION='1.9.16p2'
PACKAGE_STRING='sudo 1.9.16p1' PACKAGE_STRING='sudo 1.9.16p2'
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/' PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
PACKAGE_URL='' PACKAGE_URL=''
@ -1645,7 +1645,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
'configure' configures sudo 1.9.16p1 to adapt to many kinds of systems. 'configure' configures sudo 1.9.16p2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1711,7 +1711,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sudo 1.9.16p1:";; short | recursive ) echo "Configuration of sudo 1.9.16p2:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -2006,7 +2006,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sudo configure 1.9.16p1 sudo configure 1.9.16p2
generated by GNU Autoconf 2.72 generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc. Copyright (C) 2023 Free Software Foundation, Inc.
@ -2826,7 +2826,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sudo $as_me 1.9.16p1, which was It was created by sudo $as_me 1.9.16p2, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw $ $0$ac_configure_args_raw
@ -36774,7 +36774,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sudo $as_me 1.9.16p1, which was This file was extended by sudo $as_me 1.9.16p2, which was
generated by GNU Autoconf 2.72. Invocation command line was generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -36842,7 +36842,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped' ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\ ac_cs_version="\\
sudo config.status 1.9.16p1 sudo config.status 1.9.16p2
configured by $0, generated by GNU Autoconf 2.72, configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
dnl dnl
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([sudo], [1.9.16p1], [https://bugzilla.sudo.ws/], [sudo]) AC_INIT([sudo], [1.9.16p2], [https://bugzilla.sudo.ws/], [sudo])
AC_CONFIG_HEADERS([config.h pathnames.h]) AC_CONFIG_HEADERS([config.h pathnames.h])
AC_CONFIG_SRCDIR([src/sudo.c]) AC_CONFIG_SRCDIR([src/sudo.c])
AC_CONFIG_AUX_DIR([scripts]) AC_CONFIG_AUX_DIR([scripts])

View File

@ -96,7 +96,11 @@ typedef int (*sudo_printf_t)(int msg_type, const char * restrict fmt, ...);
#endif #endif
/* Hook functions typedefs. */ /* Hook functions typedefs. */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)
typedef int (*sudo_hook_fn_t)(...);
#else
typedef int (*sudo_hook_fn_t)(); typedef int (*sudo_hook_fn_t)();
#endif
typedef int (*sudo_hook_fn_setenv_t)(const char *name, const char *value, int overwrite, void *closure); typedef int (*sudo_hook_fn_setenv_t)(const char *name, const char *value, int overwrite, void *closure);
typedef int (*sudo_hook_fn_putenv_t)(char *string, void *closure); typedef int (*sudo_hook_fn_putenv_t)(char *string, void *closure);
typedef int (*sudo_hook_fn_getenv_t)(const char *name, char **value, void *closure); typedef int (*sudo_hook_fn_getenv_t)(const char *name, char **value, void *closure);

View File

@ -50,7 +50,7 @@ static struct parse_gids_test test_data[] = {
{ "1,2,3,4", &test_data[0].basegid, 0, 5, test1_out }, { "1,2,3,4", &test_data[0].basegid, 0, 5, test1_out },
{ "1,2,3,4", NULL, 0, 4, test2_out }, { "1,2,3,4", NULL, 0, 4, test2_out },
{ "1,-2,3,4", &test_data[2].basegid, 0, 5, test3_out }, { "1,-2,3,4", &test_data[2].basegid, 0, 5, test3_out },
{ NULL, false, 0, 0, NULL } { NULL, NULL, 0, 0, NULL }
}; };
static void static void

View File

@ -50,7 +50,7 @@ sudo_setgroups_v1(int ngids, const GETGROUPS_T *gids)
if (maxgids == -1) if (maxgids == -1)
maxgids = NGROUPS_MAX; maxgids = NGROUPS_MAX;
if (ngids > maxgids) if (ngids > maxgids)
ret = setgroups(maxgids, (GETGROUPS_T *)gids); ret = setgroups((int)maxgids, (GETGROUPS_T *)gids);
} }
debug_return_int(ret); debug_return_int(ret);
} }

View File

@ -253,11 +253,39 @@ char *
sudo_ttyname_dev_v1(dev_t rdev, char *buf, size_t buflen) sudo_ttyname_dev_v1(dev_t rdev, char *buf, size_t buflen)
{ {
const char *devsearch, *devsearch_end; const char *devsearch, *devsearch_end;
char path[PATH_MAX], *ret; char path[PATH_MAX], *ret = NULL;
const char *cp, *ep; const char *cp, *ep;
size_t len; size_t len;
debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL); debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL);
#ifdef __linux__
/*
* First check std{in,out,err} and use /proc/self/fd/{0,1,2} if possible.
*/
for (int fd = STDIN_FILENO; fd <= STDERR_FILENO; fd++) {
char fdpath[] = "/proc/self/fd/N";
struct stat sb;
if (fstat(fd, &sb) == -1 || !S_ISCHR(sb.st_mode))
continue;
if (rdev != sb.st_rdev)
continue;
fdpath[sizeof("/proc/self/fd/N") - 2] = '0' + fd;
len = readlink(fdpath, buf, buflen);
if (len != (size_t)-1) {
if (len == buflen) {
errno = ERANGE; /* buf too small */
} else {
/* readlink(2) does not NUL-terminate. */
buf[len] = '\0';
ret = buf;
}
goto done;
}
}
#endif
/* /*
* First, check /dev/console. * First, check /dev/console.
*/ */

View File

@ -204,7 +204,7 @@ print_global_defaults_ldif(FILE *fp,
lbuf.len = 0; lbuf.len = 0;
if (!sudo_lbuf_append(&lbuf, "# ")) if (!sudo_lbuf_append(&lbuf, "# "))
goto done; goto done;
if (!sudoers_format_default_line(&lbuf, parse_tree, opt, false, true)) if (!sudoers_format_default_line(&lbuf, parse_tree, opt, NULL, true))
goto done; goto done;
fprintf(fp, "# Unable to translate %s:%d:%d:\n%s\n", fprintf(fp, "# Unable to translate %s:%d:%d:\n%s\n",
opt->file, opt->line, opt->column, lbuf.buf); opt->file, opt->line, opt->column, lbuf.buf);

View File

@ -403,7 +403,7 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
struct cache_item_grlist *grlitem; struct cache_item_grlist *grlitem;
struct sudoers_string *s; struct sudoers_string *s;
struct group_list *grlist; struct group_list *grlist;
size_t groupname_len; long groupname_len;
debug_decl(cvtsudoers_make_grlist_item, SUDOERS_DEBUG_NSS); debug_decl(cvtsudoers_make_grlist_item, SUDOERS_DEBUG_NSS);
/* /*
@ -421,7 +421,9 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
} }
#ifdef _SC_LOGIN_NAME_MAX #ifdef _SC_LOGIN_NAME_MAX
groupname_len = (size_t)MAX(sysconf(_SC_LOGIN_NAME_MAX), 32); groupname_len = sysconf(_SC_LOGIN_NAME_MAX);
if (groupname_len < 32)
groupname_len = 32;
#else #else
groupname_len = MAX(LOGIN_NAME_MAX, 32); groupname_len = MAX(LOGIN_NAME_MAX, 32);
#endif #endif
@ -429,7 +431,7 @@ cvtsudoers_make_grlist_item(const struct passwd *pw, char * const *unused1)
/* Allocate in one big chunk for easy freeing. */ /* Allocate in one big chunk for easy freeing. */
nsize = strlen(pw->pw_name) + 1; nsize = strlen(pw->pw_name) + 1;
total = sizeof(*grlitem) + nsize; total = sizeof(*grlitem) + nsize;
total += groupname_len * ngroups; total += (size_t)groupname_len * ngroups;
again: again:
if ((grlitem = calloc(1, total)) == NULL) { if ((grlitem = calloc(1, total)) == NULL) {
@ -470,7 +472,7 @@ again:
} }
len = strlen(s->str) + 1; len = strlen(s->str) + 1;
if ((size_t)(cp - (char *)grlitem) + len > total) { if ((size_t)(cp - (char *)grlitem) + len > total) {
total += len + groupname_len; total += len + (size_t)groupname_len;
free(grlitem); free(grlitem);
goto again; goto again;
} }

View File

@ -1358,10 +1358,10 @@ sudoers_policy_version(int verbose)
} }
static struct sudo_hook sudoers_hooks[] = { static struct sudo_hook sudoers_hooks[] = {
{ SUDO_HOOK_VERSION, SUDO_HOOK_SETENV, sudoers_hook_setenv, NULL }, { SUDO_HOOK_VERSION, SUDO_HOOK_SETENV, (sudo_hook_fn_t)sudoers_hook_setenv, NULL },
{ SUDO_HOOK_VERSION, SUDO_HOOK_UNSETENV, sudoers_hook_unsetenv, NULL }, { SUDO_HOOK_VERSION, SUDO_HOOK_UNSETENV, (sudo_hook_fn_t)sudoers_hook_unsetenv, NULL },
{ SUDO_HOOK_VERSION, SUDO_HOOK_GETENV, sudoers_hook_getenv, NULL }, { SUDO_HOOK_VERSION, SUDO_HOOK_GETENV, (sudo_hook_fn_t)sudoers_hook_getenv, NULL },
{ SUDO_HOOK_VERSION, SUDO_HOOK_PUTENV, sudoers_hook_putenv, NULL }, { SUDO_HOOK_VERSION, SUDO_HOOK_PUTENV, (sudo_hook_fn_t)sudoers_hook_putenv, NULL },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };

View File

@ -363,12 +363,13 @@ PREFIX(make_gidlist_item)(const struct passwd *pw, int ngids, GETGROUPS_T *gids,
struct cache_item * struct cache_item *
PREFIX(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 len, ngroups, nsize, total;
size_t groupname_len, len, ngroups, nsize, total;
struct cache_item_grlist *grlitem; struct cache_item_grlist *grlitem;
struct group_list *grlist; struct group_list *grlist;
struct gid_list *gidlist; struct gid_list *gidlist;
struct group *grp = NULL; struct group *grp = NULL;
long groupname_len;
char *cp;
int i; int i;
debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS); debug_decl(sudo_make_grlist_item, SUDOERS_DEBUG_NSS);
@ -381,7 +382,9 @@ PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
} }
#ifdef _SC_LOGIN_NAME_MAX #ifdef _SC_LOGIN_NAME_MAX
groupname_len = (size_t)MAX(sysconf(_SC_LOGIN_NAME_MAX), 32); groupname_len = sysconf(_SC_LOGIN_NAME_MAX);
if (groupname_len < 32)
groupname_len = 32;
#else #else
groupname_len = MAX(LOGIN_NAME_MAX, 32); groupname_len = MAX(LOGIN_NAME_MAX, 32);
#endif #endif
@ -390,7 +393,7 @@ PREFIX(make_grlist_item)(const struct passwd *pw, char * const *unused1)
nsize = strlen(pw->pw_name) + 1; nsize = strlen(pw->pw_name) + 1;
total = sizeof(*grlitem) + nsize; total = sizeof(*grlitem) + nsize;
total += sizeof(char *) * (size_t)gidlist->ngids; total += sizeof(char *) * (size_t)gidlist->ngids;
total += groupname_len * (size_t)gidlist->ngids; total += (size_t)(groupname_len * gidlist->ngids);
again: again:
if ((grlitem = calloc(1, total)) == NULL) { if ((grlitem = calloc(1, total)) == NULL) {
@ -429,7 +432,7 @@ again:
if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) { if ((grp = sudo_getgrgid(gidlist->gids[i])) != NULL) {
len = strlen(grp->gr_name) + 1; len = strlen(grp->gr_name) + 1;
if ((size_t)(cp - (char *)grlitem) + len > total) { if ((size_t)(cp - (char *)grlitem) + len > total) {
total += len + groupname_len; total += len + (size_t)groupname_len;
free(grlitem); free(grlitem);
sudo_gr_delref(grp); sudo_gr_delref(grp);
goto again; goto again;

View File

@ -69,7 +69,7 @@ sudo_printf_int(int msg_type, const char * restrict fmt, ...)
va_end(ap); va_end(ap);
} }
if (len != -1) { if (len != -1) {
if (fwrite(buf, 1, len, ttyfp ? ttyfp : fp) == 0) if (fwrite(buf, 1, (size_t)len, ttyfp ? ttyfp : fp) == 0)
len = -1; len = -1;
if (buf != sbuf) if (buf != sbuf)
free(buf); free(buf);

View File

@ -1678,9 +1678,9 @@ read_keyboard(int fd, int what, void *v)
static void static void
display_usage(FILE *fp) display_usage(FILE *fp)
{ {
fprintf(fp, _("usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n"), fprintf(fp, "usage: %s [-hnRS] [-d dir] [-m num] [-s num] ID\n",
getprogname()); getprogname());
fprintf(fp, _("usage: %s [-h] [-d dir] -l [search expression]\n"), fprintf(fp, "usage: %s [-h] [-d dir] -l [search expression]\n",
getprogname()); getprogname());
} }

View File

@ -219,7 +219,7 @@ sudo_conversation_printf(int msg_type, const char * restrict fmt, ...)
va_end(ap); va_end(ap);
} }
if (len != -1) { if (len != -1) {
if (fwrite(buf, 1, len, ttyfp ? ttyfp : fp) == 0) if (fwrite(buf, 1, (size_t)len, ttyfp ? ttyfp : fp) == 0)
len = -1; len = -1;
if (buf != sbuf) if (buf != sbuf)
free(buf); free(buf);

View File

@ -125,7 +125,7 @@ process_hooks_unsetenv(const char *name)
/* Hook registration internals. */ /* Hook registration internals. */
static int static int
register_hook_internal(struct sudo_hook_list *head, register_hook_internal(struct sudo_hook_list *head,
int (*hook_fn)(), void *closure) sudo_hook_fn_t hook_fn, void *closure)
{ {
struct sudo_hook_entry *hook; struct sudo_hook_entry *hook;
debug_decl(register_hook_internal, SUDO_DEBUG_HOOKS); debug_decl(register_hook_internal, SUDO_DEBUG_HOOKS);
@ -185,7 +185,7 @@ register_hook(struct sudo_hook *hook)
/* Hook deregistration internals. */ /* Hook deregistration internals. */
static void static void
deregister_hook_internal(struct sudo_hook_list *head, deregister_hook_internal(struct sudo_hook_list *head,
int (*hook_fn)(), void *closure) sudo_hook_fn_t hook_fn, void *closure)
{ {
struct sudo_hook_entry *hook, *prev = NULL; struct sudo_hook_entry *hook, *prev = NULL;
debug_decl(deregister_hook_internal, SUDO_DEBUG_HOOKS); debug_decl(deregister_hook_internal, SUDO_DEBUG_HOOKS);

View File

@ -622,10 +622,13 @@ get_user_info(struct user_details *ud)
if (ttydev != (dev_t)-1) { if (ttydev != (dev_t)-1) {
if (asprintf(&info[++i], "ttydev=%lld", (long long)ttydev) == -1) if (asprintf(&info[++i], "ttydev=%lld", (long long)ttydev) == -1)
goto oom; goto oom;
info[++i] = sudo_new_key_val("tty", path); /* The terminal device file may be missing in a chroot() jail. */
if (info[i] == NULL) if (path[0] != '\0') {
goto oom; info[++i] = sudo_new_key_val("tty", path);
ud->tty = info[i] + sizeof("tty=") - 1; if (info[i] == NULL)
goto oom;
ud->tty = info[i] + sizeof("tty=") - 1;
}
} else { } else {
/* tty may not always be present */ /* tty may not always be present */
if (errno != ENOENT) if (errno != ENOENT)

View File

@ -94,8 +94,10 @@
#if defined(sudo_kp_tdev) #if defined(sudo_kp_tdev)
/* /*
* Store the name of the tty to which the process is attached in name. * Look up terminal device that the process is attached to and
* Returns name on success and NULL on failure, setting errno. * fill in its name, if available. Sets name to the empty string
* if the device number cannot be mapped to a device name.
* Returns the tty device number on success and -1 on failure, setting errno.
*/ */
dev_t dev_t
get_process_ttyname(char *name, size_t namelen) get_process_ttyname(char *name, size_t namelen)
@ -135,10 +137,11 @@ get_process_ttyname(char *name, size_t namelen)
errno = serrno; errno = serrno;
ttydev = (dev_t)ki_proc->sudo_kp_tdev; ttydev = (dev_t)ki_proc->sudo_kp_tdev;
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)major(ttydev), (unsigned int)minor(ttydev)); (unsigned int)major(ttydev), (unsigned int)minor(ttydev));
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
} }
} else { } else {
@ -151,8 +154,10 @@ get_process_ttyname(char *name, size_t namelen)
} }
#elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) #elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV)
/* /*
* Store the name of the tty to which the process is attached in name. * Look up terminal device that the process is attached to and
* Returns name on success and NULL on failure, setting errno. * fill in its name, if available. Sets name to the empty string
* if the device number cannot be mapped to a device name.
* Returns the tty device number on success and -1 on failure, setting errno.
*/ */
dev_t dev_t
get_process_ttyname(char *name, size_t namelen) get_process_ttyname(char *name, size_t namelen)
@ -179,10 +184,11 @@ get_process_ttyname(char *name, size_t namelen)
if (ttydev != 0 && ttydev != (dev_t)-1) { if (ttydev != 0 && ttydev != (dev_t)-1) {
errno = serrno; errno = serrno;
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)major(ttydev), (unsigned int)minor(ttydev)); (unsigned int)major(ttydev), (unsigned int)minor(ttydev));
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
goto done; goto done;
} }
@ -197,10 +203,11 @@ get_process_ttyname(char *name, size_t namelen)
if (sudo_isatty(i, &sb)) { if (sudo_isatty(i, &sb)) {
ttydev = sb.st_rdev; ttydev = sb.st_rdev;
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)major(ttydev), (unsigned int)minor(ttydev)); (unsigned int)major(ttydev), (unsigned int)minor(ttydev));
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
goto done; goto done;
} }
@ -217,8 +224,10 @@ done:
} }
#elif defined(__linux__) #elif defined(__linux__)
/* /*
* Store the name of the tty to which the process is attached in name. * Look up terminal device that the process is attached to and
* Returns name on success and NULL on failure, setting errno. * fill in its name, if available. Sets name to the empty string
* if the device number cannot be mapped to a device name.
* Returns the tty device number on success and -1 on failure, setting errno.
*/ */
dev_t dev_t
get_process_ttyname(char *name, size_t namelen) get_process_ttyname(char *name, size_t namelen)
@ -282,10 +291,11 @@ get_process_ttyname(char *name, size_t namelen)
ttydev = (unsigned int)tty_nr; ttydev = (unsigned int)tty_nr;
errno = serrno; errno = serrno;
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)major(ttydev), (unsigned int)minor(ttydev)); (unsigned int)major(ttydev), (unsigned int)minor(ttydev));
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
goto done; goto done;
} }
@ -310,10 +320,11 @@ get_process_ttyname(char *name, size_t namelen)
if (sudo_isatty(i, &sb)) { if (sudo_isatty(i, &sb)) {
ttydev = sb.st_rdev; ttydev = sb.st_rdev;
if (sudo_ttyname_dev(sb.st_rdev, name, namelen) == NULL) { if (sudo_ttyname_dev(sb.st_rdev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)major(ttydev), (unsigned int)minor(ttydev)); (unsigned int)major(ttydev), (unsigned int)minor(ttydev));
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
goto done; goto done;
} }
@ -332,8 +343,10 @@ done:
} }
#elif defined(HAVE_PSTAT_GETPROC) #elif defined(HAVE_PSTAT_GETPROC)
/* /*
* Store the name of the tty to which the process is attached in name. * Look up terminal device that the process is attached to and
* Returns name on success and NULL on failure, setting errno. * fill in its name, if available. Sets name to the empty string
* if the device number cannot be mapped to a device name.
* Returns the tty device number on success and -1 on failure, setting errno.
*/ */
dev_t dev_t
get_process_ttyname(char *name, size_t namelen) get_process_ttyname(char *name, size_t namelen)
@ -354,11 +367,12 @@ get_process_ttyname(char *name, size_t namelen)
errno = serrno; errno = serrno;
ttydev = makedev(pst.pst_term.psd_major, pst.pst_term.psd_minor); ttydev = makedev(pst.pst_term.psd_major, pst.pst_term.psd_minor);
if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) { if (sudo_ttyname_dev(ttydev, name, namelen) == NULL) {
sudo_warnx( sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
U_("unable to find terminal name for device %u, %u"), "unable to find terminal name for device %u, %u",
(unsigned int)pst.pst_term.psd_major, (unsigned int)pst.pst_term.psd_major,
(unsigned int)pst.pst_term.psd_minor); (unsigned int)pst.pst_term.psd_minor);
ttydev = (dev_t)-1; if (namelen != 0)
*name = '\0';
} }
goto done; goto done;
} }
@ -373,8 +387,8 @@ done:
} }
#else #else
/* /*
* Store the name of the tty to which the process is attached in name. * Look up terminal device that the process is attached to and fill in name.
* Returns name on success and NULL on failure, setting errno. * Returns the tty device number on success and -1 on failure, setting errno.
*/ */
dev_t dev_t
get_process_ttyname(char *name, size_t namelen) get_process_ttyname(char *name, size_t namelen)