mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Add a new "devsearch" Path setting to sudo.conf for configuring the
/dev paths to traverse instead of hard-coding a list in ttyname.c The default value can be set at configure time.
This commit is contained in:
parent
777abca382
commit
cc71b99849
6
INSTALL
6
INSTALL
@ -368,6 +368,12 @@ Operating system-specific options:
|
||||
Enable the creation of an Ubuntu-style admin flag file
|
||||
the first time sudo is run.
|
||||
|
||||
--enable-devsearch=PATH
|
||||
Set a system-specific search path of directories to look in
|
||||
for device nodes. Sudo uses this when mapping the process's
|
||||
tty device number to a device name. The default value is:
|
||||
/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
|
||||
|
||||
--with-bsm-audit
|
||||
Enable support for sudo BSM audit logs on systems that support it.
|
||||
This includes recent versions of FreeBSD, Mac OS X and Solaris.
|
||||
|
23
configure
vendored
Normal file → Executable file
23
configure
vendored
Normal file → Executable file
@ -722,6 +722,7 @@ timeout
|
||||
vardir
|
||||
rundir
|
||||
iolog_dir
|
||||
devsearch
|
||||
FILEDIGEST
|
||||
exampledir
|
||||
TMPFILES_D
|
||||
@ -959,6 +960,7 @@ enable_rpath
|
||||
enable_static_sudoers
|
||||
enable_shared_libutil
|
||||
enable_tmpfiles_d
|
||||
enable_devsearch
|
||||
with_selinux
|
||||
enable_gss_krb5_ccache_name
|
||||
enable_shared
|
||||
@ -1641,6 +1643,8 @@ Optional Features:
|
||||
--disable-shared-libutil
|
||||
Disable use of the libsudo_util shared library.
|
||||
--enable-tmpfiles.d=DIR Set the path to the systemd tmpfiles.d directory.
|
||||
--enable-devsearch=PATH The colon-delimited path to search for device nodes
|
||||
when determing the tty name.
|
||||
--enable-gss-krb5-ccache-name
|
||||
Use GSS-API to set the Kerberos V cred cache name
|
||||
--enable-shared[=PKGS] build shared libraries [default=yes]
|
||||
@ -3051,6 +3055,7 @@ $as_echo "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
@ -3098,6 +3103,7 @@ pam_session=on
|
||||
pam_login_service=sudo
|
||||
PLUGINDIR=/usr/local/libexec/sudo
|
||||
FILEDIGEST=filedigest.lo
|
||||
devsearch="/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev"
|
||||
#
|
||||
# End initial values for man page substitution
|
||||
#
|
||||
@ -6664,6 +6670,23 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --enable-devsearch was given.
|
||||
if test "${enable_devsearch+set}" = set; then :
|
||||
enableval=$enable_devsearch; case $enableval in
|
||||
yes) # use default value
|
||||
;;
|
||||
no) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring attempt to disable the device search path" >&5
|
||||
$as_echo "$as_me: WARNING: Ignoring attempt to disable the device search path" >&2;}
|
||||
;;
|
||||
*) devsearch="$enableval"
|
||||
esac
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<EOF
|
||||
#define _PATH_SUDO_DEVSEARCH "$devsearch"
|
||||
EOF
|
||||
|
||||
|
||||
|
||||
# Check whether --with-selinux was given.
|
||||
if test "${with_selinux+set}" = set; then :
|
||||
|
13
configure.ac
13
configure.ac
@ -97,6 +97,7 @@ AC_SUBST([COMPAT_EXP])
|
||||
AC_SUBST([TMPFILES_D])
|
||||
AC_SUBST([exampledir])
|
||||
AC_SUBST([FILEDIGEST])
|
||||
AC_SUBST([devsearch])
|
||||
dnl
|
||||
dnl Variables that get substituted in docs (not overridden by environment)
|
||||
dnl
|
||||
@ -185,6 +186,7 @@ pam_session=on
|
||||
pam_login_service=sudo
|
||||
PLUGINDIR=/usr/local/libexec/sudo
|
||||
FILEDIGEST=filedigest.lo
|
||||
devsearch="/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev"
|
||||
#
|
||||
# End initial values for man page substitution
|
||||
#
|
||||
@ -1531,6 +1533,17 @@ esac], [
|
||||
test -f /usr/lib/tmpfiles.d/systemd.conf && TMPFILES_D=/usr/lib/tmpfiles.d
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(devsearch,
|
||||
[AS_HELP_STRING([--enable-devsearch=PATH], [The colon-delimited path to search for device nodes when determing the tty name.])],
|
||||
[case $enableval in
|
||||
yes) # use default value
|
||||
;;
|
||||
no) AC_MSG_WARN([Ignoring attempt to disable the device search path])
|
||||
;;
|
||||
*) devsearch="$enableval"
|
||||
esac])
|
||||
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_DEVSEARCH, "$devsearch")
|
||||
|
||||
AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support])],
|
||||
[case $with_selinux in
|
||||
yes) SELINUX_USAGE="[[-r role]] [[-t type]] "
|
||||
|
@ -106,6 +106,15 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
_a_s_k_p_a_s_s may be overridden by the SUDO_ASKPASS environment
|
||||
variable.
|
||||
|
||||
devsearch
|
||||
An ordered, colon-separated search path of directories to look
|
||||
in for device nodes. This is used when mapping the process's
|
||||
tty device number to a device name. Sudo will _n_o_t recurse into
|
||||
subdirectories. If terminal devices may be located in a
|
||||
subdirectory of _/_d_e_v, that path must be explicitly listed in
|
||||
_d_e_v_s_e_a_r_c_h. The default value is:
|
||||
/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
|
||||
|
||||
noexec The fully-qualified path to a shared library containing
|
||||
wrappers for the eexxeeccll(), eexxeeccllee(), eexxeeccllpp(), eexxeecctt(), eexxeeccvv(),
|
||||
eexxeeccvvee(), eexxeeccvvPP(), eexxeeccvvpp(), eexxeeccvvppee(), ffeexxeeccvvee(), ppooppeenn(),
|
||||
@ -418,4 +427,4 @@ DDIISSCCLLAAIIMMEERR
|
||||
file distributed with ssuuddoo or https://www.sudo.ws/license.html for
|
||||
complete details.
|
||||
|
||||
Sudo 1.8.20 October 15, 2016 Sudo 1.8.20
|
||||
Sudo 1.8.21 May 30, 2017 Sudo 1.8.21
|
||||
|
@ -1,7 +1,7 @@
|
||||
.\" DO NOT EDIT THIS FILE, IT IS NOT THE MASTER!
|
||||
.\" IT IS GENERATED AUTOMATICALLY FROM sudo.conf.mdoc.in
|
||||
.\"
|
||||
.\" Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
.\" Copyright (c) 2010-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -16,7 +16,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.TH "SUDO.CONF" "5" "October 15, 2016" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO.CONF" "5" "May 30, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -238,6 +238,21 @@ may be overridden by the
|
||||
\fRSUDO_ASKPASS\fR
|
||||
environment variable.
|
||||
.TP 10n
|
||||
devsearch
|
||||
.br
|
||||
An ordered, colon-separated search path of directories to look in for
|
||||
device nodes.
|
||||
This is used when mapping the process's tty device number to a device name.
|
||||
Sudo will
|
||||
\fInot\fR
|
||||
recurse into subdirectories.
|
||||
If terminal devices may be located in a subdirectory of
|
||||
\fI/dev\fR,
|
||||
that path must be explicitly listed in
|
||||
\fIdevsearch\fR.
|
||||
The default value is:
|
||||
\fR/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev\fR
|
||||
.TP 10n
|
||||
noexec
|
||||
The fully-qualified path to a shared library containing wrappers
|
||||
for the
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2010-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
.\" Copyright (c) 2010-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software for any
|
||||
.\" purpose with or without fee is hereby granted, provided that the above
|
||||
@ -14,7 +14,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd October 15, 2016
|
||||
.Dd May 30, 2017
|
||||
.Dt SUDO.CONF @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -215,6 +215,19 @@ The value of
|
||||
may be overridden by the
|
||||
.Ev SUDO_ASKPASS
|
||||
environment variable.
|
||||
.It devsearch
|
||||
An ordered, colon-separated search path of directories to look in for
|
||||
device nodes.
|
||||
This is used when mapping the process's tty device number to a device name.
|
||||
Sudo will
|
||||
.Em not
|
||||
recurse into subdirectories.
|
||||
If terminal devices may be located in a subdirectory of
|
||||
.Pa /dev ,
|
||||
that path must be explicitly listed in
|
||||
.Em devsearch .
|
||||
The default value is:
|
||||
.Li /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
|
||||
.It noexec
|
||||
The fully-qualified path to a shared library containing wrappers
|
||||
for the
|
||||
|
@ -59,6 +59,7 @@ __dso_public const char *sudo_conf_askpass_path_v1(void);
|
||||
__dso_public const char *sudo_conf_sesh_path_v1(void);
|
||||
__dso_public const char *sudo_conf_noexec_path_v1(void);
|
||||
__dso_public const char *sudo_conf_plugin_dir_path_v1(void);
|
||||
__dso_public const char *sudo_conf_devsearch_path_v1(void);
|
||||
__dso_public struct sudo_conf_debug_list *sudo_conf_debugging_v1(void);
|
||||
__dso_public struct sudo_conf_debug_file_list *sudo_conf_debug_files_v1(const char *progname);
|
||||
__dso_public struct plugin_info_list *sudo_conf_plugins_v1(void);
|
||||
@ -71,6 +72,7 @@ __dso_public void sudo_conf_clear_paths_v1(void);
|
||||
#define sudo_conf_sesh_path() sudo_conf_sesh_path_v1()
|
||||
#define sudo_conf_noexec_path() sudo_conf_noexec_path_v1()
|
||||
#define sudo_conf_plugin_dir_path() sudo_conf_plugin_dir_path_v1()
|
||||
#define sudo_conf_devsearch_path() sudo_conf_devsearch_path_v1()
|
||||
#define sudo_conf_debugging() sudo_conf_debugging_v1()
|
||||
#define sudo_conf_debug_files(_a) sudo_conf_debug_files_v1((_a))
|
||||
#define sudo_conf_plugins() sudo_conf_plugins_v1()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 2009-2017 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -99,6 +99,7 @@ static struct sudo_conf_table sudo_conf_var_table[] = {
|
||||
#define SUDO_CONF_PATH_SESH 1
|
||||
#define SUDO_CONF_PATH_NOEXEC 2
|
||||
#define SUDO_CONF_PATH_PLUGIN_DIR 3
|
||||
#define SUDO_CONF_PATH_DEVSEARCH 4
|
||||
|
||||
static struct sudo_conf_data {
|
||||
bool disable_coredump;
|
||||
@ -107,7 +108,7 @@ static struct sudo_conf_data {
|
||||
int max_groups;
|
||||
struct sudo_conf_debug_list debugging;
|
||||
struct plugin_info_list plugins;
|
||||
struct sudo_conf_path_table path_table[5];
|
||||
struct sudo_conf_path_table path_table[6];
|
||||
} sudo_conf_data = {
|
||||
true,
|
||||
true,
|
||||
@ -120,6 +121,7 @@ static struct sudo_conf_data {
|
||||
{ "sesh", sizeof("sesh") - 1, false, _PATH_SUDO_SESH },
|
||||
{ "noexec", sizeof("noexec") - 1, false, _PATH_SUDO_NOEXEC },
|
||||
{ "plugin_dir", sizeof("plugin_dir") - 1, false, _PATH_SUDO_PLUGIN_DIR },
|
||||
{ "devsearch", sizeof("devsearch") - 1, false, _PATH_SUDO_DEVSEARCH },
|
||||
{ NULL }
|
||||
}
|
||||
};
|
||||
@ -451,6 +453,12 @@ sudo_conf_plugin_dir_path_v1(void)
|
||||
return sudo_conf_data.path_table[SUDO_CONF_PATH_PLUGIN_DIR].pval;
|
||||
}
|
||||
|
||||
const char *
|
||||
sudo_conf_devsearch_path_v1(void)
|
||||
{
|
||||
return sudo_conf_data.path_table[SUDO_CONF_PATH_DEVSEARCH].pval;
|
||||
}
|
||||
|
||||
int
|
||||
sudo_conf_group_source_v1(void)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ sudo_conf_disable_coredump_v1
|
||||
sudo_conf_group_source_v1
|
||||
sudo_conf_max_groups_v1
|
||||
sudo_conf_noexec_path_v1
|
||||
sudo_conf_devsearch_path_v1
|
||||
sudo_conf_plugin_dir_path_v1
|
||||
sudo_conf_plugins_v1
|
||||
sudo_conf_probe_interfaces_v1
|
||||
|
@ -123,6 +123,10 @@
|
||||
# undef _PATH_SUDO_PLUGIN_DIR
|
||||
#endif /* _PATH_SUDO_PLUGIN_DIR */
|
||||
|
||||
#ifndef _PATH_SUDO_DEVSEARCH
|
||||
# undef _PATH_SUDO_DEVSEARCH
|
||||
#endif /* _PATH_SUDO_DEVSEARCH */
|
||||
|
||||
#ifndef _PATH_VI
|
||||
# undef _PATH_VI
|
||||
#endif /* _PATH_VI */
|
||||
|
176
src/ttyname.c
176
src/ttyname.c
@ -62,12 +62,6 @@
|
||||
|
||||
#include "sudo.h"
|
||||
|
||||
#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN) && HAVE_STRUCT_DIRENT_D_NAMLEN
|
||||
# define NAMLEN(dirent) (dirent)->d_namlen
|
||||
#else
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* How to access the tty device number in struct kinfo_proc.
|
||||
*/
|
||||
@ -145,22 +139,9 @@ sudo_ttyname_dev(dev_t tdev, char *name, size_t namelen)
|
||||
}
|
||||
#elif defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || defined(HAVE_PSTAT_GETPROC) || defined(__linux__)
|
||||
/*
|
||||
* Device nodes and directories to search before searching all of /dev
|
||||
* Device nodes to ignore.
|
||||
*/
|
||||
static char *search_devs[] = {
|
||||
"/dev/console",
|
||||
"/dev/pts/", /* POSIX pty */
|
||||
"/dev/vt/", /* Solaris virtual console */
|
||||
"/dev/term/", /* Solaris serial ports */
|
||||
"/dev/zcons/", /* Solaris zone console */
|
||||
"/dev/pty/", /* HP-UX old-style pty */
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Device nodes to ignore when searching all of /dev
|
||||
*/
|
||||
static char *ignore_devs[] = {
|
||||
static const char *ignore_devs[] = {
|
||||
"/dev/stdin",
|
||||
"/dev/stdout",
|
||||
"/dev/stderr",
|
||||
@ -207,7 +188,7 @@ sudo_ttyname_scan(const char *dir, dev_t rdev, char *name, size_t namelen)
|
||||
"scanning for dev %u in %s", (unsigned int)rdev, dir);
|
||||
|
||||
sdlen = strlen(dir);
|
||||
if (dir[sdlen - 1] == '/')
|
||||
while (sdlen > 0 && dir[sdlen - 1] == '/')
|
||||
sdlen--;
|
||||
if (sdlen + 1 >= sizeof(pathbuf)) {
|
||||
errno = ERANGE;
|
||||
@ -215,32 +196,33 @@ sudo_ttyname_scan(const char *dir, dev_t rdev, char *name, size_t namelen)
|
||||
}
|
||||
memcpy(pathbuf, dir, sdlen);
|
||||
pathbuf[sdlen++] = '/';
|
||||
pathbuf[sdlen] = '\0';
|
||||
|
||||
while ((dp = readdir(d)) != NULL) {
|
||||
struct stat sb;
|
||||
size_t d_len, len;
|
||||
|
||||
/* Skip anything starting with "." */
|
||||
if (dp->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
d_len = NAMLEN(dp);
|
||||
if (sdlen + d_len >= sizeof(pathbuf))
|
||||
pathbuf[sdlen] = '\0';
|
||||
if (strlcat(pathbuf, dp->d_name, sizeof(pathbuf)) >= sizeof(pathbuf)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"%s%s is too big to fit in pathbuf", pathbuf, dp->d_name);
|
||||
continue;
|
||||
memcpy(&pathbuf[sdlen], dp->d_name, d_len + 1); /* copy NUL too */
|
||||
d_len += sdlen;
|
||||
}
|
||||
|
||||
/* Ignore device nodes listed in ignore_devs[]. */
|
||||
for (i = 0; ignore_devs[i] != NULL; i++) {
|
||||
len = strlen(ignore_devs[i]);
|
||||
if (ignore_devs[i][len - 1] == '/')
|
||||
len--;
|
||||
if (d_len == len && strncmp(pathbuf, ignore_devs[i], len) == 0)
|
||||
if (strcmp(pathbuf, ignore_devs[i]) == 0)
|
||||
break;
|
||||
}
|
||||
if (ignore_devs[i] != NULL)
|
||||
if (ignore_devs[i] != NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
|
||||
"ignoring %s", pathbuf);
|
||||
continue;
|
||||
# if defined(HAVE_STRUCT_DIRENT_D_TYPE) && defined(DTTOIF)
|
||||
}
|
||||
|
||||
# if defined(HAVE_STRUCT_DIRENT_D_TYPE)
|
||||
/*
|
||||
* Avoid excessive stat() calls by checking dp->d_type.
|
||||
*/
|
||||
@ -248,18 +230,19 @@ sudo_ttyname_scan(const char *dir, dev_t rdev, char *name, size_t namelen)
|
||||
case DT_CHR:
|
||||
case DT_LNK:
|
||||
case DT_UNKNOWN:
|
||||
/* Could be a character device, stat() it. */
|
||||
if (stat(pathbuf, &sb) == -1)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
/* Not a character device or link, skip it. */
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
|
||||
"skipping non-device %s", pathbuf);
|
||||
continue;
|
||||
}
|
||||
# else
|
||||
if (stat(pathbuf, &sb) == -1)
|
||||
continue;
|
||||
# endif
|
||||
if (stat(pathbuf, &sb) == -1) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
"unable to stat %s", pathbuf);
|
||||
continue;
|
||||
}
|
||||
if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"resolved dev %u as %s", (unsigned int)rdev, pathbuf);
|
||||
@ -281,67 +264,88 @@ done:
|
||||
debug_return_str(ret);
|
||||
}
|
||||
|
||||
static char *
|
||||
sudo_dev_check(dev_t rdev, const char *devname, char *buf, size_t buflen)
|
||||
{
|
||||
struct stat sb;
|
||||
debug_decl(sudo_dev_check, SUDO_DEBUG_UTIL)
|
||||
|
||||
if (stat(devname, &sb) == 0) {
|
||||
if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"comparing dev %u to %s: match!",
|
||||
(unsigned int)rdev, devname);
|
||||
if (strlcpy(buf, devname, buflen) < buflen)
|
||||
debug_return_str(buf);
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to store %s, have %zu, need %zu",
|
||||
devname, buflen, strlen(devname) + 1);
|
||||
errno = ERANGE;
|
||||
}
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"comparing dev %u to %s: no", (unsigned int)rdev, devname);
|
||||
debug_return_str(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like ttyname() but uses a dev_t instead of an open fd.
|
||||
* Returns name on success and NULL on failure, setting errno.
|
||||
* Generic version.
|
||||
*/
|
||||
static char *
|
||||
sudo_ttyname_dev(dev_t rdev, char *name, size_t namelen)
|
||||
sudo_ttyname_dev(dev_t rdev, char *buf, size_t buflen)
|
||||
{
|
||||
char buf[PATH_MAX], **sd, *devname;
|
||||
char *ret = NULL;
|
||||
struct stat sb;
|
||||
const char *devsearch, *devsearch_end;
|
||||
char path[PATH_MAX], *ret;
|
||||
const char *cp, *ep;
|
||||
size_t len;
|
||||
debug_decl(sudo_ttyname_dev, SUDO_DEBUG_UTIL)
|
||||
|
||||
/*
|
||||
* First check search_devs[] for common tty devices.
|
||||
* First, check /dev/console.
|
||||
*/
|
||||
for (sd = search_devs; (devname = *sd) != NULL; sd++) {
|
||||
len = strlen(devname);
|
||||
if (devname[len - 1] == '/') {
|
||||
if (strcmp(devname, "/dev/pts/") == 0) {
|
||||
/* Special case /dev/pts */
|
||||
(void)snprintf(buf, sizeof(buf), "%spts/%u", _PATH_DEV,
|
||||
(unsigned int)minor(rdev));
|
||||
if (stat(buf, &sb) == 0) {
|
||||
if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"comparing dev %u to %s: match!",
|
||||
(unsigned int)rdev, buf);
|
||||
if (strlcpy(name, buf, namelen) < namelen)
|
||||
ret = name;
|
||||
else
|
||||
errno = ERANGE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"comparing dev %u to %s: no", (unsigned int)rdev, buf);
|
||||
} else {
|
||||
/* Traverse directory */
|
||||
ret = sudo_ttyname_scan(devname, rdev, name, namelen);
|
||||
if (ret != NULL || errno == ENOMEM)
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
if (stat(devname, &sb) == 0) {
|
||||
if (S_ISCHR(sb.st_mode) && sb.st_rdev == rdev) {
|
||||
if (strlcpy(name, devname, namelen) < namelen)
|
||||
ret = name;
|
||||
else
|
||||
errno = ERANGE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = sudo_dev_check(rdev, "/dev/console", buf, buflen);
|
||||
if (ret != NULL)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Not found? Check all device nodes in /dev.
|
||||
* Then check the device search path.
|
||||
*/
|
||||
ret = sudo_ttyname_scan(_PATH_DEV, rdev, name, namelen);
|
||||
devsearch = sudo_conf_devsearch_path();
|
||||
devsearch_end = devsearch + strlen(devsearch);
|
||||
for (cp = sudo_strsplit(devsearch, devsearch_end, ":", &ep);
|
||||
cp != NULL; cp = sudo_strsplit(NULL, devsearch_end, ":", &ep)) {
|
||||
|
||||
len = (size_t)(ep - cp);
|
||||
if (len >= sizeof(path)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"devsearch entry %.*s too long", (int)len, cp);
|
||||
continue;
|
||||
}
|
||||
memcpy(path, cp, len);
|
||||
path[len] = '\0';
|
||||
|
||||
if (strcmp(path, "/dev/pts") == 0) {
|
||||
/* Special case /dev/pts */
|
||||
len = (size_t)snprintf(path, sizeof(path), "/dev/pts/%u",
|
||||
(unsigned int)minor(rdev));
|
||||
if (len >= sizeof(path)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"devsearch entry /dev/pts/%u too long",
|
||||
(unsigned int)minor(rdev));
|
||||
continue;
|
||||
}
|
||||
ret = sudo_dev_check(rdev, path, buf, buflen);
|
||||
if (ret != NULL)
|
||||
goto done;
|
||||
} else {
|
||||
/* Scan path, looking for rdev. */
|
||||
ret = sudo_ttyname_scan(path, rdev, buf, buflen);
|
||||
if (ret != NULL || errno == ENOMEM)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
debug_return_str(ret);
|
||||
|
Loading…
x
Reference in New Issue
Block a user