Implement memset_s() and use it instead of zero_bytes().
A new constant, SUDO_CONV_REPL_MAX, is defined by the plugin API as the max conversation reply length. This constant can be used as a max value for memset_s() when clearing passwords filled in by the conversation function.
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -45,7 +45,6 @@ common/sudo_debug.c
|
||||
common/sudo_printf.c
|
||||
common/term.c
|
||||
common/ttysize.c
|
||||
common/zero_bytes.c
|
||||
compat/Makefile.in
|
||||
compat/charclass.h
|
||||
compat/closefrom.c
|
||||
@@ -66,6 +65,7 @@ compat/glob.c
|
||||
compat/glob.h
|
||||
compat/isblank.c
|
||||
compat/memrchr.c
|
||||
compat/memset_s.c
|
||||
compat/mksiglist.c
|
||||
compat/mksiglist.h
|
||||
compat/mksigname.c
|
||||
|
@@ -68,7 +68,7 @@ SHELL = @SHELL@
|
||||
|
||||
LTOBJS = alloc.lo atobool.lo error.lo fileops.lo fmt_string.lo lbuf.lo list.lo \
|
||||
secure_path.lo setgroups.lo sudo_conf.lo sudo_debug.lo sudo_printf.lo \
|
||||
term.lo ttysize.lo zero_bytes.lo @COMMON_OBJS@
|
||||
term.lo ttysize.lo @COMMON_OBJS@
|
||||
|
||||
PARSELN_TEST_OBJS = parseln_test.lo
|
||||
|
||||
@@ -218,6 +218,3 @@ term.lo: $(srcdir)/term.c $(top_builddir)/config.h $(incdir)/missing.h \
|
||||
ttysize.lo: $(srcdir)/ttysize.c $(top_builddir)/config.h $(incdir)/missing.h \
|
||||
$(incdir)/sudo_debug.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ttysize.c
|
||||
zero_bytes.lo: $(srcdir)/zero_bytes.c $(top_builddir)/config.h \
|
||||
$(incdir)/missing.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/zero_bytes.c
|
||||
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005, 2007, 2010
|
||||
* 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
|
||||
* 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 <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "missing.h"
|
||||
|
||||
/*
|
||||
* Like bzero(3) but with a volatile pointer. The hope is that
|
||||
* the compiler will not be able to optimize away this function.
|
||||
*/
|
||||
void
|
||||
zero_bytes(volatile void *v, size_t n)
|
||||
{
|
||||
volatile char *p, *ep;
|
||||
|
||||
for (p = v, ep = p + n; p < ep; p++)
|
||||
*p = 0;
|
||||
return;
|
||||
}
|
@@ -199,6 +199,8 @@ isblank.lo: $(srcdir)/isblank.c $(top_builddir)/config.h $(incdir)/missing.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/isblank.c
|
||||
memrchr.lo: $(srcdir)/memrchr.c $(top_builddir)/config.h $(incdir)/missing.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/memrchr.c
|
||||
memset_s.lo: $(srcdir)/memset_s.c $(top_builddir)/config.h $(incdir)/missing.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/memset_s.c
|
||||
mksiglist.lo: $(srcdir)/mksiglist.c $(top_builddir)/config.h \
|
||||
$(incdir)/missing.h $(top_srcdir)/compat/mksiglist.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/mksiglist.c
|
||||
|
71
compat/memset_s.c
Normal file
71
compat/memset_s.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2013 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
|
||||
* 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 <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include "missing.h"
|
||||
|
||||
#ifndef RSIZE_MAX
|
||||
# if defined(SIZE_MAX)
|
||||
# define RSIZE_MAX (SIZE_MAX >> 1)
|
||||
# elif defined(__LP64__)
|
||||
# define RSIZE_MAX 0x7fffffffffffffffUL
|
||||
# else
|
||||
# define RSIZE_MAX 0x7fffffffU
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Simple implementation of C11 memset_s() function.
|
||||
* We use a volatile pointer when updating the byte string.
|
||||
* Most compilers will avoid optimizing away access to a
|
||||
* volatile pointer, even if the pointer appears to be unused
|
||||
* after the call.
|
||||
*
|
||||
* Note that C11 does not specify the return value on error, only
|
||||
* that it be non-zero. We use EINVAL for all errors.
|
||||
*/
|
||||
errno_t
|
||||
memset_s(void *v, rsize_t smax, int c, rsize_t n)
|
||||
{
|
||||
errno_t ret = 0;
|
||||
volatile unsigned char *s = v;
|
||||
|
||||
/* Fatal runtime-constraint violations. */
|
||||
if (s == NULL || smax > RSIZE_MAX) {
|
||||
ret = errno = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
/* Non-fatal runtime-constraint violation, n must not exceed smax. */
|
||||
if (n > smax) {
|
||||
n = smax;
|
||||
ret = errno = EINVAL;
|
||||
}
|
||||
/* Updating through a volatile pointer should not be optimized away. */
|
||||
while (n--)
|
||||
*s++ = (unsigned char)c;
|
||||
done:
|
||||
return ret;
|
||||
}
|
@@ -373,6 +373,9 @@
|
||||
/* Define to 1 if you have the `memrchr' function. */
|
||||
#undef HAVE_MEMRCHR
|
||||
|
||||
/* Define to 1 if you have the `memset_s' function. */
|
||||
#undef HAVE_MEMSET_S
|
||||
|
||||
/* Define to 1 if you have the `mkdtemp' function. */
|
||||
#undef HAVE_MKDTEMP
|
||||
|
||||
@@ -948,6 +951,9 @@
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef dev_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef errno_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
@@ -960,6 +966,9 @@
|
||||
/* Define to an OS-specific initialization function or `os_init_common'. */
|
||||
#undef os_init
|
||||
|
||||
/* Define to `size_t' if <sys/types.h> does not define. */
|
||||
#undef rsize_t
|
||||
|
||||
/* Define to `int' if <signal.h> does not define. */
|
||||
#undef sig_atomic_t
|
||||
|
||||
|
48
configure
vendored
48
configure
vendored
@@ -15979,6 +15979,19 @@ fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
case "${CPPFLAGS}" in
|
||||
*"-D__STDC_WANT_LIB_EXT1__=1"|*"-D__STDC_WANT_LIB_EXT1__=1 ")
|
||||
;;
|
||||
*)
|
||||
if test X"${CPPFLAGS}" = X""; then
|
||||
CPPFLAGS="-D__STDC_WANT_LIB_EXT1__=1"
|
||||
else
|
||||
CPPFLAGS="${CPPFLAGS} -D__STDC_WANT_LIB_EXT1__=1"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_mode_t" = xyes; then :
|
||||
|
||||
@@ -16299,6 +16312,28 @@ else
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "rsize_t" "ac_cv_type_rsize_t" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_rsize_t" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define rsize_t size_t
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_type "$LINENO" "errno_t" "ac_cv_type_errno_t" "$ac_includes_default"
|
||||
if test "x$ac_cv_type_errno_t" = xyes; then :
|
||||
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define errno_t int
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking max length of uid_t" >&5
|
||||
$as_echo_n "checking max length of uid_t... " >&6; }
|
||||
@@ -17543,6 +17578,19 @@ esac
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "memset_s" "ac_cv_func_memset_s"
|
||||
if test "x$ac_cv_func_memset_s" = xyes; then :
|
||||
$as_echo "#define HAVE_MEMSET_S 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" memset_s.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS memset_s.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "pw_dup" "ac_cv_func_pw_dup"
|
||||
if test "x$ac_cv_func_pw_dup" = xyes; then :
|
||||
$as_echo "#define HAVE_PW_DUP 1" >>confdefs.h
|
||||
|
@@ -2143,7 +2143,9 @@ if test ${with_project-'no'} != "no"; then
|
||||
fi
|
||||
dnl
|
||||
dnl typedef checks
|
||||
dnl We need to define __STDC_WANT_LIB_EXT1__ for errno_t and rsize_t
|
||||
dnl
|
||||
SUDO_APPEND_CPPFLAGS(-D__STDC_WANT_LIB_EXT1__=1)
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_UID_T
|
||||
AC_CHECK_TYPE([__signed char], [], [AC_CHECK_TYPE([signed char], [AC_DEFINE(__signed, signed)], [AC_DEFINE(__signed, [])])])
|
||||
@@ -2173,6 +2175,8 @@ AC_CHECK_TYPE(uint64_t, unsigned long long)
|
||||
AC_CHECK_TYPE(socklen_t, [], [AC_DEFINE(socklen_t, unsigned int)], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#include <sys/socket.h>])
|
||||
AC_CHECK_TYPE(rsize_t, size_t)
|
||||
AC_CHECK_TYPE(errno_t, int)
|
||||
SUDO_UID_T_LEN
|
||||
SUDO_SOCK_SA_LEN
|
||||
dnl
|
||||
@@ -2348,7 +2352,7 @@ SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [AC_LIBOBJ(fnmatch)
|
||||
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }fnm_test"
|
||||
])
|
||||
SUDO_FUNC_ISBLANK
|
||||
AC_REPLACE_FUNCS(getopt_long memrchr pw_dup strlcpy strlcat)
|
||||
AC_REPLACE_FUNCS(getopt_long memrchr memset_s pw_dup strlcpy strlcat)
|
||||
AC_CHECK_FUNCS(nanosleep, [], [
|
||||
# On Solaris, nanosleep is in librt
|
||||
AC_CHECK_LIB(rt, nanosleep, [REPLAY_LIBS="${REPLAY_LIBS} -lrt"], [AC_LIBOBJ(nanosleep)])
|
||||
|
@@ -1229,6 +1229,8 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
#define SUDO_CONV_REPL_MAX 255
|
||||
|
||||
struct sudo_conv_reply {
|
||||
char *reply;
|
||||
};
|
||||
@@ -1246,7 +1248,12 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
sudo_conv_message and sudo_conv_reply structures. There must be a struct
|
||||
sudo_conv_message and struct sudo_conv_reply for each message in the
|
||||
conversation. The plugin is responsible for freeing the reply buffer
|
||||
filled in to the struct sudo_conv_reply, if any.
|
||||
located in each struct sudo_conv_reply, if it is not NULL.
|
||||
SUDO_CONV_REPL_MAX represents the maximum length of the reply buffer (not
|
||||
including the trailing NUL character). In practical terms, this is the
|
||||
longest password ssuuddoo will support. It is also useful as a maximum value
|
||||
for the mmeemmsseett__ss() function when clearing passwords filled in by the
|
||||
conversation function.
|
||||
|
||||
The pprriinnttff()-style function uses the same underlying mechanism as the
|
||||
ccoonnvveerrssaattiioonn() function but only supports SUDO_CONV_INFO_MSG,
|
||||
|
@@ -107,15 +107,15 @@ to determine the API version the plugin was
|
||||
built against.
|
||||
.TP 6n
|
||||
open
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t plugin_printf, char * const settings[],
|
||||
char * const user_info[], char * const user_env[],
|
||||
char * const plugin_options[]);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
Returns 1 on success, 0 on failure, \-1 if a general error occurred,
|
||||
or \-2 if there was a usage error.
|
||||
@@ -156,7 +156,7 @@ settings
|
||||
A vector of user-supplied
|
||||
\fBsudo\fR
|
||||
settings in the form of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
The vector is terminated by a
|
||||
\fRNULL\fR
|
||||
@@ -171,23 +171,20 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
itself but the
|
||||
\fIvalue\fR
|
||||
might.
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.RS
|
||||
.TP 6n
|
||||
bsdauth_type=string
|
||||
Authentication type, if specified by the
|
||||
\fB\-a\fR
|
||||
flag, to use on
|
||||
systems where BSD authentication is supported.
|
||||
.PD
|
||||
.TP 6n
|
||||
closefrom=number
|
||||
If specified, the user has requested via the
|
||||
@@ -218,7 +215,7 @@ plugin is
|
||||
\fIsubsystem\fR@\fIpriority\fR
|
||||
but the plugin is free to use a different
|
||||
format so long as it does not include a comma
|
||||
(\(oq,\&\(cq).
|
||||
(`,\&').
|
||||
There is not currently a way to specify a set of debug flags specific
|
||||
to the plugin--the flags are shared by
|
||||
\fBsudo\fR
|
||||
@@ -274,13 +271,13 @@ sudo.conf(@mansectform@).
|
||||
network_addrs=list
|
||||
A space-separated list of IP network addresses and netmasks in the
|
||||
form
|
||||
\(lqaddr/netmask\(rq,
|
||||
``addr/netmask'',
|
||||
e.g.\&
|
||||
\(lq192.168.1.2/255.255.255.0\(rq.
|
||||
``192.168.1.2/255.255.255.0''.
|
||||
The address and netmask pairs may be either IPv4 or IPv6, depending on
|
||||
what the operating system supports.
|
||||
If the address contains a colon
|
||||
(\(oq:\&\(cq),
|
||||
(`:\&'),
|
||||
it is an IPv6 address, else it is IPv4.
|
||||
.TP 6n
|
||||
noninteractive=bool
|
||||
@@ -315,9 +312,9 @@ based on the runas user.
|
||||
.TP 6n
|
||||
progname=string
|
||||
The command name that sudo was run as, typically
|
||||
\(lqsudo\(rq
|
||||
``sudo''
|
||||
or
|
||||
\(lqsudoedit\(rq.
|
||||
``sudoedit''.
|
||||
.TP 6n
|
||||
prompt=string
|
||||
The prompt to use when requesting a password, if specified via
|
||||
@@ -391,11 +388,13 @@ section.
|
||||
.PP
|
||||
Additional settings may be added in the future so the plugin should
|
||||
silently ignore settings that it does not recognize.
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
user_info
|
||||
A vector of information about the user running the command in the form of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
The vector is terminated by a
|
||||
\fRNULL\fR
|
||||
@@ -406,21 +405,19 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
itself but the
|
||||
\fIvalue\fR
|
||||
might.
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.RS
|
||||
.PD
|
||||
.TP 6n
|
||||
cols=int
|
||||
The number of columns the user's terminal supports.
|
||||
If there is no terminal device available, a default value of 80 is used.
|
||||
.PD
|
||||
.TP 6n
|
||||
cwd=string
|
||||
The user's current working directory.
|
||||
@@ -516,7 +513,7 @@ tty=string
|
||||
The path to the user's terminal device.
|
||||
If the user has no terminal device associated with the session,
|
||||
the value will be empty, as in
|
||||
\(lq\fRtty=\fR\(rq.
|
||||
``\fRtty=\fR''.
|
||||
.TP 6n
|
||||
uid=uid_t
|
||||
The real user ID of the user invoking
|
||||
@@ -525,15 +522,14 @@ The real user ID of the user invoking
|
||||
user=string
|
||||
The name of the user invoking
|
||||
\fBsudo\fR.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
user_env
|
||||
The user's environment in the form of a
|
||||
\fRNULL\fR-terminated vector of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
.sp
|
||||
When parsing
|
||||
@@ -541,26 +537,26 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
itself but the
|
||||
\fIvalue\fR
|
||||
might.
|
||||
.PD 0
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
close
|
||||
.br
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*close)(int exit_status, int error);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBclose\fR()
|
||||
@@ -569,6 +565,7 @@ function is called when the command being run by
|
||||
finishes.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
exit_status
|
||||
The command's exit status, as returned by the
|
||||
@@ -609,15 +606,17 @@ list, the
|
||||
\fBsudo\fR
|
||||
front end may execute the command directly instead of running
|
||||
it as a child process.
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
show_version
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*show_version)(int verbose);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBshow_version\fR()
|
||||
@@ -634,17 +633,20 @@ or
|
||||
function using
|
||||
\fRSUDO_CONV_INFO_MSG\fR.
|
||||
If the user requests detailed version information, the verbose flag will be set.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
check_policy
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*check_policy)(int argc, char * const argv[]
|
||||
char *env_add[], char **command_info[],
|
||||
char **argv_out[], char **user_env_out[]);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBcheck_policy\fR()
|
||||
@@ -686,10 +688,10 @@ into
|
||||
\fIargv_out\fR,
|
||||
separated from the
|
||||
editor and its arguments by a
|
||||
\(lq\fR--\fR\(rq
|
||||
``\fR--\fR''
|
||||
element.
|
||||
The
|
||||
\(lq\fR--\fR\(rq
|
||||
``\fR--\fR''
|
||||
will
|
||||
be removed by
|
||||
\fBsudo\fR
|
||||
@@ -720,6 +722,7 @@ function with
|
||||
to present additional error information to the user.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
argc
|
||||
The number of elements in
|
||||
@@ -742,7 +745,7 @@ Additional environment variables specified by the user on the command
|
||||
line in the form of a
|
||||
\fRNULL\fR-terminated
|
||||
vector of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
The plugin may reject the command if one or more variables
|
||||
are not allowed to be set, or it may silently ignore such variables.
|
||||
@@ -752,7 +755,7 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
@@ -762,7 +765,7 @@ might.
|
||||
.TP 6n
|
||||
command_info
|
||||
Information about the command being run in the form of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
These values are used by
|
||||
\fBsudo\fR
|
||||
@@ -774,13 +777,10 @@ which must be terminated with a
|
||||
pointer.
|
||||
The following values are recognized by
|
||||
\fBsudo\fR:
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.RS
|
||||
.TP 6n
|
||||
chroot=string
|
||||
The root directory to use when running the command.
|
||||
.PD
|
||||
.TP 6n
|
||||
closefrom=number
|
||||
If specified,
|
||||
@@ -995,7 +995,9 @@ will base the new entry on
|
||||
the invoking user's existing entry.
|
||||
.PP
|
||||
Unsupported values will be ignored.
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
argv_out
|
||||
The
|
||||
@@ -1004,25 +1006,25 @@ argument vector to pass to the
|
||||
execve(2)
|
||||
system call when executing the command.
|
||||
The plugin is responsible for allocating and populating the vector.
|
||||
.PD
|
||||
.TP 6n
|
||||
user_env_out
|
||||
The
|
||||
\fRNULL\fR-terminated
|
||||
environment vector to use when executing the command.
|
||||
The plugin is responsible for allocating and populating the vector.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
list
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*list)(int verbose, const char *list_user,
|
||||
int argc, char * const argv[]);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
List available privileges for the invoking user.
|
||||
Returns 1 on success, 0 on failure and \-1 on error.
|
||||
@@ -1041,6 +1043,7 @@ or
|
||||
\fBplugin_printf\fR()
|
||||
function using
|
||||
\fRSUDO_CONV_INFO_MSG\fR,
|
||||
.PD
|
||||
.TP 6n
|
||||
verbose
|
||||
Flag indicating whether to list in verbose mode or not.
|
||||
@@ -1069,18 +1072,17 @@ execve(2)
|
||||
system call.
|
||||
If the command is permitted by the policy, the fully-qualified path
|
||||
to the command should be displayed along with any command line arguments.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
validate
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*validate)(void);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBvalidate\fR()
|
||||
@@ -1110,15 +1112,18 @@ function with
|
||||
\fRSUDO_CONF_ERROR_MSG\fR
|
||||
to present additional
|
||||
error information to the user.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
invalidate
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*invalidate)(int remove);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBinvalidate\fR()
|
||||
@@ -1145,15 +1150,18 @@ The
|
||||
function should be
|
||||
\fRNULL\fR
|
||||
if the plugin does not support credential caching.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
init_session
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*init_session)(struct passwd *pwd, char **user_envp[);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBinit_session\fR()
|
||||
@@ -1186,7 +1194,7 @@ argument points to the environment the command will
|
||||
run in, in the form of a
|
||||
\fRNULL\fR-terminated
|
||||
vector of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
This is the same string passed back to the front end via
|
||||
the Policy Plugin's
|
||||
@@ -1222,16 +1230,19 @@ function with
|
||||
\fRSUDO_CONF_ERROR_MSG\fR
|
||||
to present additional
|
||||
error information to the user.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
register_hooks
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*register_hooks)(int version,
|
||||
int (*register_hook)(struct sudo_hook *hook));
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBregister_hooks\fR()
|
||||
@@ -1274,16 +1285,19 @@ front end doesn't support API
|
||||
version 1.2 or higher,
|
||||
\fRregister_hooks\fR
|
||||
will not be called.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
deregister_hooks
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*deregister_hooks)(int version,
|
||||
int (*deregister_hook)(struct sudo_hook *hook));
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBderegister_hooks\fR()
|
||||
@@ -1328,6 +1342,7 @@ version 1.2 or higher,
|
||||
\fRderegister_hooks\fR
|
||||
will not be called.
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
\fIPolicy Plugin Version Macros\fR
|
||||
.nf
|
||||
@@ -1428,15 +1443,15 @@ to determine the API version the plugin was
|
||||
built against.
|
||||
.TP 6n
|
||||
open
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t plugin_printf, char * const settings[],
|
||||
char * const user_info[], int argc, char * const argv[],
|
||||
char * const user_env[], char * const plugin_options[]);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBopen\fR()
|
||||
@@ -1506,7 +1521,7 @@ settings
|
||||
A vector of user-supplied
|
||||
\fBsudo\fR
|
||||
settings in the form of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
The vector is terminated by a
|
||||
\fRNULL\fR
|
||||
@@ -1521,7 +1536,7 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
@@ -1535,7 +1550,7 @@ section for a list of all possible settings.
|
||||
.TP 6n
|
||||
user_info
|
||||
A vector of information about the user running the command in the form of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
The vector is terminated by a
|
||||
\fRNULL\fR
|
||||
@@ -1546,7 +1561,7 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
@@ -1577,7 +1592,7 @@ user_env
|
||||
The user's environment in the form of a
|
||||
\fRNULL\fR-terminated
|
||||
vector of
|
||||
\(lqname=value\(rq
|
||||
``name=value''
|
||||
strings.
|
||||
.sp
|
||||
When parsing
|
||||
@@ -1585,7 +1600,7 @@ When parsing
|
||||
the plugin should split on the
|
||||
\fBfirst\fR
|
||||
equal sign
|
||||
(\(oq=\(cq)
|
||||
(`=')
|
||||
since the
|
||||
\fIname\fR
|
||||
field will never include one
|
||||
@@ -1618,19 +1633,18 @@ by the
|
||||
front end before using
|
||||
\fIplugin_options\fR.
|
||||
Failure to do so may result in a crash.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
close
|
||||
.br
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*close)(int exit_status, int error);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBclose\fR()
|
||||
@@ -1639,6 +1653,7 @@ function is called when the command being run by
|
||||
finishes.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
exit_status
|
||||
The command's exit status, as returned by the
|
||||
@@ -1660,18 +1675,17 @@ system call.
|
||||
If the command was successfully executed, the value of
|
||||
\fRerror\fR
|
||||
is 0.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
show_version
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*show_version)(int verbose);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBshow_version\fR()
|
||||
@@ -1688,15 +1702,18 @@ or
|
||||
function using
|
||||
\fRSUDO_CONV_INFO_MSG\fR.
|
||||
If the user requests detailed version information, the verbose flag will be set.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
log_ttyin
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*log_ttyin)(const char *buf, unsigned int len);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBlog_ttyin\fR()
|
||||
@@ -1708,6 +1725,7 @@ Returns 1 if the data should be passed to the command, 0 if the data
|
||||
is rejected (which will terminate the command) or \-1 if an error occurred.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
buf
|
||||
The buffer containing user input.
|
||||
@@ -1716,18 +1734,17 @@ len
|
||||
The length of
|
||||
\fIbuf\fR
|
||||
in bytes.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
log_ttyout
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*log_ttyout)(const char *buf, unsigned int len);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBlog_ttyout\fR()
|
||||
@@ -1739,6 +1756,7 @@ Returns 1 if the data should be passed to the user, 0 if the data is rejected
|
||||
(which will terminate the command) or \-1 if an error occurred.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
buf
|
||||
The buffer containing command output.
|
||||
@@ -1747,18 +1765,17 @@ len
|
||||
The length of
|
||||
\fIbuf\fR
|
||||
in bytes.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
log_stdin
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*log_stdin)(const char *buf, unsigned int len);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBlog_stdin\fR()
|
||||
@@ -1772,6 +1789,7 @@ Returns 1 if the data should be passed to the command, 0 if the data is
|
||||
rejected (which will terminate the command) or \-1 if an error occurred.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
buf
|
||||
The buffer containing user input.
|
||||
@@ -1780,18 +1798,17 @@ len
|
||||
The length of
|
||||
\fIbuf\fR
|
||||
in bytes.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
log_stdout
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*log_stdout)(const char *buf, unsigned int len);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBlog_stdout\fR()
|
||||
@@ -1805,6 +1822,7 @@ Returns 1 if the data should be passed to the user, 0 if the data is
|
||||
rejected (which will terminate the command) or \-1 if an error occurred.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
buf
|
||||
The buffer containing command output.
|
||||
@@ -1813,18 +1831,17 @@ len
|
||||
The length of
|
||||
\fIbuf\fR
|
||||
in bytes.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
log_stderr
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*log_stderr)(const char *buf, unsigned int len);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBlog_stderr\fR()
|
||||
@@ -1838,6 +1855,7 @@ Returns 1 if the data should be passed to the user, 0 if the data is
|
||||
rejected (which will terminate the command) or \-1 if an error occurred.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
buf
|
||||
The buffer containing command output.
|
||||
@@ -1846,16 +1864,16 @@ len
|
||||
The length of
|
||||
\fIbuf\fR
|
||||
in bytes.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
register_hooks
|
||||
See the
|
||||
\fIPolicy plugin API\fR
|
||||
section for a description of
|
||||
\fRregister_hooks\fR.
|
||||
.PD
|
||||
.TP 6n
|
||||
deregister_hooks
|
||||
See the
|
||||
@@ -1962,9 +1980,7 @@ hook_type
|
||||
The
|
||||
\fRhook_type\fR
|
||||
field may be one of the following supported hook types:
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.RS
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_SETENV\fR
|
||||
The C library
|
||||
@@ -1975,19 +1991,20 @@ The
|
||||
\fRhook_fn\fR
|
||||
field should
|
||||
be a function that matches the following typedef:
|
||||
.RS
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
typedef int (*sudo_hook_fn_setenv_t)(const char *name,
|
||||
const char *value, int overwrite, void *closure);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
If the registered hook does not match the typedef the results are
|
||||
unspecified.
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_UNSETENV\fR
|
||||
The C library
|
||||
@@ -1998,13 +2015,18 @@ The
|
||||
\fRhook_fn\fR
|
||||
field should
|
||||
be a function that matches the following typedef:
|
||||
.RS
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
|
||||
void *closure);
|
||||
.RE
|
||||
.fi
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_GETENV\fR
|
||||
The C library
|
||||
@@ -2015,18 +2037,21 @@ The
|
||||
\fRhook_fn\fR
|
||||
field should
|
||||
be a function that matches the following typedef:
|
||||
.RS
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
typedef int (*sudo_hook_fn_getenv_t)(const char *name,
|
||||
char **value, void *closure);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
If the registered hook does not match the typedef the results are
|
||||
unspecified.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_PUTENV\fR
|
||||
The C library
|
||||
@@ -2037,22 +2062,22 @@ The
|
||||
\fRhook_fn\fR
|
||||
field should
|
||||
be a function that matches the following typedef:
|
||||
.RS
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
typedef int (*sudo_hook_fn_putenv_t)(char *string,
|
||||
void *closure);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
If the registered hook does not match the typedef the results are
|
||||
unspecified.
|
||||
.RE
|
||||
.PD 0
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
hook_fn
|
||||
sudo_hook_fn_t hook_fn;
|
||||
@@ -2073,13 +2098,11 @@ is passed as the last function parameter.
|
||||
This can be used to pass arbitrary data to the plugin's hook implementation.
|
||||
.sp
|
||||
The function return value may be one of the following:
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.RS
|
||||
.PD
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_RET_ERROR\fR
|
||||
The hook function encountered an error.
|
||||
.PD
|
||||
.TP 6n
|
||||
\fRSUDO_HOOK_RET_NEXT\fR
|
||||
The hook completed without error, go on to the next hook (including
|
||||
@@ -2099,10 +2122,7 @@ hook that operates on a private copy of
|
||||
the environment but leaves
|
||||
\fRenviron\fR
|
||||
unchanged.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
Note that it is very easy to create an infinite loop when hooking
|
||||
C library functions.
|
||||
@@ -2184,6 +2204,8 @@ struct sudo_conv_message {
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
#define SUDO_CONV_REPL_MAX 255
|
||||
|
||||
struct sudo_conv_reply {
|
||||
char *reply;
|
||||
};
|
||||
@@ -2218,9 +2240,19 @@ and
|
||||
\fRstruct sudo_conv_reply\fR
|
||||
for
|
||||
each message in the conversation.
|
||||
The plugin is responsible for freeing the reply buffer filled in to the
|
||||
The plugin is responsible for freeing the reply buffer located in each
|
||||
\fRstruct sudo_conv_reply\fR,
|
||||
if any.
|
||||
if it is not
|
||||
\fRNULL\fR.
|
||||
\fRSUDO_CONV_REPL_MAX\fR
|
||||
represents the maximum length of the reply buffer (not including
|
||||
the trailing NUL character).
|
||||
In practical terms, this is the longest password
|
||||
\fBsudo\fR
|
||||
will support.
|
||||
It is also useful as a maximum value for the
|
||||
\fBmemset_s\fR()
|
||||
function when clearing passwords filled in by the conversation function.
|
||||
.PP
|
||||
The
|
||||
\fBprintf\fR()-style
|
||||
@@ -2313,13 +2345,13 @@ to determine the API version the group plugin
|
||||
was built against.
|
||||
.TP 6n
|
||||
init
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*init)(int version, sudo_printf_t plugin_printf,
|
||||
char *const argv[]);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBinit\fR()
|
||||
@@ -2362,18 +2394,17 @@ If no arguments were given,
|
||||
\fIargv\fR
|
||||
will be
|
||||
\fRNULL\fR.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PD 0
|
||||
.TP 6n
|
||||
cleanup
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
void (*cleanup)();
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBcleanup\fR()
|
||||
@@ -2382,17 +2413,20 @@ function is called when
|
||||
has finished its
|
||||
group checks.
|
||||
The plugin should free any memory it has allocated and close open file handles.
|
||||
.PD
|
||||
.PP
|
||||
.RE
|
||||
.PD 0
|
||||
.TP 6n
|
||||
query
|
||||
.br
|
||||
.RS
|
||||
.nf
|
||||
.RS 6n
|
||||
.RS 0n
|
||||
int (*query)(const char *user, const char *group,
|
||||
const struct passwd *pwd);
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The
|
||||
\fBquery\fR()
|
||||
@@ -2402,6 +2436,7 @@ is a member of
|
||||
\fIgroup\fR.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.PD
|
||||
.TP 6n
|
||||
user
|
||||
The name of the user being looked up in the external group database.
|
||||
@@ -2421,10 +2456,7 @@ present in the password database,
|
||||
\fIpwd\fR
|
||||
will be
|
||||
\fRNULL\fR.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
\fIGroup API Version Macros\fR
|
||||
.nf
|
||||
@@ -2537,7 +2569,7 @@ search the archives.
|
||||
.SH "DISCLAIMER"
|
||||
\fBsudo\fR
|
||||
is provided
|
||||
\(lqAS IS\(rq
|
||||
``AS IS''
|
||||
and any express or implied warranties, including, but not limited
|
||||
to, the implied warranties of merchantability and fitness for a
|
||||
particular purpose are disclaimed.
|
||||
|
@@ -1893,6 +1893,8 @@ struct sudo_conv_message {
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
#define SUDO_CONV_REPL_MAX 255
|
||||
|
||||
struct sudo_conv_reply {
|
||||
char *reply;
|
||||
};
|
||||
@@ -1926,9 +1928,19 @@ and
|
||||
.Li struct sudo_conv_reply
|
||||
for
|
||||
each message in the conversation.
|
||||
The plugin is responsible for freeing the reply buffer filled in to the
|
||||
The plugin is responsible for freeing the reply buffer located in each
|
||||
.Li struct sudo_conv_reply ,
|
||||
if any.
|
||||
if it is not
|
||||
.Dv NULL .
|
||||
.Dv SUDO_CONV_REPL_MAX
|
||||
represents the maximum length of the reply buffer (not including
|
||||
the trailing NUL character).
|
||||
In practical terms, this is the longest password
|
||||
.Nm sudo
|
||||
will support.
|
||||
It is also useful as a maximum value for the
|
||||
.Fn memset_s
|
||||
function when clearing passwords filled in by the conversation function.
|
||||
.Pp
|
||||
The
|
||||
.Fn printf Ns No -style
|
||||
|
@@ -384,6 +384,9 @@ size_t strlcpy(char *, const char *, size_t);
|
||||
#ifndef HAVE_MEMRCHR
|
||||
void *memrchr(const void *, int, size_t);
|
||||
#endif
|
||||
#ifndef HAVE_MEMSET_S
|
||||
errno_t memset_s(void *, rsize_t, int, rsize_t);
|
||||
#endif
|
||||
#ifndef HAVE_MKDTEMP
|
||||
char *mkdtemp(char *);
|
||||
#endif
|
||||
|
@@ -47,6 +47,17 @@ struct sudo_conv_message {
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
/*
|
||||
* Maximum length of a reply (not including the trailing NUL) when
|
||||
* conversing with the user. In practical terms, this is the longest
|
||||
* password sudo will support. This means that a buffer of size
|
||||
* SUDO_CONV_REPL_MAX+1 is guaranteed to be able to hold any reply
|
||||
* from the conversation function. It is also useful as a max value
|
||||
* for memset_s() when clearing passwords returned by the conversation
|
||||
* function.
|
||||
*/
|
||||
#define SUDO_CONV_REPL_MAX 255
|
||||
|
||||
struct sudo_conv_reply {
|
||||
char *reply;
|
||||
};
|
||||
|
2
mkdep.pl
2
mkdep.pl
@@ -70,7 +70,7 @@ sub mkdep {
|
||||
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo sssd.lo:;
|
||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
|
||||
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo getopt_long.lo glob.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo utimes.lo globtest.o fnm_test.o:;
|
||||
|
||||
# Parse OBJS lines
|
||||
my %objs;
|
||||
|
@@ -786,7 +786,7 @@ set_perms.lo: $(srcdir)/set_perms.c $(top_builddir)/config.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/gettext.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/set_perms.c
|
||||
sha2.lo: $(srcdir)/sha2.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/endian.h $(srcdir)/sha2.h
|
||||
$(top_srcdir)/compat/endian.h $(incdir)/missing.h $(srcdir)/sha2.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sha2.c
|
||||
sha2.o: sha2.lo
|
||||
sia.lo: $(authdir)/sia.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2005, 2007-2012 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* Copyright (c) 1999-2005, 2007-2013 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
|
||||
@@ -65,7 +65,7 @@ sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
|
||||
efree(message);
|
||||
message = NULL;
|
||||
result = authenticate(pw->pw_name, pass, &reenter, &message);
|
||||
zero_bytes(pass, strlen(pass));
|
||||
memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
|
||||
prompt = message;
|
||||
} while (reenter);
|
||||
|
||||
|
@@ -156,7 +156,7 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
|
||||
|
||||
if (pass) {
|
||||
authok = auth_userresponse(as, pass, 1);
|
||||
zero_bytes(pass, strlen(pass));
|
||||
memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
|
||||
}
|
||||
|
||||
/* restore old signal handler */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2005, 2008, 2010-2012
|
||||
* Copyright (c) 1999-2005, 2008, 2010-2013
|
||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -82,7 +82,7 @@ int
|
||||
sudo_fwtk_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
|
||||
{
|
||||
char *pass; /* Password from the user */
|
||||
char buf[SUDO_PASS_MAX + 12]; /* General prupose buffer */
|
||||
char buf[SUDO_CONV_REPL_MAX + 12]; /* General prupose buffer */
|
||||
char resp[128]; /* Response from the server */
|
||||
int error;
|
||||
debug_decl(sudo_fwtk_verify, SUDO_DEBUG_AUTH)
|
||||
@@ -139,8 +139,8 @@ restart:
|
||||
warningx("%s", resp);
|
||||
error = AUTH_FAILURE;
|
||||
done:
|
||||
zero_bytes(pass, strlen(pass));
|
||||
zero_bytes(buf, strlen(buf));
|
||||
memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
|
||||
memset_s(buf, sizeof(buf), 0, sizeof(buf));
|
||||
debug_return_int(error);
|
||||
}
|
||||
|
||||
|
@@ -312,7 +312,7 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
|
||||
|
||||
if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
|
||||
debug_return_int(PAM_SYSTEM_ERR);
|
||||
zero_bytes(*response, num_msg * sizeof(struct pam_response));
|
||||
memset(*response, 0, num_msg * sizeof(struct pam_response));
|
||||
|
||||
for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
|
||||
type = SUDO_CONV_PROMPT_ECHO_OFF;
|
||||
@@ -356,7 +356,7 @@ converse(int num_msg, PAM_CONST struct pam_message **msg,
|
||||
#endif
|
||||
}
|
||||
pr->resp = estrdup(pass);
|
||||
zero_bytes(pass, strlen(pass));
|
||||
memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
|
||||
break;
|
||||
case PAM_TEXT_INFO:
|
||||
if (pm->msg)
|
||||
@@ -380,12 +380,11 @@ done:
|
||||
/* Zero and free allocated memory and return an error. */
|
||||
for (pr = *response, n = num_msg; n--; pr++) {
|
||||
if (pr->resp != NULL) {
|
||||
zero_bytes(pr->resp, strlen(pr->resp));
|
||||
memset_s(pr->resp, SUDO_CONV_REPL_MAX, 0, strlen(pr->resp));
|
||||
free(pr->resp);
|
||||
pr->resp = NULL;
|
||||
}
|
||||
}
|
||||
zero_bytes(*response, num_msg * sizeof(struct pam_response));
|
||||
free(*response);
|
||||
*response = NULL;
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@ sudo_passwd_cleanup(pw, auth)
|
||||
debug_decl(sudo_passwd_cleanup, SUDO_DEBUG_AUTH)
|
||||
|
||||
if (pw_epasswd != NULL) {
|
||||
zero_bytes(pw_epasswd, strlen(pw_epasswd));
|
||||
memset_s(pw_epasswd, SUDO_CONV_REPL_MAX, 0, strlen(pw_epasswd));
|
||||
efree(pw_epasswd);
|
||||
}
|
||||
debug_return_int(AUTH_SUCCESS);
|
||||
|
@@ -106,7 +106,7 @@ sudo_secureware_cleanup(pw, auth)
|
||||
debug_decl(sudo_secureware_cleanup, SUDO_DEBUG_AUTH)
|
||||
|
||||
if (pw_epasswd != NULL) {
|
||||
zero_bytes(pw_epasswd, strlen(pw_epasswd));
|
||||
memset_s(pw_epasswd, SUDO_CONV_REPL_MAX, 0, strlen(pw_epasswd));
|
||||
efree(pw_epasswd);
|
||||
}
|
||||
debug_return_int(AUTH_SUCCESS);
|
||||
|
@@ -254,7 +254,7 @@ verify_user(struct passwd *pw, char *prompt, int validated)
|
||||
goto done;
|
||||
}
|
||||
if (!standalone)
|
||||
zero_bytes(p, strlen(p));
|
||||
memset_s(p, SUDO_CONV_REPL_MAX, 0, strlen(p));
|
||||
pass_warn();
|
||||
}
|
||||
|
||||
|
@@ -356,7 +356,7 @@ init_defaults(void)
|
||||
list_op(NULL, 0, def, freeall);
|
||||
break;
|
||||
}
|
||||
zero_bytes(&def->sd_un, sizeof(def->sd_un));
|
||||
memset(&def->sd_un, 0, sizeof(def->sd_un));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -609,7 +609,7 @@ send_mail(const char *fmt, ...)
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
/* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */
|
||||
zero_bytes(&sa, sizeof(sa));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_INTERRUPT;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
|
@@ -58,6 +58,7 @@
|
||||
# include "compat/endian.h"
|
||||
#endif
|
||||
|
||||
#include "missing.h"
|
||||
#include "sha2.h"
|
||||
|
||||
/*
|
||||
@@ -117,8 +118,6 @@
|
||||
#define g(i) T[(6-i)&7]
|
||||
#define h(i) T[(7-i)&7]
|
||||
|
||||
extern void zero_bytes(volatile void *, size_t);
|
||||
|
||||
void
|
||||
SHA224Init(SHA2_CTX *ctx)
|
||||
{
|
||||
@@ -249,8 +248,8 @@ SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])
|
||||
state[6] += g(0);
|
||||
state[7] += h(0);
|
||||
/* Cleanup */
|
||||
zero_bytes(T, sizeof(T));
|
||||
zero_bytes(W, sizeof(W));
|
||||
memset_s(T, sizeof(T), 0, sizeof(T));
|
||||
memset_s(W, sizeof(W), 0, sizeof(W));
|
||||
}
|
||||
|
||||
#undef S0
|
||||
@@ -466,8 +465,8 @@ SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])
|
||||
state[6] += g(0);
|
||||
state[7] += h(0);
|
||||
/* Cleanup. */
|
||||
zero_bytes(T, sizeof(T));
|
||||
zero_bytes(W, sizeof(W));
|
||||
memset_s(T, sizeof(T), 0, sizeof(T));
|
||||
memset_s(W, sizeof(W), 0, sizeof(W));
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -807,7 +807,7 @@ set_fqdn(void)
|
||||
char *p;
|
||||
debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN)
|
||||
|
||||
zero_bytes(&hint, sizeof(hint));
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
hint.ai_family = PF_UNSPEC;
|
||||
hint.ai_flags = AI_FQDN;
|
||||
if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
|
||||
|
@@ -210,14 +210,6 @@ struct sudo_user {
|
||||
#endif
|
||||
#define ROOT_GID 0
|
||||
|
||||
/*
|
||||
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
|
||||
* but that caused problems with various alternate authentication
|
||||
* methods. So, we just define our own and assume that it is >= the
|
||||
* system max.
|
||||
*/
|
||||
#define SUDO_PASS_MAX 256
|
||||
|
||||
struct lbuf;
|
||||
struct passwd;
|
||||
struct stat;
|
||||
@@ -287,9 +279,6 @@ void dump_auth_methods(void);
|
||||
/* getspwuid.c */
|
||||
char *sudo_getepw(const struct passwd *);
|
||||
|
||||
/* zero_bytes.c */
|
||||
void zero_bytes(volatile void *, size_t);
|
||||
|
||||
/* sudo_nss.c */
|
||||
void display_privs(struct sudo_nss_list *, struct passwd *);
|
||||
bool display_cmnd(struct sudo_nss_list *, struct passwd *);
|
||||
|
@@ -130,7 +130,7 @@ next_entry:
|
||||
if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
|
||||
return NULL;
|
||||
|
||||
zero_bytes(&pw, sizeof(pw));
|
||||
memset(&pw, 0, sizeof(pw));
|
||||
if ((colon = strchr(cp = colon, ':')) == NULL)
|
||||
goto next_entry;
|
||||
*colon++ = '\0';
|
||||
@@ -263,7 +263,7 @@ next_entry:
|
||||
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
|
||||
return NULL;
|
||||
|
||||
zero_bytes(&gr, sizeof(gr));
|
||||
memset(&gr, 0, sizeof(gr));
|
||||
if ((colon = strchr(cp = colon, ':')) == NULL)
|
||||
goto next_entry;
|
||||
*colon++ = '\0';
|
||||
|
@@ -741,7 +741,7 @@ setup_signals(void)
|
||||
/*
|
||||
* Setup signal handlers to cleanup nicely.
|
||||
*/
|
||||
zero_bytes(&sa, sizeof(sa));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = quit;
|
||||
|
@@ -311,7 +311,8 @@ tgetpass.o: $(srcdir)/tgetpass.c $(top_builddir)/config.h $(srcdir)/sudo.h \
|
||||
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
|
||||
$(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
|
||||
$(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_conf.h \
|
||||
$(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
|
||||
$(incdir)/list.h $(incdir)/sudo_debug.h $(incdir)/gettext.h \
|
||||
$(incdir)/sudo_plugin.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/tgetpass.c
|
||||
ttyname.o: $(srcdir)/ttyname.c $(top_builddir)/config.h $(srcdir)/sudo.h \
|
||||
$(top_builddir)/pathnames.h $(top_srcdir)/compat/stdbool.h \
|
||||
|
@@ -81,7 +81,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
||||
if (pass == NULL)
|
||||
goto err;
|
||||
repl->reply = estrdup(pass);
|
||||
zero_bytes(pass, strlen(pass));
|
||||
memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass));
|
||||
break;
|
||||
case SUDO_CONV_INFO_MSG:
|
||||
if (msg->msg)
|
||||
@@ -107,7 +107,7 @@ err:
|
||||
do {
|
||||
repl = &replies[n];
|
||||
if (repl->reply != NULL) {
|
||||
zero_bytes(repl->reply, strlen(repl->reply));
|
||||
memset_s(repl->reply, SUDO_CONV_REPL_MAX, 0, strlen(repl->reply));
|
||||
free(repl->reply);
|
||||
repl->reply = NULL;
|
||||
}
|
||||
|
11
src/sudo.h
11
src/sudo.h
@@ -75,14 +75,6 @@
|
||||
#define MODE_NONINTERACTIVE 0x00800000
|
||||
#define MODE_LONG_LIST 0x01000000
|
||||
|
||||
/*
|
||||
* We used to use the system definition of PASS_MAX or _PASSWD_LEN,
|
||||
* but that caused problems with various alternate authentication
|
||||
* methods. So, we just define our own and assume that it is >= the
|
||||
* system max.
|
||||
*/
|
||||
#define SUDO_PASS_MAX 256
|
||||
|
||||
/*
|
||||
* Flags for tgetpass()
|
||||
*/
|
||||
@@ -178,9 +170,6 @@ void cleanup(int);
|
||||
char *tgetpass(const char *, int, int);
|
||||
int tty_present(void);
|
||||
|
||||
/* zero_bytes.c */
|
||||
void zero_bytes(volatile void *, size_t);
|
||||
|
||||
/* exec.c */
|
||||
int pipe_nonblock(int fds[2]);
|
||||
int sudo_execute(struct command_details *details, struct command_status *cstat);
|
||||
|
@@ -148,14 +148,14 @@ sudo_edit(struct command_details *command_details)
|
||||
* and copy the contents of the original to it.
|
||||
*/
|
||||
tf = emalloc2(nfiles, sizeof(*tf));
|
||||
zero_bytes(tf, nfiles * sizeof(*tf));
|
||||
memset(tf, 0, nfiles * sizeof(*tf));
|
||||
for (i = 0, j = 0; i < nfiles; i++) {
|
||||
rc = -1;
|
||||
switch_user(command_details->euid, command_details->egid,
|
||||
command_details->ngroups, command_details->groups);
|
||||
if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) {
|
||||
if (ofd == -1) {
|
||||
zero_bytes(&sb, sizeof(sb)); /* new file */
|
||||
memset(&sb, 0, sizeof(sb)); /* new file */
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = fstat(ofd, &sb);
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "sudo.h"
|
||||
#include "sudo_plugin.h"
|
||||
|
||||
static volatile sig_atomic_t signo[NSIG];
|
||||
|
||||
@@ -70,7 +71,7 @@ tgetpass(const char *prompt, int timeout, int flags)
|
||||
sigaction_t savetstp, savettin, savettou, savepipe;
|
||||
char *pass;
|
||||
static const char *askpass;
|
||||
static char buf[SUDO_PASS_MAX + 1];
|
||||
static char buf[SUDO_CONV_REPL_MAX + 1];
|
||||
int i, input, output, save_errno, neednl = 0, need_restart;
|
||||
debug_decl(tgetpass, SUDO_DEBUG_CONV)
|
||||
|
||||
@@ -127,7 +128,7 @@ restart:
|
||||
* Catch signals that would otherwise cause the user to end
|
||||
* up with echo turned off in the shell.
|
||||
*/
|
||||
zero_bytes(&sa, sizeof(sa));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */
|
||||
sa.sa_handler = tgetpass_handler;
|
||||
@@ -207,7 +208,7 @@ restore:
|
||||
static char *
|
||||
sudo_askpass(const char *askpass, const char *prompt)
|
||||
{
|
||||
static char buf[SUDO_PASS_MAX + 1], *pass;
|
||||
static char buf[SUDO_CONV_REPL_MAX + 1], *pass;
|
||||
sigaction_t sa, saved_sa_pipe;
|
||||
int pfd[2];
|
||||
pid_t pid;
|
||||
@@ -242,7 +243,7 @@ sudo_askpass(const char *askpass, const char *prompt)
|
||||
}
|
||||
|
||||
/* Ignore SIGPIPE in case child exits prematurely */
|
||||
zero_bytes(&sa, sizeof(sa));
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_INTERRUPT;
|
||||
sa.sa_handler = SIG_IGN;
|
||||
|
Reference in New Issue
Block a user