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