mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +00:00
Merge sudo 1.9.12 from tip.
--HG-- branch : 1.9
This commit is contained in:
commit
c684bf0830
34
.github/workflows/codeql-analysis.yml
vendored
34
.github/workflows/codeql-analysis.yml
vendored
@ -13,12 +13,12 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '19 3 * * 2'
|
||||
- cron: '25 15 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
@ -34,37 +34,39 @@ jobs:
|
||||
matrix:
|
||||
language: [ 'cpp', 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
@ -30,13 +30,13 @@ for a list of packages required to build sudo.
|
||||
|
||||
## Simple sudo installation
|
||||
|
||||
0. If you are upgrading from a previous version of sudo, read
|
||||
1. If you are upgrading from a previous version of sudo, read
|
||||
[docs/UPGRADE.md](docs/UPGRADE.md) before proceeding.
|
||||
|
||||
1. Read the "OS dependent notes" section for any particular
|
||||
2. Read the "OS dependent notes" section for any particular
|
||||
"gotchas" relating to your operating system.
|
||||
|
||||
2. `cd` to the source or build directory and type `./configure`
|
||||
3. `cd` to the source or build directory and type `./configure`
|
||||
to generate a Makefile and config.h file suitable for building
|
||||
sudo. Before you actually run configure you should read the
|
||||
"Available configure options" section to see if there are
|
||||
@ -320,7 +320,7 @@ Defaults are listed in brackets after the description.
|
||||
Adds the specified library (or libraries) to SUDO_LIBS and
|
||||
and VISUDO_LIBS so sudo will link against them. If the
|
||||
library doesn't start with "-l" or end in ".a" or ".o" a
|
||||
"-l" will be pre-pended to it. Multiple libraries may be
|
||||
"-l" will be prepended to it. Multiple libraries may be
|
||||
specified as long as they are space separated.
|
||||
|
||||
--with-libtool=PATH
|
||||
|
@ -296,7 +296,7 @@ The file getentropy.c bears the following license:
|
||||
|
||||
The embedded copy of zlib bears the following license:
|
||||
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -319,7 +319,7 @@ The embedded copy of zlib bears the following license:
|
||||
|
||||
The embedded copy of protobuf-c bears the following license:
|
||||
|
||||
Copyright (c) 2008-2018, Dave Benson and the protobuf-c authors.
|
||||
Copyright (c) 2008-2022, Dave Benson and the protobuf-c authors.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
8
MANIFEST
8
MANIFEST
@ -220,6 +220,7 @@ lib/util/event_select.c
|
||||
lib/util/explicit_bzero.c
|
||||
lib/util/fatal.c
|
||||
lib/util/fchmodat.c
|
||||
lib/util/fchownat.c
|
||||
lib/util/fnmatch.c
|
||||
lib/util/freezero.c
|
||||
lib/util/fstatat.c
|
||||
@ -251,6 +252,8 @@ lib/util/mkdirat.c
|
||||
lib/util/mksiglist.c
|
||||
lib/util/mksigname.c
|
||||
lib/util/mktemp.c
|
||||
lib/util/mmap_alloc.c
|
||||
lib/util/multiarch.c
|
||||
lib/util/nanosleep.c
|
||||
lib/util/openat.c
|
||||
lib/util/parseln.c
|
||||
@ -278,6 +281,8 @@ lib/util/regress/glob/globtest.c
|
||||
lib/util/regress/glob/globtest.in
|
||||
lib/util/regress/harness.in
|
||||
lib/util/regress/mktemp/mktemp_test.c
|
||||
lib/util/regress/multiarch/multiarch_test.c
|
||||
lib/util/regress/open_parent_dir/open_parent_dir_test.c
|
||||
lib/util/regress/parse_gids/parse_gids_test.c
|
||||
lib/util/regress/progname/progname_test.c
|
||||
lib/util/regress/strsig/strsig_test.c
|
||||
@ -1018,6 +1023,8 @@ plugins/sudoers/regress/testsudoers/test17.out.ok
|
||||
plugins/sudoers/regress/testsudoers/test17.sh
|
||||
plugins/sudoers/regress/testsudoers/test18.out.ok
|
||||
plugins/sudoers/regress/testsudoers/test18.sh
|
||||
plugins/sudoers/regress/testsudoers/test19.out.ok
|
||||
plugins/sudoers/regress/testsudoers/test19.sh
|
||||
plugins/sudoers/regress/testsudoers/test2.inc
|
||||
plugins/sudoers/regress/testsudoers/test2.out.ok
|
||||
plugins/sudoers/regress/testsudoers/test2.sh
|
||||
@ -1196,6 +1203,7 @@ src/exec.c
|
||||
src/exec_common.c
|
||||
src/exec_intercept.c
|
||||
src/exec_intercept.h
|
||||
src/exec_iolog.c
|
||||
src/exec_monitor.c
|
||||
src/exec_nopty.c
|
||||
src/exec_preload.c
|
||||
|
26
Makefile.in
26
Makefile.in
@ -58,10 +58,10 @@ python_version = @PYTHON_VERSION@
|
||||
|
||||
SUBDIRS = lib/util @ZLIB_SRC@ lib/eventlog lib/fuzzstub lib/iolog \
|
||||
lib/protobuf-c @LOGSRV_SRC@ @LOGSRVD_SRC@ plugins/audit_json \
|
||||
plugins/group_file plugins/sample_approval plugins/sudoers \
|
||||
plugins/system_group @PYTHON_PLUGIN_SRC@ src include docs examples
|
||||
plugins/group_file plugins/sudoers plugins/system_group \
|
||||
@PYTHON_PLUGIN_SRC@ src include docs examples
|
||||
|
||||
SAMPLES = plugins/sample
|
||||
SAMPLES = plugins/sample plugins/sample_approval
|
||||
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
@ -70,6 +70,8 @@ LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
EGREP = @EGREP@
|
||||
GREP = @GREP@
|
||||
SED = @SED@
|
||||
|
||||
INSTALL = $(SHELL) $(scriptdir)/install-sh -c
|
||||
@ -105,19 +107,19 @@ PVS_IGNORE = 'V707,V011,V002,V536,V568'
|
||||
PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
|
||||
|
||||
all: config.status
|
||||
for d in $(SUBDIRS); do \
|
||||
for d in $(SUBDIRS) $(SAMPLES); do \
|
||||
(cd $$d && exec $(MAKE) $@) && continue; \
|
||||
exit $$?; \
|
||||
done
|
||||
|
||||
check check-verbose check-fuzzer fuzz pre-install: config.status
|
||||
for d in $(SUBDIRS); do \
|
||||
for d in $(SUBDIRS) $(SAMPLES); do \
|
||||
(cd $$d && exec $(MAKE) $@) && continue; \
|
||||
exit $$?; \
|
||||
done
|
||||
|
||||
uncrustify.files: Makefile
|
||||
grep '\.[ch]$$' $(top_srcdir)/MANIFEST | egrep -v '(/zlib/|/(arc4random|arc4random_uniform|chacha_private|charclass|fnmatch|getaddrinfo|getcwd|getdate|getentropy|getopt|getopt_long|glob|gram|inet_ntop|inet_pton|log_server.pb-c|mktemp|pw_dup|reallocarray|mktemp_test|protobuf-c|snprintf|stdbool|strlcat|strlcpy|sudo_queue|toke)\.[ch]$$)' > uncrustify.files
|
||||
$(GREP) '\.[ch]$$' $(top_srcdir)/MANIFEST | $(EGREP) -v '(/zlib/|/(arc4random|arc4random_uniform|chacha_private|charclass|fnmatch|getaddrinfo|getcwd|getdate|getentropy|getopt|getopt_long|glob|gram|inet_ntop|inet_pton|log_server.pb-c|mktemp|pw_dup|reallocarray|mktemp_test|protobuf-c|snprintf|stdbool|strlcat|strlcpy|sudo_queue|toke)\.[ch]$$)' > uncrustify.files
|
||||
|
||||
reformat: uncrustify.files
|
||||
( cd $(top_srcdir) && uncrustify -c etc/uncrustify.cfg --replace --no-backup -F $(top_builddir)/uncrustify.files )
|
||||
@ -126,11 +128,11 @@ check-format: uncrustify.files
|
||||
( cd $(top_srcdir) && uncrustify -c etc/uncrustify.cfg --check -F $(top_builddir)/uncrustify.files )
|
||||
|
||||
spell:
|
||||
( cd $(top_srcdir) && codespell -I etc/codespell.ignore -x etc/codespell.exclude `egrep -v -f etc/codespell.skip MANIFEST` )
|
||||
( cd $(top_srcdir) && codespell -I etc/codespell.ignore -x etc/codespell.exclude `$(EGREP) -v -f etc/codespell.skip MANIFEST` )
|
||||
|
||||
cppcheck: config.status
|
||||
rval=0; \
|
||||
for d in $(SUBDIRS); do \
|
||||
for d in $(SUBDIRS) $(SAMPLES); do \
|
||||
echo checking $$d; \
|
||||
(cd $$d && exec $(MAKE) CPPCHECK_OPTS="$(CPPCHECK_OPTS)" $@) || rval=`expr $$rval + $$?`; \
|
||||
done; \
|
||||
@ -138,7 +140,7 @@ cppcheck: config.status
|
||||
|
||||
splint: config.status
|
||||
rval=0; \
|
||||
for d in $(SUBDIRS); do \
|
||||
for d in $(SUBDIRS) $(SAMPLES); do \
|
||||
echo splinting $$d; \
|
||||
(cd $$d && exec $(MAKE) SPLINT_OPTS="$(SPLINT_OPTS)" $@) || rval=`expr $$rval + $$?`; \
|
||||
done; \
|
||||
@ -161,7 +163,7 @@ cov-analyze: cov-upload
|
||||
pvs-studio: config.status
|
||||
files=; \
|
||||
rval=0; \
|
||||
for d in $(SUBDIRS); do \
|
||||
for d in $(SUBDIRS) $(SAMPLES); do \
|
||||
(cd $$d && exec $(MAKE) PVS_IGNORE="$(PVS_IGNORE)" pvs-log-files) || rval=`expr $$rval + $$?`; \
|
||||
for f in $$d/*.plog; do \
|
||||
if test "$$f" != "$$d/*.plog"; then \
|
||||
@ -234,7 +236,7 @@ depend: siglist.c signame.c
|
||||
|
||||
ChangeLog:
|
||||
if test -d $(srcdir)/.hg; then \
|
||||
if hg log -R $(srcdir) --style=changelog -r "sort(branch(.) or follow(), -date)" > $@.tmp; then \
|
||||
if hg log -R $(srcdir) --template=changelog -r "sort(branch(.) or follow(), -date)" > $@.tmp; then \
|
||||
mv -f $@.tmp $(srcdir)/$@; \
|
||||
else \
|
||||
rm -f $@.tmp; \
|
||||
@ -440,4 +442,4 @@ sandwich:
|
||||
fi
|
||||
|
||||
.PHONY: clean mostlyclean distclean cleandir clobber realclean ChangeLog \
|
||||
me a sandwhich check-format reformat
|
||||
me a sandwich check-format reformat
|
||||
|
124
NEWS
124
NEWS
@ -1,3 +1,127 @@
|
||||
What's new in Sudo 1.9.12
|
||||
|
||||
* Fixed a bug in the ptrace-based intercept mode where the current
|
||||
working directory could include garbage at the end.
|
||||
|
||||
* Fixed a compilation error on systems that lack the stdint.h
|
||||
header. Bug #1035
|
||||
|
||||
* Fixed a bug when logging the command's exit status in intercept
|
||||
mode. The wrong command could be logged with the exit status.
|
||||
|
||||
* For ptrace-based intercept mode, sudo will now attempt to
|
||||
verify that the command path name, arguments and environment
|
||||
have not changed from the time when they were authorized by the
|
||||
security policy. The new "intercept_verify" sudoers setting can
|
||||
be used to control this behavior.
|
||||
|
||||
* Fixed running commands with a relative path (e.g. ./foo) in
|
||||
intercept mode. Previously, this would fail if sudo's current
|
||||
working directory was different from that of the command.
|
||||
|
||||
* Sudo now supports passing the execve(2) system call the NULL
|
||||
pointer for the `argv` and/or `envp` arguments when in intercept
|
||||
mode. Linux treats a NULL pointer like an empty array.
|
||||
|
||||
* The sudoers LDAP schema now allows sudoUser, sudoRunasUser and
|
||||
sudoRunasGroup to include UTF-8 characters, not just 7-bit ASCII.
|
||||
|
||||
* Fixed a problem with "sudo -i" on SELinux when the target user's
|
||||
home directory is not searchable by sudo. GitHub issue #160.
|
||||
|
||||
* Neovim has been added to the list of visudo editors that support
|
||||
passing the line number on the command line.
|
||||
|
||||
* Fixed a bug in sudo's SHA384 and SHA512 message digest padding.
|
||||
|
||||
* Added a new "-N" (--no-update) command line option to sudo which
|
||||
can be used to prevent sudo from updating the user's cached
|
||||
credentials. It is now possible to determine whether or not a
|
||||
user's cached credentials are currently valid by running:
|
||||
|
||||
$ sudo -Nnv
|
||||
|
||||
and checking the exit value. One use case for this is to indicate
|
||||
in a shell prompt that sudo is "active" for the user.
|
||||
|
||||
* PAM approval modules are no longer invoked when running sub-commands
|
||||
in intercept mode unless the "intercept_authenticate" option is set.
|
||||
There is a substantial performance penalty for calling into PAM
|
||||
for each command run. PAM approval modules are still called for
|
||||
the initial command.
|
||||
|
||||
* Intercept mode on Linux now uses process_vm_readv(2) and
|
||||
process_vm_writev(2) if available.
|
||||
|
||||
* The XDG_CURRENT_DESKTOP environment variable is now preserved
|
||||
by default. This makes it possible for graphical applications
|
||||
to choose the correct theme when run via sudo.
|
||||
|
||||
* On 64-bit systems, if sudo fails to load a sudoers group plugin,
|
||||
it will use system-specific heuristics to try to locate a 64-bit
|
||||
version of the plugin.
|
||||
|
||||
* The cvtsudoers manual now documents the JSON and CSV output
|
||||
formats. GitHub issue #172.
|
||||
|
||||
* Fixed a bug where sub-commands were not being logged to a remote
|
||||
log server when log_subcmds was enabled. GitHub issue #174.
|
||||
|
||||
* The new log_stdin, log_stdout, log_stderr, log_ttyin, and log_ttyout
|
||||
sudoers settings can be used to support more fine-grained I/O logging.
|
||||
The sudo front-end no longer allocates a pseudo-terminal when running
|
||||
a command if the I/O logging plugin requests logging of stdin, stdout,
|
||||
or stderr but not terminal input/output.
|
||||
|
||||
* Quieted a libgcrypt run-time initialization warning.
|
||||
This fixes Debian bug #1019428 and Ubuntu bug #1397663.
|
||||
|
||||
* Fixed a bug in visudo that caused literal backslashes to be removed
|
||||
from the EDITOR environment variable. GitHub issue #179.
|
||||
|
||||
* The sudo Python plugin now implements the "find_spec" method instead
|
||||
of the the deprecated "find_module". This fixes a test failure when
|
||||
a newer version of setuptools that doesn't include "find_module" is
|
||||
found on the system.
|
||||
|
||||
* Fixed a bug introduced in sudo 1.9.9 where sudo_logsrvd created
|
||||
the process ID file, usually /var/run/sudo/sudo_logsrvd.pid, as
|
||||
a directory instead of a plain file. The same bug could result
|
||||
in I/O log directories that end in six or more X's being created
|
||||
literally in addition to the name being used as a template for
|
||||
the mkdtemp(3) function.
|
||||
|
||||
* Fixed a long-standing bug where a sudoers rule with a command
|
||||
line argument of "", which indicates the command may be run with
|
||||
no arguments, would also match a literal "" on the command line.
|
||||
GitHub issue #182.
|
||||
|
||||
* Added the -I option to visudo which only edits the main sudoers
|
||||
file. Include files are not edited unless a syntax error is found.
|
||||
|
||||
* Fixed "sudo -l -U otheruser" output when the runas list is empty.
|
||||
Previously, sudo would list the invoking user instead of the
|
||||
list user. GitHub issue #183.
|
||||
|
||||
* Fixed the display of command tags and options in "sudo -l" output
|
||||
when the RunAs user or group changes. A new line is started for
|
||||
RunAs changes which means we need to display the command tags
|
||||
and options again. GitHub issue #184.
|
||||
|
||||
* The sesh helper program now uses getopt_long(3) to parse the
|
||||
command line options.
|
||||
|
||||
* The embedded copy of zlib has been updated to version 1.2.13.
|
||||
|
||||
* Fixed a bug that prevented event log data from being sent to the
|
||||
log server when I/O logging was not enabled. This only affected
|
||||
systems without PAM or configurations where the pam_session and
|
||||
pam_setcred options were disabled in the sudoers file.
|
||||
|
||||
* Fixed a bug where "sudo -l" output included a carriage return
|
||||
after the newline. This is only needed when displaying to a
|
||||
terminal in raw mode. Bug #1042.
|
||||
|
||||
What's new in Sudo 1.9.11p3
|
||||
|
||||
* Fixed "connection reset" errors on AIX when running shell scripts
|
||||
|
68
config.h.in
68
config.h.in
@ -298,6 +298,9 @@
|
||||
/* Define to 1 if you have the `fchmodat' function. */
|
||||
#undef HAVE_FCHMODAT
|
||||
|
||||
/* Define to 1 if you have the `fchownat' function. */
|
||||
#undef HAVE_FCHOWNAT
|
||||
|
||||
/* Define to 1 if your system has the F_CLOSEM fcntl. */
|
||||
#undef HAVE_FCNTL_CLOSEM
|
||||
|
||||
@ -599,11 +602,17 @@
|
||||
/* Define to 1 if you have the `mkdirat' function. */
|
||||
#undef HAVE_MKDIRAT
|
||||
|
||||
/* Define to 1 if you have the `mkdtemp' function. */
|
||||
#undef HAVE_MKDTEMP
|
||||
/* Define to 1 if you have the `mkdtempat' function. */
|
||||
#undef HAVE_MKDTEMPAT
|
||||
|
||||
/* Define to 1 if you have the `mkstemps' function. */
|
||||
#undef HAVE_MKSTEMPS
|
||||
/* Define to 1 if you have the `mkdtempat_np' function. */
|
||||
#undef HAVE_MKDTEMPAT_NP
|
||||
|
||||
/* Define to 1 if you have the `mkostempsat' function. */
|
||||
#undef HAVE_MKOSTEMPSAT
|
||||
|
||||
/* Define to 1 if you have the `mkostempsat_np' function. */
|
||||
#undef HAVE_MKOSTEMPSAT_NP
|
||||
|
||||
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
|
||||
#undef HAVE_MPS_LDAP_SSL_H
|
||||
@ -686,6 +695,9 @@
|
||||
/* Define to 1 if you have the `priv_set' function. */
|
||||
#undef HAVE_PRIV_SET
|
||||
|
||||
/* Define to 1 if you have the `process_vm_readv' function. */
|
||||
#undef HAVE_PROCESS_VM_READV
|
||||
|
||||
/* Define to 1 if you have the <procfs.h> header file. */
|
||||
#undef HAVE_PROCFS_H
|
||||
|
||||
@ -1448,7 +1460,53 @@
|
||||
code using `volatile' can become incorrect without. Disable with care. */
|
||||
#undef volatile
|
||||
|
||||
/* Symbol visibility controls */
|
||||
#ifndef __GNUC_PREREQ__
|
||||
# ifdef __GNUC__
|
||||
# define __GNUC_PREREQ__(ma, mi) \
|
||||
((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
|
||||
# else
|
||||
# define __GNUC_PREREQ__(ma, mi) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define away __attribute__ for non-gcc or old gcc. */
|
||||
#if !defined(__attribute__) && !__GNUC_PREREQ__(2, 5)
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* For functions that call exit() directly. */
|
||||
#if __GNUC_PREREQ__(2, 5)
|
||||
# define sudo_noreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
# define sudo_noreturn
|
||||
#endif
|
||||
|
||||
/* For malloc-like functions that return uninitialized or zeroed memory. */
|
||||
#if __GNUC_PREREQ__(2, 96)
|
||||
# define sudo_malloclike __attribute__((__malloc__))
|
||||
#else
|
||||
# define sudo_malloclike
|
||||
#endif
|
||||
|
||||
/* Compile-time checking for function arguments that must not be NULL. */
|
||||
#if __GNUC_PREREQ__(3, 3)
|
||||
# define sudo_attr_nonnull(_a) __attribute__((__nonnull__ (_a)))
|
||||
#else
|
||||
# define sudo_attr_nonnull(_a)
|
||||
#endif
|
||||
|
||||
/* For catching format string mismatches. */
|
||||
#if __GNUC_PREREQ__(2, 7)
|
||||
# define sudo_printflike(_f, _v) __attribute__((__format__ (__printf__, _f, _v))) sudo_attr_nonnull(_f)
|
||||
# define sudo_printf0like(_f, _v) __attribute__((__format__ (__printf__, _f, _v)))
|
||||
# define sudo_attr_fmt_arg(_f) __attribute__((__format_arg__ (_f)))
|
||||
#else
|
||||
# define sudo_printflike(_f, _v)
|
||||
# define sudo_printf0like(_f, _v)
|
||||
# define sudo_attr_fmt_arg(_f)
|
||||
#endif
|
||||
|
||||
/* Symbol visibility controls. */
|
||||
#ifdef HAVE_DSO_VISIBILITY
|
||||
# if defined(__GNUC__)
|
||||
# define sudo_dso_public __attribute__((__visibility__("default")))
|
||||
|
96
configure
vendored
96
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for sudo 1.9.11p3.
|
||||
# Generated by GNU Autoconf 2.71 for sudo 1.9.12.
|
||||
#
|
||||
# Report bugs to <https://bugzilla.sudo.ws/>.
|
||||
#
|
||||
@ -621,8 +621,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='sudo'
|
||||
PACKAGE_TARNAME='sudo'
|
||||
PACKAGE_VERSION='1.9.11p3'
|
||||
PACKAGE_STRING='sudo 1.9.11p3'
|
||||
PACKAGE_VERSION='1.9.12'
|
||||
PACKAGE_STRING='sudo 1.9.12'
|
||||
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1640,7 +1640,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures sudo 1.9.11p3 to adapt to many kinds of systems.
|
||||
\`configure' configures sudo 1.9.12 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1706,7 +1706,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of sudo 1.9.11p3:";;
|
||||
short | recursive ) echo "Configuration of sudo 1.9.12:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1996,7 +1996,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
sudo configure 1.9.11p3
|
||||
sudo configure 1.9.12
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@ -2653,7 +2653,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by sudo $as_me 1.9.11p3, which was
|
||||
It was created by sudo $as_me 1.9.12, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@ -17851,9 +17851,23 @@ fi
|
||||
# We use our own getentropy() by default on Linux.
|
||||
: ${ac_cv_func_getentropy='no'}
|
||||
|
||||
# The glibc arc4random() may fail in chroot on older kernels.
|
||||
# We use our own arc4random() by default on Linux.
|
||||
: ${ac_cv_func_arc4random='no'}
|
||||
|
||||
# The glibc closefrom() emulation may fail in chroot.
|
||||
# We use our own closefrom() by default on Linux.
|
||||
: ${ac_cv_func_closefrom='no'}
|
||||
|
||||
# Linux 3.2 supports reading/writing a another process
|
||||
# without using ptrace(2).
|
||||
ac_fn_c_check_func "$LINENO" "process_vm_readv" "ac_cv_func_process_vm_readv"
|
||||
if test "x$ac_cv_func_process_vm_readv" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_PROCESS_VM_READV 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
;;
|
||||
*-*-gnu*)
|
||||
# lockf() is broken on the Hurd
|
||||
@ -22733,6 +22747,32 @@ esac
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in fchownat
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "fchownat" "ac_cv_func_fchownat"
|
||||
if test "x$ac_cv_func_fchownat" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_FCHOWNAT 1" >>confdefs.h
|
||||
|
||||
else $as_nop
|
||||
|
||||
case " $LIBOBJS " in
|
||||
*" fchownat.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS fchownat.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
for _sym in sudo_fchownat; do
|
||||
COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
"
|
||||
done
|
||||
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
@ -23297,8 +23337,12 @@ fi
|
||||
fi
|
||||
|
||||
done
|
||||
sudo_mktemp=no
|
||||
case "$host_os" in
|
||||
darwin*)
|
||||
# macOS has these but uses a _np (non-portable) suffix
|
||||
|
||||
for ac_func in mkstemps mkdtemp
|
||||
for ac_func in mkdtempat_np mkostempsat_np
|
||||
do :
|
||||
as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@ -23309,11 +23353,32 @@ then :
|
||||
_ACEOF
|
||||
|
||||
else $as_nop
|
||||
break
|
||||
sudo_mktemp=yes; break
|
||||
fi
|
||||
|
||||
done
|
||||
if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
|
||||
;;
|
||||
*)
|
||||
|
||||
for ac_func in mkdtempat mkostempsat
|
||||
do :
|
||||
as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
if eval test \"x\$"$as_ac_var"\" = x"yes"
|
||||
then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1
|
||||
_ACEOF
|
||||
|
||||
else $as_nop
|
||||
sudo_mktemp=yes; break
|
||||
fi
|
||||
|
||||
done
|
||||
;;
|
||||
esac
|
||||
# If any of the mktemp family are missing we use our own.
|
||||
if test X"$sudo_mktemp" = X"yes"; then
|
||||
|
||||
for ac_func in arc4random random lrand48
|
||||
do :
|
||||
@ -23343,9 +23408,8 @@ fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If either mkdtemp() or mkstemps() is missing, replace both.
|
||||
|
||||
for _sym in sudo_mkdtemp sudo_mkstemps; do
|
||||
for _sym in sudo_mkdtemp sudo_mkdtempat sudo_mkostempsat sudo_mkstemp sudo_mkstemps; do
|
||||
COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
"
|
||||
done
|
||||
@ -32298,7 +32362,7 @@ printf "%s\n" "#define os_init $OS_INIT" >>confdefs.h
|
||||
|
||||
if test -n "$GCC"; then
|
||||
if test X"$enable_warnings" = X"yes" -o X"$with_devel" = X"yes"; then
|
||||
CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith -Wno-unknown-pragmas"
|
||||
CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith -Wno-unknown-pragmas -Wmissing-prototypes -Wwrite-strings"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wshadow" >&5
|
||||
printf %s "checking whether C compiler accepts -Wshadow... " >&6; }
|
||||
if test ${ax_cv_check_cflags___Wshadow+y}
|
||||
@ -32384,7 +32448,7 @@ printf "%s\n" "$sudo_cv_var_fallthrough_attribute" >&6; }
|
||||
if test X"$enable_werror" = X"yes"; then
|
||||
CFLAGS="${CFLAGS} -Werror"
|
||||
fi
|
||||
case "$host" in
|
||||
case "$host_os" in
|
||||
# Avoid unwanted warnings on macOS
|
||||
darwin*) CFLAGS="${CFLAGS} -Wno-deprecated-declarations";;
|
||||
esac
|
||||
@ -33050,7 +33114,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by sudo $as_me 1.9.11p3, which was
|
||||
This file was extended by sudo $as_me 1.9.12, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -33118,7 +33182,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
sudo config.status 1.9.11p3
|
||||
sudo config.status 1.9.12
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
83
configure.ac
83
configure.ac
@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
dnl
|
||||
AC_PREREQ([2.70])
|
||||
AC_INIT([sudo], [1.9.11p3], [https://bugzilla.sudo.ws/], [sudo])
|
||||
AC_INIT([sudo], [1.9.12], [https://bugzilla.sudo.ws/], [sudo])
|
||||
AC_CONFIG_HEADERS([config.h pathnames.h])
|
||||
AC_CONFIG_SRCDIR([src/sudo.c])
|
||||
AC_CONFIG_AUX_DIR([scripts])
|
||||
@ -2080,9 +2080,17 @@ case "$host" in
|
||||
# We use our own getentropy() by default on Linux.
|
||||
: ${ac_cv_func_getentropy='no'}
|
||||
|
||||
# The glibc arc4random() may fail in chroot on older kernels.
|
||||
# We use our own arc4random() by default on Linux.
|
||||
: ${ac_cv_func_arc4random='no'}
|
||||
|
||||
# The glibc closefrom() emulation may fail in chroot.
|
||||
# We use our own closefrom() by default on Linux.
|
||||
: ${ac_cv_func_closefrom='no'}
|
||||
|
||||
# Linux 3.2 supports reading/writing a another process
|
||||
# without using ptrace(2).
|
||||
AC_CHECK_FUNCS([process_vm_readv])
|
||||
;;
|
||||
*-*-gnu*)
|
||||
# lockf() is broken on the Hurd
|
||||
@ -2865,6 +2873,10 @@ AC_CHECK_FUNCS(nanosleep, [], [
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_nanosleep)
|
||||
])
|
||||
])
|
||||
AC_CHECK_FUNCS([fchownat], [], [
|
||||
AC_LIBOBJ(fchownat)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_fchownat)
|
||||
])
|
||||
AC_CHECK_FUNCS([mkdirat], [], [
|
||||
AC_LIBOBJ(mkdirat)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_mkdirat)
|
||||
@ -2949,15 +2961,24 @@ AC_CHECK_FUNCS([closefrom], [], [AC_LIBOBJ(closefrom)
|
||||
# include <fcntl.h> ])
|
||||
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }closefrom_test"
|
||||
])
|
||||
AC_CHECK_FUNCS([mkstemps mkdtemp], [], [break])
|
||||
if test X"$ac_cv_func_mkstemps$ac_cv_func_mkdtemp" != X"yesyes"; then
|
||||
sudo_mktemp=no
|
||||
case "$host_os" in
|
||||
darwin*)
|
||||
# macOS has these but uses a _np (non-portable) suffix
|
||||
AC_CHECK_FUNCS([mkdtempat_np mkostempsat_np], [], [sudo_mktemp=yes; break])
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_FUNCS([mkdtempat mkostempsat], [], [sudo_mktemp=yes; break])
|
||||
;;
|
||||
esac
|
||||
# If any of the mktemp family are missing we use our own.
|
||||
if test X"$sudo_mktemp" = X"yes"; then
|
||||
AC_CHECK_FUNCS([arc4random random lrand48], [break])
|
||||
if test X"$ac_cv_func_arc4random" != X"yes"; then
|
||||
AC_CHECK_FUNCS([getentropy])
|
||||
fi
|
||||
AC_LIBOBJ(mktemp)
|
||||
# If either mkdtemp() or mkstemps() is missing, replace both.
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkstemps)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_mkdtemp sudo_mkdtempat sudo_mkostempsat sudo_mkstemp sudo_mkstemps)
|
||||
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }mktemp_test"
|
||||
fi
|
||||
AX_FUNC_SNPRINTF
|
||||
@ -4995,7 +5016,7 @@ if test -n "$GCC"; then
|
||||
dnl
|
||||
dnl Default warnings for development use.
|
||||
dnl
|
||||
CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith -Wno-unknown-pragmas"
|
||||
CFLAGS="${CFLAGS} -Wall -Wsign-compare -Wpointer-arith -Wno-unknown-pragmas -Wmissing-prototypes -Wwrite-strings"
|
||||
AX_CHECK_COMPILE_FLAG([-Wshadow], [CFLAGS="$CFLAGS -Wshadow"])
|
||||
dnl
|
||||
dnl The fallthrough attribute is supported by gcc 7.0 and clang 10.
|
||||
@ -5032,7 +5053,7 @@ if test -n "$GCC"; then
|
||||
if test X"$enable_werror" = X"yes"; then
|
||||
CFLAGS="${CFLAGS} -Werror"
|
||||
fi
|
||||
case "$host" in
|
||||
case "$host_os" in
|
||||
# Avoid unwanted warnings on macOS
|
||||
darwin*) CFLAGS="${CFLAGS} -Wno-deprecated-declarations";;
|
||||
esac
|
||||
@ -5525,7 +5546,53 @@ dnl
|
||||
AH_TOP([#ifndef SUDO_CONFIG_H
|
||||
#define SUDO_CONFIG_H])
|
||||
|
||||
AH_BOTTOM([/* Symbol visibility controls */
|
||||
AH_BOTTOM([#ifndef __GNUC_PREREQ__
|
||||
# ifdef __GNUC__
|
||||
# define __GNUC_PREREQ__(ma, mi) \
|
||||
((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
|
||||
# else
|
||||
# define __GNUC_PREREQ__(ma, mi) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define away __attribute__ for non-gcc or old gcc. */
|
||||
#if !defined(__attribute__) && !__GNUC_PREREQ__(2, 5)
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* For functions that call exit() directly. */
|
||||
#if __GNUC_PREREQ__(2, 5)
|
||||
# define sudo_noreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
# define sudo_noreturn
|
||||
#endif
|
||||
|
||||
/* For malloc-like functions that return uninitialized or zeroed memory. */
|
||||
#if __GNUC_PREREQ__(2, 96)
|
||||
# define sudo_malloclike __attribute__((__malloc__))
|
||||
#else
|
||||
# define sudo_malloclike
|
||||
#endif
|
||||
|
||||
/* Compile-time checking for function arguments that must not be NULL. */
|
||||
#if __GNUC_PREREQ__(3, 3)
|
||||
# define sudo_attr_nonnull(_a) __attribute__((__nonnull__ (_a)))
|
||||
#else
|
||||
# define sudo_attr_nonnull(_a)
|
||||
#endif
|
||||
|
||||
/* For catching format string mismatches. */
|
||||
#if __GNUC_PREREQ__(2, 7)
|
||||
# define sudo_printflike(_f, _v) __attribute__((__format__ (__printf__, _f, _v))) sudo_attr_nonnull(_f)
|
||||
# define sudo_printf0like(_f, _v) __attribute__((__format__ (__printf__, _f, _v)))
|
||||
# define sudo_attr_fmt_arg(_f) __attribute__((__format_arg__ (_f)))
|
||||
#else
|
||||
# define sudo_printflike(_f, _v)
|
||||
# define sudo_printf0like(_f, _v)
|
||||
# define sudo_attr_fmt_arg(_f)
|
||||
#endif
|
||||
|
||||
/* Symbol visibility controls. */
|
||||
#ifdef HAVE_DSO_VISIBILITY
|
||||
# if defined(__GNUC__)
|
||||
# define sudo_dso_public __attribute__((__visibility__("default")))
|
||||
|
@ -25,6 +25,11 @@ Notes on upgrading from an older release
|
||||
such as those seen with the Linux logrotate utility, which could
|
||||
interpret a core dump as a valid configuration file.
|
||||
|
||||
To restore the historic core dump file size behavior, add the
|
||||
following line to the sudoers file:
|
||||
|
||||
Defaults rlimit_core=default
|
||||
|
||||
* Upgrading from a version prior to 1.9.7:
|
||||
|
||||
Sudo now links with OpenSSL 1.0.1 or higher by default if it
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "CVTSUDOERS" "1" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
|
||||
.TH "CVTSUDOERS" "1" "September 29, 2022" "Sudo @PACKAGE_VERSION@" "General Commands Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -67,9 +67,8 @@ The options are as follows:
|
||||
The base DN (distinguished name) that will be used when performing
|
||||
LDAP queries.
|
||||
Typically this is of the form
|
||||
\fRou=SUDOers,dc=my-domain,dc=com\fR
|
||||
for the domain
|
||||
\fRmy-domain.com\fR.
|
||||
\(lqou=SUDOers,dc=my-domain,dc=com\(rq
|
||||
for the domain my-domain.com.
|
||||
If this option is not specified, the value of the
|
||||
\fRSUDOERS_BASE\fR
|
||||
environment variable will be used instead.
|
||||
@ -82,10 +81,10 @@ Defaults to
|
||||
.TP 12n
|
||||
\fB\-d\fR \fIdeftypes\fR, \fB\--defaults\fR=\fIdeftypes\fR
|
||||
Only convert
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
entries of the specified types.
|
||||
One or more
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
types may be specified, separated by a comma
|
||||
(\(oq\&,\(cq).
|
||||
The supported types are:
|
||||
@ -122,7 +121,7 @@ for more information.
|
||||
If the
|
||||
\fB\-d\fR
|
||||
option is not specified, all
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
entries will be converted.
|
||||
.RE
|
||||
.TP 12n
|
||||
@ -143,12 +142,9 @@ The following formats are supported:
|
||||
CSV
|
||||
CSV (comma-separated value) files are often used by spreadsheets
|
||||
and report generators.
|
||||
For CSV output,
|
||||
\fBcvtsudoers\fR
|
||||
double quotes strings that contain commas.
|
||||
For each literal double quote character present inside the string,
|
||||
two double quotes are output.
|
||||
This method of quoting commas is compatible with most spreadsheet programs.
|
||||
See
|
||||
\fICSV output format\fR
|
||||
for more details.
|
||||
.PD
|
||||
.TP 10n
|
||||
JSON
|
||||
@ -160,6 +156,9 @@ The various values have explicit types which removes much of the
|
||||
ambiguity of the
|
||||
\fIsudoers\fR
|
||||
format.
|
||||
See
|
||||
\fIJSON output format\fR
|
||||
for more details.
|
||||
.TP 10n
|
||||
LDIF
|
||||
LDIF (LDAP Data Interchange Format) files can be imported into an LDAP
|
||||
@ -264,7 +263,12 @@ For example,
|
||||
\fBuser\fR = \fIoperator\fR
|
||||
or
|
||||
\fBhost\fR = \fIwww\fR.
|
||||
An upper-case Cmnd_Alias, Host_alias, or Host_Alias may be specified as the
|
||||
An upper-case
|
||||
\fICmnd_Alias\fR,
|
||||
\fIHost_alias\fR,
|
||||
or
|
||||
\fIUser_Alias\fR
|
||||
may be specified as the
|
||||
\(lqcmnd\(rq,
|
||||
\(lqhost\(rq,
|
||||
or
|
||||
@ -436,7 +440,7 @@ Per-user rules are merged and duplicates are removed.
|
||||
If a host name is specified with the input file,
|
||||
\fBcvtsudoers\fR
|
||||
will change rules that specify a host name of
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
to the host name associated with the policy file being merged.
|
||||
The merging of rules is currently fairly simplistic but will be
|
||||
improved in a later release.
|
||||
@ -522,6 +526,754 @@ command line option.
|
||||
.PP
|
||||
Options on the command line will override values from the
|
||||
configuration file.
|
||||
.SS "JSON output format"
|
||||
The
|
||||
\fIsudoers\fR
|
||||
JSON format may contain any of the following top-level objects:
|
||||
.TP 6n
|
||||
Defaults
|
||||
An array of objects, each containing an
|
||||
\fIOptions\fR
|
||||
array and an optional
|
||||
\fIBinding\fR
|
||||
array.
|
||||
.sp
|
||||
The
|
||||
\fIOptions\fR
|
||||
array consists of one or more objects, each containing a
|
||||
\(lqname:value\(rq
|
||||
pair that corresponds to a
|
||||
\fIsudoers\fR
|
||||
\fIDefaults\fR
|
||||
setting.
|
||||
\fIOptions\fR
|
||||
that operate on a list will also include an
|
||||
\fIoperation\fR
|
||||
entry in the object, with a value of
|
||||
\(lqlist_assign\(rq
|
||||
for
|
||||
\(oq=\(cq,
|
||||
\(lqlist_add\(rq
|
||||
for
|
||||
\(oq+=\(cq,
|
||||
or
|
||||
\(lqlist_remove\(rq
|
||||
for
|
||||
\(oq-=\(cq.
|
||||
.sp
|
||||
The optional
|
||||
\fIBinding\fR
|
||||
array consists of one or more objects, each containing a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
If a
|
||||
\fIBinding\fR
|
||||
is present, the setting will only take effect if one of the specified
|
||||
\fIcommand\fR,
|
||||
\fIhostname\fR,
|
||||
\fInetgroup\fR,
|
||||
\fInetworkaddr\fR,
|
||||
\fInonunixgid\fR,
|
||||
\fInonunixgroup\fR,
|
||||
\fIusergid\fR,
|
||||
\fIusergroup\fR,
|
||||
\fIuserid\fR,
|
||||
\fIusername\fR,
|
||||
or alias entries match.
|
||||
.sp
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entry:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
Defaults@somehost set_home, env_keep += DISPLAY
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
converts to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"Defaults": [
|
||||
{
|
||||
"Binding": [
|
||||
{ "hostname": "somehost" }
|
||||
],
|
||||
"Options": [
|
||||
{ "set_home": true },
|
||||
{
|
||||
"operation": "list_add",
|
||||
"env_keep": [
|
||||
"DISPLAY"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.TP 6n
|
||||
User_Aliases
|
||||
A JSON object containing one or more
|
||||
\fIsudoers\fR
|
||||
\fIUser_Alias\fR
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fInetgroup\fR,
|
||||
\fInonunixgid\fR,
|
||||
\fInonunixgroup\fR,
|
||||
\fIuseralias\fR,
|
||||
\fIusergid\fR,
|
||||
\fIusergroup\fR,
|
||||
\fIuserid\fR,
|
||||
or
|
||||
\fIusername\fR.
|
||||
.sp
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entry:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
User_Alias SYSADMIN = will, %wheel, +admin
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
converts to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"User_Aliases": {
|
||||
"SYSADMIN": [
|
||||
{ "username": "will" },
|
||||
{ "usergroup": "wheel" },
|
||||
{ "netgroup": "admin" }
|
||||
]
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.TP 6n
|
||||
Runas_Aliases
|
||||
A JSON object containing one or more
|
||||
\fIsudoers\fR
|
||||
\fIRunas_Alias\fR
|
||||
entries, where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fInetgroup\fR,
|
||||
\fInonunixgid\fR,
|
||||
\fInonunixgroup\fR,
|
||||
\fIrunasalias\fR,
|
||||
\fIusergid\fR,
|
||||
\fIusergroup\fR,
|
||||
\fIuserid\fR,
|
||||
or
|
||||
\fIusername\fR.
|
||||
.sp
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entry:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
Runas_Alias DB = oracle, sybase : OP = root, operator
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
converts to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"Runas_Aliases": {
|
||||
"DB": [
|
||||
{ "username": "oracle" },
|
||||
{ "username": "sybase" }
|
||||
],
|
||||
"OP": [
|
||||
{ "username": "root" },
|
||||
{ "username": "operator" }
|
||||
]
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.TP 6n
|
||||
Host_Aliases
|
||||
A JSON object containing one or more
|
||||
\fIsudoers\fR
|
||||
\fIHost_Alias\fR
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fIhostalias\fR,
|
||||
\fIhostname\fR,
|
||||
\fInetgroup\fR,
|
||||
or
|
||||
\fInetworkaddr\fR.
|
||||
.sp
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entries:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
Host_Alias DORMNET = 128.138.243.0, 128.138.204.0/24
|
||||
Host_Alias SERVERS = boulder, refuge
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
convert to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"Host_Aliases": {
|
||||
"DORMNET": [
|
||||
{ "networkaddr": "128.138.243.0" },
|
||||
{ "networkaddr": "128.138.204.0/24" }
|
||||
],
|
||||
"SERVERS": [
|
||||
{ "hostname": "boulder" },
|
||||
{ "hostname": "refuge" }
|
||||
]
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.TP 6n
|
||||
Cmnd_Aliases
|
||||
A JSON object containing one or more
|
||||
\fIsudoers\fR
|
||||
\fICmnd_Alias\fR
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be either another
|
||||
\fIcmndalias\fR
|
||||
or a
|
||||
\fIcommand\fR.
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entries:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
Cmnd_Alias SHELLS = /bin/bash, /bin/csh, /bin/sh, /bin/zsh
|
||||
Cmnd_Alias VIPW = /usr/bin/chpass, /usr/bin/chfn, /usr/bin/chsh, \e
|
||||
/usr/bin/passwd, /usr/sbin/vigr, /usr/sbin/vipw
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
convert to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"Cmnd_Aliases": {
|
||||
"SHELLS": [
|
||||
{ "command": "/bin/bash" },
|
||||
{ "command": "/bin/csh" },
|
||||
{ "command": "/bin/sh" },
|
||||
{ "command": "/bin/zsh" }
|
||||
],
|
||||
"VIPW": [
|
||||
{ "command": "/usr/bin/chpass" },
|
||||
{ "command": "/usr/bin/chfn" },
|
||||
{ "command": "/usr/bin/chsh" },
|
||||
{ "command": "/usr/bin/passwd" },
|
||||
{ "command": "/usr/sbin/vigr" },
|
||||
{ "command": "/usr/sbin/vipw" }
|
||||
]
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.TP 6n
|
||||
User_Specs
|
||||
A JSON array containing one or more objects, each representing a
|
||||
\fIsudoers\fR
|
||||
User_Spec.
|
||||
Each object in the
|
||||
\fIUser_Specs\fR
|
||||
array should contain a
|
||||
\fIUser_List\fR
|
||||
array, a
|
||||
\fIHost_List\fR
|
||||
array and a
|
||||
\fICmnd_Specs\fR
|
||||
array.
|
||||
.sp
|
||||
A
|
||||
\fIUser_List\fR
|
||||
consists of one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fInetgroup\fR,
|
||||
\fInonunixgid\fR,
|
||||
\fInonunixgroup\fR,
|
||||
\fIuseralias\fR,
|
||||
\fIusergid\fR,
|
||||
\fIusergroup\fR,
|
||||
\fIuserid\fR,
|
||||
or
|
||||
\fIusername\fR.
|
||||
If
|
||||
\fIusername\fR
|
||||
is set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any user.
|
||||
.sp
|
||||
A
|
||||
\fIHost_List\fR
|
||||
consists of one or more objects.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fIhostalias\fR,
|
||||
\fIhostname\fR,
|
||||
\fInetgroup\fR,
|
||||
or
|
||||
\fInetworkaddr\fR.
|
||||
If
|
||||
\fIhostname\fR
|
||||
is set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any host.
|
||||
.sp
|
||||
The
|
||||
\fICmnd_Specs\fR
|
||||
array consists of one or more JSON objects describing a command that
|
||||
may be run.
|
||||
Each
|
||||
\fICmnd_Specs\fR
|
||||
is made up of a
|
||||
\fICommands\fR
|
||||
array, an optional
|
||||
\fIrunasusers\fR
|
||||
array, an optional
|
||||
\fIrunasgroups\fR
|
||||
array, and an optional
|
||||
\fIOptions array.\fR
|
||||
.sp
|
||||
The
|
||||
\fICommands\fR
|
||||
array consists of one or more objects containing
|
||||
\(lqname:value\(rq
|
||||
pair elements.
|
||||
The following names and values are supported:
|
||||
.PP
|
||||
.RS 6n
|
||||
.PD 0
|
||||
.TP 10n
|
||||
command
|
||||
A string containing the command to run.
|
||||
The special value
|
||||
\fBALL\fR
|
||||
it will match any command.
|
||||
.PD
|
||||
.TP 10n
|
||||
negated
|
||||
A boolean value that, if true, will negate any comparison performed
|
||||
with the object.
|
||||
.TP 10n
|
||||
sha224
|
||||
A string containing the SHA224 digest of the
|
||||
\fIcommand\fR.
|
||||
.TP 10n
|
||||
sha256
|
||||
A string containing the SHA256 digest of the
|
||||
\fIcommand\fR.
|
||||
.TP 10n
|
||||
sha384
|
||||
A string containing the SHA384 digest of the
|
||||
\fIcommand\fR.
|
||||
.TP 10n
|
||||
sha512
|
||||
A string containing the SHA512 digest of the
|
||||
\fIcommand\fR.
|
||||
.PP
|
||||
The
|
||||
\fIrunasusers\fR
|
||||
array consists of objects describing users the command may be run as.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fInetgroup\fR,
|
||||
\fInonunixgid\fR,
|
||||
\fInonunixgroup\fR,
|
||||
\fIrunasalias\fR,
|
||||
\fIusergid\fR,
|
||||
\fIusergroup\fR,
|
||||
\fIuserid\fR,
|
||||
or
|
||||
\fIusername\fR.
|
||||
If
|
||||
\fIusername\fR
|
||||
is set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any user.
|
||||
If
|
||||
\fIusername\fR
|
||||
is set to the empty string
|
||||
\(lq\(rq,
|
||||
it will match the invoking user.
|
||||
.sp
|
||||
The
|
||||
\fIrunasgroups\fR
|
||||
array consists of objects describing groups the command may be run as.
|
||||
Each object contains a
|
||||
\(lqname:value\(rq
|
||||
pair and an optional
|
||||
\fInegated\fR
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
\fIrunasalias\fR,
|
||||
\fIusergid\fR,
|
||||
or
|
||||
\fIusergroup\fR.
|
||||
If
|
||||
\fIusergroup\fR
|
||||
is set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any group.
|
||||
.sp
|
||||
The
|
||||
\fIOptions\fR
|
||||
array is of the same format as the one in the
|
||||
\fIDefaults\fR
|
||||
object.
|
||||
Any
|
||||
\fITag_Spec\fR
|
||||
entries in
|
||||
\fIsudoers\fR
|
||||
are converted to
|
||||
\fIOptions\fR.
|
||||
A user with
|
||||
\(lqsudo ALL\(rq
|
||||
privileges will automatically have the
|
||||
\fIsetenv\fR
|
||||
option enabled to match the implicit behavior provided by
|
||||
\fIsudoers\fR.
|
||||
.sp
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entry:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
millert ALL = (ALL : ALL) NOPASSWD: ALL, !/usr/bin/id
|
||||
.RE
|
||||
.fi
|
||||
.sp
|
||||
converts to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
"User_Specs": [
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "millert" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostname": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"runasusers": [
|
||||
{ "username": "ALL" }
|
||||
],
|
||||
"runasgroups": [
|
||||
{ "usergroup": "ALL" }
|
||||
],
|
||||
"Options": [
|
||||
{ "authenticate": false },
|
||||
{ "setenv": true }
|
||||
],
|
||||
"Commands": [
|
||||
{ "command": "ALL" },
|
||||
{
|
||||
"command": "/usr/bin/id",
|
||||
"negated": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.SS "CSV output format"
|
||||
CSV (comma-separated value) files are often used by spreadsheets
|
||||
and report generators.
|
||||
For CSV output,
|
||||
\fBcvtsudoers\fR
|
||||
double quotes strings that contain commas.
|
||||
For each literal double quote character present inside the string,
|
||||
two double quotes are output.
|
||||
This method of quoting commas is compatible with most spreadsheet programs.
|
||||
.PP
|
||||
There are three possible sections in
|
||||
\fBcvtsudoers\fR's
|
||||
CSV output, each separated by a blank line:
|
||||
.TP 6n
|
||||
defaults
|
||||
This section includes any
|
||||
\fIDefaults\fR
|
||||
settings in
|
||||
\fIsudoers\fR.
|
||||
The
|
||||
\fIdefaults\fR
|
||||
section begins with the following heading:
|
||||
.nf
|
||||
.sp
|
||||
.RS 12n
|
||||
defaults_type,binding,name,operator,value
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The fields are as follows:
|
||||
.TP 10n
|
||||
defaults_type
|
||||
The type of
|
||||
\fIDefaults\fR
|
||||
setting; one of
|
||||
\fIdefaults\fR,
|
||||
\fIdefaults_command\fR,
|
||||
\fIdefaults_host\fR,
|
||||
\fIdefaults_runas\fR,
|
||||
or
|
||||
\fIdefaults_user\fR.
|
||||
.TP 10n
|
||||
binding
|
||||
For
|
||||
\fIdefaults_command\fR,
|
||||
\fIdefaults_host\fR,
|
||||
\fIdefaults_runas\fR,
|
||||
and
|
||||
\fIdefaults_user\fR
|
||||
this is the value that must match for the setting to be applied.
|
||||
.TP 10n
|
||||
name
|
||||
The name of the
|
||||
\fIDefaults\fR
|
||||
setting.
|
||||
.TP 10n
|
||||
operator
|
||||
The operator determines how the value is applied to the setting.
|
||||
It may be either
|
||||
\(oq=\(cq
|
||||
(assignment),
|
||||
\(oq+=\(cq
|
||||
(append),
|
||||
or
|
||||
\(oq-=\(cq
|
||||
(remove).
|
||||
.TP 10n
|
||||
value
|
||||
The setting's value, usually a string or, for
|
||||
settings used in a boolean context,
|
||||
\fItrue\fR
|
||||
or
|
||||
\fIfalse\fR.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
aliases
|
||||
This section includes any
|
||||
\fICmnd_Alias\fR
|
||||
\fIHost_Alias\fR,
|
||||
\fIRunas_Alias\fR,
|
||||
or
|
||||
\fIUser_Alias\fR,
|
||||
entries from
|
||||
\fIsudoers\fR.
|
||||
The
|
||||
\fIaliases\fR
|
||||
section begins with the following heading:
|
||||
.nf
|
||||
.sp
|
||||
.RS 12n
|
||||
alias_type,alias_name,members
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The fields are as follows:
|
||||
.TP 10n
|
||||
alias_type
|
||||
The type of alias; one of
|
||||
\fICmnd_Alias\fR,
|
||||
\fIHost_Alias\fR,
|
||||
\fIRunas_Alias\fR,
|
||||
or
|
||||
\fIUser_Alias\fR.
|
||||
.TP 10n
|
||||
alias_name
|
||||
The name of the alias; a string starting with an upper-case letter that
|
||||
consists of upper-case letters, digits, or underscores.
|
||||
.TP 10n
|
||||
members
|
||||
A comma-separated list of members belonging to the alias.
|
||||
Due to the use of commas,
|
||||
\fImembers\fR
|
||||
is surrounded by double quotes if it contains more than one member.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
rules
|
||||
.br
|
||||
This section includes the
|
||||
\fIsudoers\fR
|
||||
rules that grant privileges.
|
||||
The
|
||||
\fIrules\fR
|
||||
section begins with the following heading:
|
||||
.nf
|
||||
.sp
|
||||
.RS 12n
|
||||
rule,user,host,runusers,rungroups,options,command
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
The fields are as follows:
|
||||
.TP 10n
|
||||
rule
|
||||
This field indicates a
|
||||
\fIsudoers\fR
|
||||
\fIrule\fR
|
||||
entry.
|
||||
.TP 10n
|
||||
user
|
||||
The user the rule applies to.
|
||||
This may also be a Unix group (preceded by a
|
||||
\(oq%\(cq
|
||||
character), a non-Unix group (preceded by
|
||||
\(oq%:\(cq)
|
||||
or a netgroup (preceded by a
|
||||
\(oq+\(cq
|
||||
character)
|
||||
or a
|
||||
\fIUser_Alias\fR.
|
||||
If set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any user.
|
||||
.TP 10n
|
||||
host
|
||||
The host the rule applies to.
|
||||
This may also be a netgroup (preceded by a
|
||||
\(oq+\(cq
|
||||
character)
|
||||
or a
|
||||
\fIHost_Alias\fR.
|
||||
If set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any host.
|
||||
.TP 10n
|
||||
runusers
|
||||
An optional comma-separated list of users (or
|
||||
\fIRunas_Alias\fRes)
|
||||
the command may be run as.
|
||||
If it contains more than one member, the value is surrounded by
|
||||
double quotes.
|
||||
If set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any user.
|
||||
If empty, the root user is assumed.
|
||||
.TP 10n
|
||||
rungroups
|
||||
.br
|
||||
An optional comma-separated list of groups (or
|
||||
\fIRunas_Alias\fRes)
|
||||
the command may be run as.
|
||||
If it contains more than one member, the value is surrounded by
|
||||
double quotes.
|
||||
If set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any group.
|
||||
If empty, the
|
||||
\fIrunuser\fR's
|
||||
group is used.
|
||||
.TP 10n
|
||||
options
|
||||
An optional list of
|
||||
\fIDefaults\fR
|
||||
settings to apply to the command.
|
||||
Any
|
||||
\fITag_Spec\fR
|
||||
entries in
|
||||
\fIsudoers\fR
|
||||
are converted to
|
||||
\fIoptions\fR.
|
||||
.TP 10n
|
||||
commands
|
||||
A list of commands, with optional arguments, that the user is allowed to run.
|
||||
If set to the special value
|
||||
\fBALL\fR,
|
||||
it will match any command.
|
||||
.PP
|
||||
For example, the following
|
||||
\fIsudoers\fR
|
||||
entry:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
millert ALL = (ALL : ALL) NOPASSWD: ALL, !/usr/bin/id
|
||||
.RE
|
||||
.fi
|
||||
.sp
|
||||
converts to:
|
||||
.nf
|
||||
.sp
|
||||
.RS 6n
|
||||
rule,millert,ALL,ALL,ALL,"!authenticate","ALL,!/usr/bin/id"
|
||||
.RE
|
||||
.fi
|
||||
.RE
|
||||
.SH "FILES"
|
||||
.TP 26n
|
||||
\fI@sysconfdir@/cvtsudoers.conf\fR
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 29, 2022
|
||||
.Dt CVTSUDOERS 1
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -65,9 +65,8 @@ The options are as follows:
|
||||
The base DN (distinguished name) that will be used when performing
|
||||
LDAP queries.
|
||||
Typically this is of the form
|
||||
.Li ou=SUDOers,dc=my-domain,dc=com
|
||||
for the domain
|
||||
.Li my-domain.com .
|
||||
.Dq ou=SUDOers,dc=my-domain,dc=com
|
||||
for the domain my-domain.com.
|
||||
If this option is not specified, the value of the
|
||||
.Ev SUDOERS_BASE
|
||||
environment variable will be used instead.
|
||||
@ -78,10 +77,10 @@ Defaults to
|
||||
.Pa @sysconfdir@/cvtsudoers.conf .
|
||||
.It Fl d Ar deftypes , Fl -defaults Ns = Ns Ar deftypes
|
||||
Only convert
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
entries of the specified types.
|
||||
One or more
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
types may be specified, separated by a comma
|
||||
.Pq Ql \&, .
|
||||
The supported types are:
|
||||
@ -110,7 +109,7 @@ for more information.
|
||||
If the
|
||||
.Fl d
|
||||
option is not specified, all
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
entries will be converted.
|
||||
.It Fl e , Fl -expand-aliases
|
||||
Expand aliases in
|
||||
@ -125,12 +124,9 @@ The following formats are supported:
|
||||
.It CSV
|
||||
CSV (comma-separated value) files are often used by spreadsheets
|
||||
and report generators.
|
||||
For CSV output,
|
||||
.Nm
|
||||
double quotes strings that contain commas.
|
||||
For each literal double quote character present inside the string,
|
||||
two double quotes are output.
|
||||
This method of quoting commas is compatible with most spreadsheet programs.
|
||||
See
|
||||
.Sx CSV output format
|
||||
for more details.
|
||||
.It JSON
|
||||
JSON (JavaScript Object Notation) files are usually easier for
|
||||
third-party applications to consume than the traditional
|
||||
@ -140,6 +136,9 @@ The various values have explicit types which removes much of the
|
||||
ambiguity of the
|
||||
.Em sudoers
|
||||
format.
|
||||
See
|
||||
.Sx JSON output format
|
||||
for more details.
|
||||
.It LDIF
|
||||
LDIF (LDAP Data Interchange Format) files can be imported into an LDAP
|
||||
server for use with
|
||||
@ -217,7 +216,12 @@ For example,
|
||||
.Sy user No = Ar operator
|
||||
or
|
||||
.Sy host No = Ar www .
|
||||
An upper-case Cmnd_Alias, Host_alias, or Host_Alias may be specified as the
|
||||
An upper-case
|
||||
.Em Cmnd_Alias ,
|
||||
.Em Host_alias ,
|
||||
or
|
||||
.Em User_Alias
|
||||
may be specified as the
|
||||
.Dq cmnd ,
|
||||
.Dq host ,
|
||||
or
|
||||
@ -360,9 +364,9 @@ subsequent aliases of the same name are renamed with a numeric suffix
|
||||
separated with a underscore
|
||||
.Pq Ql _ .
|
||||
For example, if there are two different aliases named
|
||||
.Li SERVERS ,
|
||||
.Dv SERVERS ,
|
||||
the first will be left as-is and the second will be renamed
|
||||
.Li SERVERS_1 .
|
||||
.Dv SERVERS_1 .
|
||||
References to the renamed alias are also updated in the policy file.
|
||||
Duplicate aliases (those with identical contents) are pruned.
|
||||
.It
|
||||
@ -379,7 +383,7 @@ Per-user rules are merged and duplicates are removed.
|
||||
If a host name is specified with the input file,
|
||||
.Nm
|
||||
will change rules that specify a host name of
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
to the host name associated with the policy file being merged.
|
||||
The merging of rules is currently fairly simplistic but will be
|
||||
improved in a later release.
|
||||
@ -454,6 +458,656 @@ command line option.
|
||||
.Pp
|
||||
Options on the command line will override values from the
|
||||
configuration file.
|
||||
.Ss JSON output format
|
||||
The
|
||||
.Em sudoers
|
||||
JSON format may contain any of the following top-level objects:
|
||||
.Bl -tag -width 4n
|
||||
.It Defaults
|
||||
An array of objects, each containing an
|
||||
.Em Options
|
||||
array and an optional
|
||||
.Em Binding
|
||||
array.
|
||||
.Pp
|
||||
The
|
||||
.Em Options
|
||||
array consists of one or more objects, each containing a
|
||||
.Dq name:value
|
||||
pair that corresponds to a
|
||||
.Em sudoers
|
||||
.Em Defaults
|
||||
setting.
|
||||
.Em Options
|
||||
that operate on a list will also include an
|
||||
.Em operation
|
||||
entry in the object, with a value of
|
||||
.Dq list_assign
|
||||
for
|
||||
.Ql = ,
|
||||
.Dq list_add
|
||||
for
|
||||
.Ql += ,
|
||||
or
|
||||
.Dq list_remove
|
||||
for
|
||||
.Ql -= .
|
||||
.Pp
|
||||
The optional
|
||||
.Em Binding
|
||||
array consists of one or more objects, each containing a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
If a
|
||||
.Em Binding
|
||||
is present, the setting will only take effect if one of the specified
|
||||
.Em command ,
|
||||
.Em hostname ,
|
||||
.Em netgroup ,
|
||||
.Em networkaddr ,
|
||||
.Em nonunixgid ,
|
||||
.Em nonunixgroup ,
|
||||
.Em usergid ,
|
||||
.Em usergroup ,
|
||||
.Em userid ,
|
||||
.Em username ,
|
||||
or alias entries match.
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entry:
|
||||
.Bd -literal
|
||||
Defaults@somehost set_home, env_keep += DISPLAY
|
||||
.Ed
|
||||
.Pp
|
||||
converts to:
|
||||
.Bd -literal
|
||||
"Defaults": [
|
||||
{
|
||||
"Binding": [
|
||||
{ "hostname": "somehost" }
|
||||
],
|
||||
"Options": [
|
||||
{ "set_home": true },
|
||||
{
|
||||
"operation": "list_add",
|
||||
"env_keep": [
|
||||
"DISPLAY"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
.Ed
|
||||
.It User_Aliases
|
||||
A JSON object containing one or more
|
||||
.Em sudoers
|
||||
.Em User_Alias
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em netgroup ,
|
||||
.Em nonunixgid ,
|
||||
.Em nonunixgroup ,
|
||||
.Em useralias ,
|
||||
.Em usergid ,
|
||||
.Em usergroup ,
|
||||
.Em userid ,
|
||||
or
|
||||
.Em username .
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entry:
|
||||
.Bd -literal
|
||||
User_Alias SYSADMIN = will, %wheel, +admin
|
||||
.Ed
|
||||
.Pp
|
||||
converts to:
|
||||
.Bd -literal
|
||||
"User_Aliases": {
|
||||
"SYSADMIN": [
|
||||
{ "username": "will" },
|
||||
{ "usergroup": "wheel" },
|
||||
{ "netgroup": "admin" }
|
||||
]
|
||||
}
|
||||
.Ed
|
||||
.It Runas_Aliases
|
||||
A JSON object containing one or more
|
||||
.Em sudoers
|
||||
.Em Runas_Alias
|
||||
entries, where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em netgroup ,
|
||||
.Em nonunixgid ,
|
||||
.Em nonunixgroup ,
|
||||
.Em runasalias ,
|
||||
.Em usergid ,
|
||||
.Em usergroup ,
|
||||
.Em userid ,
|
||||
or
|
||||
.Em username .
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entry:
|
||||
.Bd -literal
|
||||
Runas_Alias DB = oracle, sybase : OP = root, operator
|
||||
.Ed
|
||||
.Pp
|
||||
converts to:
|
||||
.Bd -literal
|
||||
"Runas_Aliases": {
|
||||
"DB": [
|
||||
{ "username": "oracle" },
|
||||
{ "username": "sybase" }
|
||||
],
|
||||
"OP": [
|
||||
{ "username": "root" },
|
||||
{ "username": "operator" }
|
||||
]
|
||||
}
|
||||
.Ed
|
||||
.It Host_Aliases
|
||||
A JSON object containing one or more
|
||||
.Em sudoers
|
||||
.Em Host_Alias
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em hostalias ,
|
||||
.Em hostname ,
|
||||
.Em netgroup ,
|
||||
or
|
||||
.Em networkaddr .
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entries:
|
||||
.Bd -literal
|
||||
Host_Alias DORMNET = 128.138.243.0, 128.138.204.0/24
|
||||
Host_Alias SERVERS = boulder, refuge
|
||||
.Ed
|
||||
.Pp
|
||||
convert to:
|
||||
.Bd -literal
|
||||
"Host_Aliases": {
|
||||
"DORMNET": [
|
||||
{ "networkaddr": "128.138.243.0" },
|
||||
{ "networkaddr": "128.138.204.0/24" }
|
||||
],
|
||||
"SERVERS": [
|
||||
{ "hostname": "boulder" },
|
||||
{ "hostname": "refuge" }
|
||||
]
|
||||
}
|
||||
.Ed
|
||||
.It Cmnd_Aliases
|
||||
A JSON object containing one or more
|
||||
.Em sudoers
|
||||
.Em Cmnd_Alias
|
||||
entries where each named alias has as its value an array
|
||||
containing one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be either another
|
||||
.Em cmndalias
|
||||
or a
|
||||
.Em command .
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entries:
|
||||
.Bd -literal
|
||||
Cmnd_Alias SHELLS = /bin/bash, /bin/csh, /bin/sh, /bin/zsh
|
||||
Cmnd_Alias VIPW = /usr/bin/chpass, /usr/bin/chfn, /usr/bin/chsh, \e
|
||||
/usr/bin/passwd, /usr/sbin/vigr, /usr/sbin/vipw
|
||||
.Ed
|
||||
.Pp
|
||||
convert to:
|
||||
.Bd -literal
|
||||
"Cmnd_Aliases": {
|
||||
"SHELLS": [
|
||||
{ "command": "/bin/bash" },
|
||||
{ "command": "/bin/csh" },
|
||||
{ "command": "/bin/sh" },
|
||||
{ "command": "/bin/zsh" }
|
||||
],
|
||||
"VIPW": [
|
||||
{ "command": "/usr/bin/chpass" },
|
||||
{ "command": "/usr/bin/chfn" },
|
||||
{ "command": "/usr/bin/chsh" },
|
||||
{ "command": "/usr/bin/passwd" },
|
||||
{ "command": "/usr/sbin/vigr" },
|
||||
{ "command": "/usr/sbin/vipw" }
|
||||
]
|
||||
}
|
||||
.Ed
|
||||
.It User_Specs
|
||||
A JSON array containing one or more objects, each representing a
|
||||
.Em sudoers
|
||||
User_Spec.
|
||||
Each object in the
|
||||
.Em User_Specs
|
||||
array should contain a
|
||||
.Em User_List
|
||||
array, a
|
||||
.Em Host_List
|
||||
array and a
|
||||
.Em Cmnd_Specs
|
||||
array.
|
||||
.Pp
|
||||
A
|
||||
.Em User_List
|
||||
consists of one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em netgroup ,
|
||||
.Em nonunixgid ,
|
||||
.Em nonunixgroup ,
|
||||
.Em useralias ,
|
||||
.Em usergid ,
|
||||
.Em usergroup ,
|
||||
.Em userid ,
|
||||
or
|
||||
.Em username .
|
||||
If
|
||||
.Em username
|
||||
is set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any user.
|
||||
.Pp
|
||||
A
|
||||
.Em Host_List
|
||||
consists of one or more objects.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em hostalias ,
|
||||
.Em hostname ,
|
||||
.Em netgroup ,
|
||||
or
|
||||
.Em networkaddr .
|
||||
If
|
||||
.Em hostname
|
||||
is set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any host.
|
||||
.Pp
|
||||
The
|
||||
.Em Cmnd_Specs
|
||||
array consists of one or more JSON objects describing a command that
|
||||
may be run.
|
||||
Each
|
||||
.Em Cmnd_Specs
|
||||
is made up of a
|
||||
.Em Commands
|
||||
array, an optional
|
||||
.Em runasusers
|
||||
array, an optional
|
||||
.Em runasgroups
|
||||
array, and an optional
|
||||
.Em Options array.
|
||||
.Pp
|
||||
The
|
||||
.Em Commands
|
||||
array consists of one or more objects containing
|
||||
.Dq name:value
|
||||
pair elements.
|
||||
The following names and values are supported:
|
||||
.Bl -tag -width 8n
|
||||
.It command
|
||||
A string containing the command to run.
|
||||
The special value
|
||||
.Sy ALL
|
||||
it will match any command.
|
||||
.It negated
|
||||
A boolean value that, if true, will negate any comparison performed
|
||||
with the object.
|
||||
.It sha224
|
||||
A string containing the SHA224 digest of the
|
||||
.Em command .
|
||||
.It sha256
|
||||
A string containing the SHA256 digest of the
|
||||
.Em command .
|
||||
.It sha384
|
||||
A string containing the SHA384 digest of the
|
||||
.Em command .
|
||||
.It sha512
|
||||
A string containing the SHA512 digest of the
|
||||
.Em command .
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Em runasusers
|
||||
array consists of objects describing users the command may be run as.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em netgroup ,
|
||||
.Em nonunixgid ,
|
||||
.Em nonunixgroup ,
|
||||
.Em runasalias ,
|
||||
.Em usergid ,
|
||||
.Em usergroup ,
|
||||
.Em userid ,
|
||||
or
|
||||
.Em username .
|
||||
If
|
||||
.Em username
|
||||
is set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any user.
|
||||
If
|
||||
.Em username
|
||||
is set to the empty string
|
||||
.Dq "" ,
|
||||
it will match the invoking user.
|
||||
.Pp
|
||||
The
|
||||
.Em runasgroups
|
||||
array consists of objects describing groups the command may be run as.
|
||||
Each object contains a
|
||||
.Dq name:value
|
||||
pair and an optional
|
||||
.Em negated
|
||||
entry, which will negate any comparison performed with the object.
|
||||
The name may be one of
|
||||
.Em runasalias ,
|
||||
.Em usergid ,
|
||||
or
|
||||
.Em usergroup .
|
||||
If
|
||||
.Em usergroup
|
||||
is set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any group.
|
||||
.Pp
|
||||
The
|
||||
.Em Options
|
||||
array is of the same format as the one in the
|
||||
.Em Defaults
|
||||
object.
|
||||
Any
|
||||
.Em Tag_Spec
|
||||
entries in
|
||||
.Em sudoers
|
||||
are converted to
|
||||
.Em Options .
|
||||
A user with
|
||||
.Dq sudo ALL
|
||||
privileges will automatically have the
|
||||
.Em setenv
|
||||
option enabled to match the implicit behavior provided by
|
||||
.Em sudoers .
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entry:
|
||||
.Bd -literal
|
||||
millert ALL = (ALL : ALL) NOPASSWD: ALL, !/usr/bin/id
|
||||
.Ed
|
||||
.Pp
|
||||
converts to:
|
||||
.Bd -literal
|
||||
"User_Specs": [
|
||||
{
|
||||
"User_List": [
|
||||
{ "username": "millert" }
|
||||
],
|
||||
"Host_List": [
|
||||
{ "hostname": "ALL" }
|
||||
],
|
||||
"Cmnd_Specs": [
|
||||
{
|
||||
"runasusers": [
|
||||
{ "username": "ALL" }
|
||||
],
|
||||
"runasgroups": [
|
||||
{ "usergroup": "ALL" }
|
||||
],
|
||||
"Options": [
|
||||
{ "authenticate": false },
|
||||
{ "setenv": true }
|
||||
],
|
||||
"Commands": [
|
||||
{ "command": "ALL" },
|
||||
{
|
||||
"command": "/usr/bin/id",
|
||||
"negated": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
.Ed
|
||||
.El
|
||||
.Ss CSV output format
|
||||
CSV (comma-separated value) files are often used by spreadsheets
|
||||
and report generators.
|
||||
For CSV output,
|
||||
.Nm
|
||||
double quotes strings that contain commas.
|
||||
For each literal double quote character present inside the string,
|
||||
two double quotes are output.
|
||||
This method of quoting commas is compatible with most spreadsheet programs.
|
||||
.Pp
|
||||
There are three possible sections in
|
||||
.Nm cvtsudoers Ns 's
|
||||
CSV output, each separated by a blank line:
|
||||
.Bl -tag -width 4n
|
||||
.It defaults
|
||||
This section includes any
|
||||
.Em Defaults
|
||||
settings in
|
||||
.Em sudoers .
|
||||
The
|
||||
.Em defaults
|
||||
section begins with the following heading:
|
||||
.Bd -literal -offset indent
|
||||
defaults_type,binding,name,operator,value
|
||||
.Ed
|
||||
.Pp
|
||||
The fields are as follows:
|
||||
.Bl -tag -width 8n
|
||||
.It defaults_type
|
||||
The type of
|
||||
.Em Defaults
|
||||
setting; one of
|
||||
.Em defaults ,
|
||||
.Em defaults_command ,
|
||||
.Em defaults_host ,
|
||||
.Em defaults_runas ,
|
||||
or
|
||||
.Em defaults_user .
|
||||
.It binding
|
||||
For
|
||||
.Em defaults_command ,
|
||||
.Em defaults_host ,
|
||||
.Em defaults_runas ,
|
||||
and
|
||||
.Em defaults_user
|
||||
this is the value that must match for the setting to be applied.
|
||||
.It name
|
||||
The name of the
|
||||
.Em Defaults
|
||||
setting.
|
||||
.It operator
|
||||
The operator determines how the value is applied to the setting.
|
||||
It may be either
|
||||
.Ql =
|
||||
(assignment),
|
||||
.Ql +=
|
||||
(append),
|
||||
or
|
||||
.Ql -=
|
||||
(remove).
|
||||
.It value
|
||||
The setting's value, usually a string or, for
|
||||
settings used in a boolean context,
|
||||
.Em true
|
||||
or
|
||||
.Em false .
|
||||
.El
|
||||
.It aliases
|
||||
This section includes any
|
||||
.Em Cmnd_Alias
|
||||
.Em Host_Alias ,
|
||||
.Em Runas_Alias ,
|
||||
or
|
||||
.Em User_Alias ,
|
||||
entries from
|
||||
.Em sudoers .
|
||||
The
|
||||
.Em aliases
|
||||
section begins with the following heading:
|
||||
.Bd -literal -offset indent
|
||||
alias_type,alias_name,members
|
||||
.Ed
|
||||
.Pp
|
||||
The fields are as follows:
|
||||
.Bl -tag -width 8n
|
||||
.It alias_type
|
||||
The type of alias; one of
|
||||
.Em Cmnd_Alias ,
|
||||
.Em Host_Alias ,
|
||||
.Em Runas_Alias ,
|
||||
or
|
||||
.Em User_Alias .
|
||||
.It alias_name
|
||||
The name of the alias; a string starting with an upper-case letter that
|
||||
consists of upper-case letters, digits, or underscores.
|
||||
.It members
|
||||
A comma-separated list of members belonging to the alias.
|
||||
Due to the use of commas,
|
||||
.Em members
|
||||
is surrounded by double quotes if it contains more than one member.
|
||||
.El
|
||||
.It rules
|
||||
This section includes the
|
||||
.Em sudoers
|
||||
rules that grant privileges.
|
||||
The
|
||||
.Em rules
|
||||
section begins with the following heading:
|
||||
.Bd -literal -offset indent
|
||||
rule,user,host,runusers,rungroups,options,command
|
||||
.Ed
|
||||
.Pp
|
||||
The fields are as follows:
|
||||
.Bl -tag -width 8n
|
||||
.It rule
|
||||
This field indicates a
|
||||
.Em sudoers
|
||||
.Em rule
|
||||
entry.
|
||||
.It user
|
||||
The user the rule applies to.
|
||||
This may also be a Unix group (preceded by a
|
||||
.Ql %
|
||||
character), a non-Unix group (preceded by
|
||||
.Ql %: )
|
||||
or a netgroup (preceded by a
|
||||
.Ql +
|
||||
character)
|
||||
or a
|
||||
.Em User_Alias .
|
||||
If set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any user.
|
||||
.It host
|
||||
The host the rule applies to.
|
||||
This may also be a netgroup (preceded by a
|
||||
.Ql +
|
||||
character)
|
||||
or a
|
||||
.Em Host_Alias .
|
||||
If set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any host.
|
||||
.It runusers
|
||||
An optional comma-separated list of users (or
|
||||
.Em Runas_Alias Ns No es )
|
||||
the command may be run as.
|
||||
If it contains more than one member, the value is surrounded by
|
||||
double quotes.
|
||||
If set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any user.
|
||||
If empty, the root user is assumed.
|
||||
.It rungroups
|
||||
An optional comma-separated list of groups (or
|
||||
.Em Runas_Alias Ns No es )
|
||||
the command may be run as.
|
||||
If it contains more than one member, the value is surrounded by
|
||||
double quotes.
|
||||
If set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any group.
|
||||
If empty, the
|
||||
.Em runuser Ns 's
|
||||
group is used.
|
||||
.It options
|
||||
An optional list of
|
||||
.Em Defaults
|
||||
settings to apply to the command.
|
||||
Any
|
||||
.Em Tag_Spec
|
||||
entries in
|
||||
.Em sudoers
|
||||
are converted to
|
||||
.Em options .
|
||||
.It commands
|
||||
A list of commands, with optional arguments, that the user is allowed to run.
|
||||
If set to the special value
|
||||
.Sy ALL ,
|
||||
it will match any command.
|
||||
.El
|
||||
.Pp
|
||||
For example, the following
|
||||
.Em sudoers
|
||||
entry:
|
||||
.Bd -literal
|
||||
millert ALL = (ALL : ALL) NOPASSWD: ALL, !/usr/bin/id
|
||||
.Ed
|
||||
.Pp
|
||||
converts to:
|
||||
.Bd -literal
|
||||
rule,millert,ALL,ALL,ALL,"!authenticate","ALL,!/usr/bin/id"
|
||||
.Ed
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width 24n
|
||||
.It Pa @sysconfdir@/cvtsudoers.conf
|
||||
|
@ -7,9 +7,9 @@
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.1
|
||||
NAME 'sudoUser'
|
||||
DESC 'User(s) who may run sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseExactIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SUBSTR caseExactSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.2
|
||||
NAME 'sudoHost'
|
||||
@ -39,14 +39,14 @@ attributetype ( 1.3.6.1.4.1.15953.9.1.5
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.6
|
||||
NAME 'sudoRunAsUser'
|
||||
DESC 'User(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.7
|
||||
NAME 'sudoRunAsGroup'
|
||||
DESC 'Group(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.8
|
||||
NAME 'sudoNotBefore'
|
||||
|
@ -1,11 +1,11 @@
|
||||
dn: cn=schema
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactMatch SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'SUDO' )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
attributeTypes: ( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
|
||||
|
@ -9,9 +9,9 @@ cn: sudoschema
|
||||
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.1
|
||||
NAME 'sudoUser'
|
||||
DESC 'User(s) who may run sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseExactIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SUBSTR caseExactSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
#
|
||||
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.2
|
||||
NAME 'sudoHost'
|
||||
@ -41,14 +41,14 @@ olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.5
|
||||
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.6
|
||||
NAME 'sudoRunAsUser'
|
||||
DESC 'User(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
#
|
||||
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.7
|
||||
NAME 'sudoRunAsGroup'
|
||||
DESC 'Group(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
#
|
||||
olcattributetypes: ( 1.3.6.1.4.1.15953.9.1.8
|
||||
NAME 'sudoNotBefore'
|
||||
|
@ -70,17 +70,17 @@ Leading white space is removed from the beginning of lines
|
||||
even when a continuation character is used.
|
||||
.PP
|
||||
Non-comment lines that don't begin with
|
||||
\fRPlugin\fR,
|
||||
\fRPath\fR,
|
||||
\fRDebug\fR,
|
||||
\fIPlugin\fR,
|
||||
\fIPath\fR,
|
||||
\fIDebug\fR,
|
||||
or
|
||||
\fRSet\fR
|
||||
\fISet\fR
|
||||
are silently ignored.
|
||||
.PP
|
||||
The
|
||||
\fBsudo.conf\fR
|
||||
file is always parsed in the
|
||||
\(lq\fRC\fR\(rq
|
||||
\(oqC\(cq
|
||||
locale.
|
||||
.SS "Plugin configuration"
|
||||
\fBsudo\fR
|
||||
@ -94,9 +94,9 @@ Plugins are dynamically loaded based on the contents of
|
||||
\fBsudo.conf\fR.
|
||||
.PP
|
||||
A
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
line consists of the
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
keyword, followed by the
|
||||
\fIsymbol_name\fR
|
||||
and the
|
||||
@ -105,14 +105,14 @@ to the dynamic shared object that contains the plugin.
|
||||
The
|
||||
\fIsymbol_name\fR
|
||||
is the name of the
|
||||
\fRapproval_plugin\fR,
|
||||
\fRaudit_plugin\fR,
|
||||
\fRio_plugin\fR,
|
||||
\fIstruct approval_plugin\fR,
|
||||
\fIstruct audit_plugin\fR,
|
||||
\fIstruct io_plugin\fR,
|
||||
or
|
||||
\fRpolicy_plugin\fR
|
||||
struct contained in the plugin.
|
||||
\fIstruct policy_plugin\fR
|
||||
defined by the plugin.
|
||||
If a plugin implements multiple plugin types, there must be a
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
line for each unique symbol name.
|
||||
The
|
||||
\fIpath\fR
|
||||
@ -120,7 +120,7 @@ may be fully qualified or relative.
|
||||
If not fully qualified, it is relative to the directory
|
||||
specified by the
|
||||
\fIplugin_dir\fR
|
||||
\fRPath\fR
|
||||
\fIPath\fR
|
||||
setting, which defaults to
|
||||
\fI@plugindir@\fR.
|
||||
In other words:
|
||||
@ -182,7 +182,7 @@ This limitation does not apply to I/O plugins.
|
||||
If no
|
||||
\fBsudo.conf\fR
|
||||
file is present, or if it contains no
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
lines, the
|
||||
\fBsudoers\fR
|
||||
plugin will be used as the default security policy, for I/O logging
|
||||
@ -221,9 +221,9 @@ sudo_plugin(@mansectform@)
|
||||
manual.
|
||||
.SS "Path settings"
|
||||
A
|
||||
\fRPath\fR
|
||||
\fIPath\fR
|
||||
line consists of the
|
||||
\fRPath\fR
|
||||
\fIPath\fR
|
||||
keyword, followed by the name of the path to set and its value.
|
||||
For example:
|
||||
.nf
|
||||
@ -238,7 +238,7 @@ Path askpass /usr/X11R6/bin/ssh-askpass
|
||||
If no path name is specified, features relying on the specified
|
||||
setting will be disabled.
|
||||
Disabling
|
||||
\fRPath\fR
|
||||
\fIPath\fR
|
||||
settings is only supported in
|
||||
\fBsudo\fR
|
||||
version 1.8.16 and higher.
|
||||
@ -277,7 +277,7 @@ If terminal devices may be located in a sub-directory of
|
||||
that path must be explicitly listed in
|
||||
\fIdevsearch\fR.
|
||||
The default value is
|
||||
\fR/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev\fR
|
||||
\fI/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev\fR
|
||||
.sp
|
||||
This option is ignored on systems that support either the
|
||||
\fBdevname\fR()
|
||||
@ -290,15 +290,15 @@ macOS and Solaris.
|
||||
intercept
|
||||
.br
|
||||
The fully-qualified path to a shared library containing a wrappers for the
|
||||
\fBexecl\fR(),
|
||||
\fBexecle\fR(),
|
||||
\fBexeclp\fR(),
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
execve(2),
|
||||
execl(3),
|
||||
execle(3),
|
||||
execlp(3),
|
||||
execv(3),
|
||||
execvp(3),
|
||||
execvpe(3),
|
||||
and
|
||||
\fBsystem\fR()
|
||||
system(3)
|
||||
library functions that intercepts attempts to run further commands and
|
||||
performs a policy check before allowing them to be executed.
|
||||
This is used to implement the
|
||||
@ -312,23 +312,23 @@ The default value is
|
||||
noexec
|
||||
The fully-qualified path to a shared library containing wrappers
|
||||
for the
|
||||
\fBexecl\fR(),
|
||||
\fBexecle\fR(),
|
||||
\fBexeclp\fR(),
|
||||
\fBexect\fR(),
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecveat\fR(),
|
||||
\fBexecvP\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
\fBfexecve\fR(),
|
||||
\fBpopen\fR(),
|
||||
\fBposix_spawn\fR(),
|
||||
\fBposix_spawnp\fR(),
|
||||
\fBsystem\fR(),
|
||||
execve(2),
|
||||
execl(3),
|
||||
execle(3),
|
||||
execlp(3),
|
||||
exect(3),
|
||||
execv(3),
|
||||
execveat(3),
|
||||
execvP(3),
|
||||
execvp(3),
|
||||
execvpe(3),
|
||||
fexecve(3),
|
||||
popen(3),
|
||||
posix_spawn(3),
|
||||
posix_spawnp(3),
|
||||
system(3),
|
||||
and
|
||||
\fBwordexp\fR()
|
||||
wordexp(3)
|
||||
library functions that prevent the execution of further commands.
|
||||
This is used to implement the
|
||||
\fInoexec\fR
|
||||
@ -569,9 +569,9 @@ that can log what
|
||||
is doing internally if there is a problem.
|
||||
.PP
|
||||
A
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
line consists of the
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
keyword, followed by the name of the program, plugin, or shared object
|
||||
to debug, the debug file name, and a comma-separated list of debug flags.
|
||||
The debug flag syntax used by
|
||||
@ -613,25 +613,25 @@ intercept functionality on some systems.
|
||||
As of
|
||||
\fBsudo\fR
|
||||
1.8.12, multiple
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
entries may be specified per program.
|
||||
Older versions of
|
||||
\fBsudo\fR
|
||||
only support a single
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
entry per program.
|
||||
Plugin-specific
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
entries are also supported starting with
|
||||
\fBsudo\fR
|
||||
1.8.12 and are matched by either the base name of the plugin that was loaded
|
||||
(for example
|
||||
\fRsudoers.so\fR)
|
||||
\fIsudoers.so\fR)
|
||||
or by the plugin's fully-qualified path name.
|
||||
Previously, the
|
||||
\fBsudoers\fR
|
||||
plugin shared the same
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
entry as the
|
||||
\fBsudo\fR
|
||||
front-end and could not be configured separately.
|
||||
|
@ -67,17 +67,17 @@ Leading white space is removed from the beginning of lines
|
||||
even when a continuation character is used.
|
||||
.Pp
|
||||
Non-comment lines that don't begin with
|
||||
.Li Plugin ,
|
||||
.Li Path ,
|
||||
.Li Debug ,
|
||||
.Em Plugin ,
|
||||
.Em Path ,
|
||||
.Em Debug ,
|
||||
or
|
||||
.Li Set
|
||||
.Em Set
|
||||
are silently ignored.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
file is always parsed in the
|
||||
.Dq Li C
|
||||
.Ql C
|
||||
locale.
|
||||
.Ss Plugin configuration
|
||||
.Nm sudo
|
||||
@ -91,9 +91,9 @@ Plugins are dynamically loaded based on the contents of
|
||||
.Nm .
|
||||
.Pp
|
||||
A
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
line consists of the
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
keyword, followed by the
|
||||
.Em symbol_name
|
||||
and the
|
||||
@ -102,14 +102,14 @@ to the dynamic shared object that contains the plugin.
|
||||
The
|
||||
.Em symbol_name
|
||||
is the name of the
|
||||
.Li approval_plugin ,
|
||||
.Li audit_plugin ,
|
||||
.Li io_plugin ,
|
||||
.Vt struct approval_plugin ,
|
||||
.Vt struct audit_plugin ,
|
||||
.Vt struct io_plugin ,
|
||||
or
|
||||
.Li policy_plugin
|
||||
struct contained in the plugin.
|
||||
.Vt struct policy_plugin
|
||||
defined by the plugin.
|
||||
If a plugin implements multiple plugin types, there must be a
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
line for each unique symbol name.
|
||||
The
|
||||
.Em path
|
||||
@ -117,7 +117,7 @@ may be fully qualified or relative.
|
||||
If not fully qualified, it is relative to the directory
|
||||
specified by the
|
||||
.Em plugin_dir
|
||||
.Li Path
|
||||
.Em Path
|
||||
setting, which defaults to
|
||||
.Pa @plugindir@ .
|
||||
In other words:
|
||||
@ -167,7 +167,7 @@ This limitation does not apply to I/O plugins.
|
||||
If no
|
||||
.Nm
|
||||
file is present, or if it contains no
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
lines, the
|
||||
.Nm sudoers
|
||||
plugin will be used as the default security policy, for I/O logging
|
||||
@ -203,9 +203,9 @@ plugin architecture, see the
|
||||
manual.
|
||||
.Ss Path settings
|
||||
A
|
||||
.Li Path
|
||||
.Em Path
|
||||
line consists of the
|
||||
.Li Path
|
||||
.Em Path
|
||||
keyword, followed by the name of the path to set and its value.
|
||||
For example:
|
||||
.Bd -literal -offset 4n
|
||||
@ -217,7 +217,7 @@ Path askpass /usr/X11R6/bin/ssh-askpass
|
||||
If no path name is specified, features relying on the specified
|
||||
setting will be disabled.
|
||||
Disabling
|
||||
.Li Path
|
||||
.Em Path
|
||||
settings is only supported in
|
||||
.Nm sudo
|
||||
version 1.8.16 and higher.
|
||||
@ -254,7 +254,7 @@ If terminal devices may be located in a sub-directory of
|
||||
that path must be explicitly listed in
|
||||
.Em devsearch .
|
||||
The default value is
|
||||
.Li /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
|
||||
.Pa /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev
|
||||
.Pp
|
||||
This option is ignored on systems that support either the
|
||||
.Fn devname
|
||||
@ -265,15 +265,15 @@ functions, for example
|
||||
macOS and Solaris.
|
||||
.It intercept
|
||||
The fully-qualified path to a shared library containing a wrappers for the
|
||||
.Fn execl ,
|
||||
.Fn execle ,
|
||||
.Fn execlp ,
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
.Xr execve 2 ,
|
||||
.Xr execl 3 ,
|
||||
.Xr execle 3 ,
|
||||
.Xr execlp 3 ,
|
||||
.Xr execv 3 ,
|
||||
.Xr execvp 3 ,
|
||||
.Xr execvpe 3 ,
|
||||
and
|
||||
.Fn system
|
||||
.Xr system 3
|
||||
library functions that intercepts attempts to run further commands and
|
||||
performs a policy check before allowing them to be executed.
|
||||
This is used to implement the
|
||||
@ -286,23 +286,23 @@ The default value is
|
||||
.It noexec
|
||||
The fully-qualified path to a shared library containing wrappers
|
||||
for the
|
||||
.Fn execl ,
|
||||
.Fn execle ,
|
||||
.Fn execlp ,
|
||||
.Fn exect ,
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execveat ,
|
||||
.Fn execvP ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
.Fn fexecve ,
|
||||
.Fn popen ,
|
||||
.Fn posix_spawn ,
|
||||
.Fn posix_spawnp ,
|
||||
.Fn system ,
|
||||
.Xr execve 2 ,
|
||||
.Xr execl 3 ,
|
||||
.Xr execle 3 ,
|
||||
.Xr execlp 3 ,
|
||||
.Xr exect 3 ,
|
||||
.Xr execv 3 ,
|
||||
.Xr execveat 3 ,
|
||||
.Xr execvP 3 ,
|
||||
.Xr execvp 3 ,
|
||||
.Xr execvpe 3 ,
|
||||
.Xr fexecve 3 ,
|
||||
.Xr popen 3 ,
|
||||
.Xr posix_spawn 3 ,
|
||||
.Xr posix_spawnp 3 ,
|
||||
.Xr system 3 ,
|
||||
and
|
||||
.Fn wordexp
|
||||
.Xr wordexp 3
|
||||
library functions that prevent the execution of further commands.
|
||||
This is used to implement the
|
||||
.Em noexec
|
||||
@ -519,9 +519,9 @@ that can log what
|
||||
is doing internally if there is a problem.
|
||||
.Pp
|
||||
A
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
line consists of the
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
keyword, followed by the name of the program, plugin, or shared object
|
||||
to debug, the debug file name, and a comma-separated list of debug flags.
|
||||
The debug flag syntax used by
|
||||
@ -557,25 +557,25 @@ intercept functionality on some systems.
|
||||
As of
|
||||
.Nm sudo
|
||||
1.8.12, multiple
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
entries may be specified per program.
|
||||
Older versions of
|
||||
.Nm sudo
|
||||
only support a single
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
entry per program.
|
||||
Plugin-specific
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
entries are also supported starting with
|
||||
.Nm sudo
|
||||
1.8.12 and are matched by either the base name of the plugin that was loaded
|
||||
(for example
|
||||
.Li sudoers.so )
|
||||
.Pa sudoers.so )
|
||||
or by the plugin's fully-qualified path name.
|
||||
Previously, the
|
||||
.Nm sudoers
|
||||
plugin shared the same
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
entry as the
|
||||
.Nm sudo
|
||||
front-end and could not be configured separately.
|
||||
|
@ -25,7 +25,7 @@
|
||||
.nr BA @BAMAN@
|
||||
.nr LC @LCMAN@
|
||||
.nr PS @PSMAN@
|
||||
.TH "SUDO" "@mansectsu@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.TH "SUDO" "@mansectsu@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -41,7 +41,7 @@
|
||||
.HP 5n
|
||||
\fBsudo\fR
|
||||
\fB\-v\fR
|
||||
[\fB\-ABknS\fR]
|
||||
[\fB\-ABkNnS\fR]
|
||||
.if \n(BA [\fB\-a\fR\ \fItype\fR]
|
||||
[\fB\-g\fR\ \fIgroup\fR]
|
||||
[\fB\-h\fR\ \fIhost\fR]
|
||||
@ -51,7 +51,7 @@
|
||||
.HP 5n
|
||||
\fBsudo\fR
|
||||
\fB\-l\fR
|
||||
[\fB\-ABknS\fR]
|
||||
[\fB\-ABkNnS\fR]
|
||||
.if \n(BA [\fB\-a\fR\ \fItype\fR]
|
||||
[\fB\-g\fR\ \fIgroup\fR]
|
||||
[\fB\-h\fR\ \fIhost\fR]
|
||||
@ -81,7 +81,7 @@
|
||||
.br
|
||||
.HP 9n
|
||||
\fBsudoedit\fR
|
||||
[\fB\-ABknS\fR]
|
||||
[\fB\-ABkNnS\fR]
|
||||
.if \n(BA [\fB\-a\fR\ \fItype\fR]
|
||||
[\fB\-C\fR\ \fInum\fR]
|
||||
.if \n(LC [\fB\-c\fR\ \fIclass\fR]
|
||||
@ -135,9 +135,7 @@ time limit.
|
||||
This limit is policy-specific; the default password prompt timeout
|
||||
for the
|
||||
\fIsudoers\fR
|
||||
security policy is
|
||||
\fR@password_timeout@\fR
|
||||
minutes.
|
||||
security policy is @password_timeout@ minutes.
|
||||
.PP
|
||||
Security policies may support credential caching to allow the user
|
||||
to run
|
||||
@ -145,9 +143,7 @@ to run
|
||||
again for a period of time without requiring authentication.
|
||||
By default, the
|
||||
\fIsudoers\fR
|
||||
policy caches credentials on a per-terminal basis for
|
||||
\fR@timeout@\fR
|
||||
minutes.
|
||||
policy caches credentials on a per-terminal basis for @timeout@ minutes.
|
||||
See the
|
||||
\fItimestamp_type\fR
|
||||
and
|
||||
@ -399,7 +395,7 @@ may be either a group name or a numeric group-ID
|
||||
prefixed with the
|
||||
\(oq#\(cq
|
||||
character (e.g.,
|
||||
\fR#0\fR
|
||||
\(oq#0\(cq
|
||||
for GID 0).
|
||||
When running a command as a GID, many shells require that the
|
||||
\(oq#\(cq
|
||||
@ -532,6 +528,22 @@ is specified but not allowed by the policy,
|
||||
\fBsudo\fR
|
||||
will exit with a status value of 1.
|
||||
.TP 12n
|
||||
\fB\-N\fR, \fB\--no-update\fR
|
||||
Do not update the user's cached credentials, even if the user successfully
|
||||
authenticates.
|
||||
Unlike the
|
||||
\fB\-k\fR
|
||||
flag, existing cached credentials are used if they are valid.
|
||||
To detect when the user's cached credentials are valid (or when no
|
||||
authentication is required), the following command can be used:
|
||||
.RS 18n
|
||||
sudo -Nnv
|
||||
.RE
|
||||
.RS 12n
|
||||
.sp
|
||||
Not all security policies support credential caching.
|
||||
.RE
|
||||
.TP 12n
|
||||
\fB\-n\fR, \fB\--non-interactive\fR
|
||||
Avoid prompting the user for input of any kind.
|
||||
If a password is required for the command to run,
|
||||
@ -558,7 +570,7 @@ policy:
|
||||
.RS 12n
|
||||
.PD 0
|
||||
.TP 4n
|
||||
\fR%H\fR
|
||||
%H
|
||||
expanded to the host name including the domain name (only if the
|
||||
machine's host name is fully qualified or the
|
||||
\fIfqdn\fR
|
||||
@ -566,10 +578,10 @@ option is set in
|
||||
sudoers(@mansectform@))
|
||||
.PD
|
||||
.TP 4n
|
||||
\fR%h\fR
|
||||
%h
|
||||
expanded to the local host name without the domain name
|
||||
.TP 4n
|
||||
\fR%p\fR
|
||||
%p
|
||||
expanded to the name of the user whose password is being requested
|
||||
(respects the
|
||||
\fIrootpw\fR,
|
||||
@ -579,16 +591,16 @@ and
|
||||
flags in
|
||||
sudoers(@mansectform@))
|
||||
.TP 4n
|
||||
\fR\&%U\fR
|
||||
\&%U
|
||||
expanded to the login name of the user the command will be run as
|
||||
(defaults to root unless the
|
||||
\fB\-u\fR
|
||||
option is also specified)
|
||||
.TP 4n
|
||||
\fR%u\fR
|
||||
%u
|
||||
expanded to the invoking user's login name
|
||||
.TP 4n
|
||||
\fR%%\fR
|
||||
%%
|
||||
two consecutive
|
||||
\(oq%\(cq
|
||||
characters are collapsed into a single
|
||||
@ -691,7 +703,7 @@ may be either a user name or a numeric user-ID
|
||||
prefixed with the
|
||||
\(oq#\(cq
|
||||
character (e.g.,
|
||||
\fR#0\fR
|
||||
\(oq#0\(cq
|
||||
for UID 0).
|
||||
When running commands as a UID, many shells require that the
|
||||
\(oq#\(cq
|
||||
@ -724,9 +736,7 @@ For the
|
||||
\fIsudoers\fR
|
||||
plugin, this extends the
|
||||
\fBsudo\fR
|
||||
timeout for another
|
||||
\fR@timeout@\fR
|
||||
minutes by default, but does not run a command.
|
||||
timeout for another @timeout@ minutes by default, but does not run a command.
|
||||
Not all security policies support cached credentials.
|
||||
.TP 12n
|
||||
\fB\--\fR
|
||||
@ -762,7 +772,7 @@ option is set in
|
||||
the command to be run has the
|
||||
\fRSETENV\fR
|
||||
tag set or the command matched is
|
||||
\fRALL\fR,
|
||||
\fBALL\fR,
|
||||
the user may set variables that would otherwise be forbidden.
|
||||
See
|
||||
sudoers(@mansectform@)
|
||||
@ -970,7 +980,7 @@ run in a new pty,
|
||||
may execute the command directly instead of running it as a child process.
|
||||
.SS "Plugins"
|
||||
Plugins may be specified via
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
directives in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
@ -981,7 +991,7 @@ binary.
|
||||
If no
|
||||
sudo.conf(@mansectform@)
|
||||
file is present, or if it doesn't contain any
|
||||
\fRPlugin\fR
|
||||
\fIPlugin\fR
|
||||
lines,
|
||||
\fBsudo\fR
|
||||
will use
|
||||
@ -1070,9 +1080,9 @@ By default,
|
||||
\fBsudo\fR
|
||||
will only log the command it explicitly runs.
|
||||
If a user runs a command such as
|
||||
\fRsudo su\fR
|
||||
\(oqsudo su\(cq
|
||||
or
|
||||
\fRsudo sh\fR,
|
||||
\(oqsudo sh\(cq,
|
||||
subsequent commands run from that shell are not subject to
|
||||
\fBsudo\fR's
|
||||
security policy.
|
||||
@ -1160,7 +1170,7 @@ or when
|
||||
is enabled in
|
||||
\fIsudoers\fR
|
||||
and
|
||||
\fIHOME\fR
|
||||
\fRHOME\fR
|
||||
is not present in the
|
||||
\fIenv_keep\fR
|
||||
list.
|
||||
@ -1210,8 +1220,7 @@ Default editor to use in
|
||||
Set to the group-ID of the user who invoked sudo.
|
||||
.TP 17n
|
||||
\fRSUDO_PROMPT\fR
|
||||
Used as the default password prompt unless
|
||||
the
|
||||
Used as the default password prompt unless the
|
||||
\fB\-p\fR
|
||||
option was specified.
|
||||
.TP 17n
|
||||
@ -1299,7 +1308,7 @@ $ sudo shutdown -r +15 "quick reboot"
|
||||
.PP
|
||||
To make a usage listing of the directories in the /home partition.
|
||||
The commands are run in a sub-shell to allow the
|
||||
\fRcd\fR
|
||||
\(oqcd\(cq
|
||||
command and file redirection to work.
|
||||
.nf
|
||||
.sp
|
||||
@ -1484,7 +1493,7 @@ plugin's
|
||||
functionality.
|
||||
.PP
|
||||
It is not meaningful to run the
|
||||
\fRcd\fR
|
||||
\(oqcd\(cq
|
||||
command directly via sudo, e.g.,
|
||||
.nf
|
||||
.sp
|
||||
|
@ -24,7 +24,7 @@
|
||||
.nr BA @BAMAN@
|
||||
.nr LC @LCMAN@
|
||||
.nr PS @PSMAN@
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDO @mansectsu@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -36,7 +36,7 @@
|
||||
.Fl h | K | k | V
|
||||
.Nm sudo
|
||||
.Fl v
|
||||
.Op Fl ABknS
|
||||
.Op Fl ABkNnS
|
||||
.if \n(BA \{\
|
||||
.Op Fl a Ar type
|
||||
.\}
|
||||
@ -46,7 +46,7 @@
|
||||
.Op Fl u Ar user
|
||||
.Nm sudo
|
||||
.Fl l
|
||||
.Op Fl ABknS
|
||||
.Op Fl ABkNnS
|
||||
.if \n(BA \{\
|
||||
.Op Fl a Ar type
|
||||
.\}
|
||||
@ -80,7 +80,7 @@
|
||||
.Op Fl i | s
|
||||
.Op Ar command
|
||||
.Nm sudoedit
|
||||
.Op Fl ABknS
|
||||
.Op Fl ABkNnS
|
||||
.if \n(BA \{\
|
||||
.Op Fl a Ar type
|
||||
.\}
|
||||
@ -139,9 +139,7 @@ time limit.
|
||||
This limit is policy-specific; the default password prompt timeout
|
||||
for the
|
||||
.Em sudoers
|
||||
security policy is
|
||||
.Li @password_timeout@
|
||||
minutes.
|
||||
security policy is @password_timeout@ minutes.
|
||||
.Pp
|
||||
Security policies may support credential caching to allow the user
|
||||
to run
|
||||
@ -149,9 +147,7 @@ to run
|
||||
again for a period of time without requiring authentication.
|
||||
By default, the
|
||||
.Em sudoers
|
||||
policy caches credentials on a per-terminal basis for
|
||||
.Li @timeout@
|
||||
minutes.
|
||||
policy caches credentials on a per-terminal basis for @timeout@ minutes.
|
||||
See the
|
||||
.Em timestamp_type
|
||||
and
|
||||
@ -380,7 +376,7 @@ may be either a group name or a numeric group-ID
|
||||
prefixed with the
|
||||
.Ql #
|
||||
character (e.g.,
|
||||
.Li #0
|
||||
.Ql #0
|
||||
for GID 0).
|
||||
When running a command as a GID, many shells require that the
|
||||
.Ql #
|
||||
@ -505,6 +501,17 @@ If a
|
||||
is specified but not allowed by the policy,
|
||||
.Nm
|
||||
will exit with a status value of 1.
|
||||
.It Fl N , -no-update
|
||||
Do not update the user's cached credentials, even if the user successfully
|
||||
authenticates.
|
||||
Unlike the
|
||||
.Fl k
|
||||
flag, existing cached credentials are used if they are valid.
|
||||
To detect when the user's cached credentials are valid (or when no
|
||||
authentication is required), the following command can be used:
|
||||
.Dl sudo -Nnv
|
||||
.Pp
|
||||
Not all security policies support credential caching.
|
||||
.It Fl n , -non-interactive
|
||||
Avoid prompting the user for input of any kind.
|
||||
If a password is required for the command to run,
|
||||
@ -526,15 +533,15 @@ escape sequences are supported by the
|
||||
.Em sudoers
|
||||
policy:
|
||||
.Bl -tag -width 2n
|
||||
.It Li %H
|
||||
.It %H
|
||||
expanded to the host name including the domain name (only if the
|
||||
machine's host name is fully qualified or the
|
||||
.Em fqdn
|
||||
option is set in
|
||||
.Xr sudoers @mansectform@ )
|
||||
.It Li %h
|
||||
.It %h
|
||||
expanded to the local host name without the domain name
|
||||
.It Li %p
|
||||
.It %p
|
||||
expanded to the name of the user whose password is being requested
|
||||
(respects the
|
||||
.Em rootpw ,
|
||||
@ -543,14 +550,14 @@ and
|
||||
.Em runaspw
|
||||
flags in
|
||||
.Xr sudoers @mansectform@ )
|
||||
.It Li \&%U
|
||||
.It \&%U
|
||||
expanded to the login name of the user the command will be run as
|
||||
(defaults to root unless the
|
||||
.Fl u
|
||||
option is also specified)
|
||||
.It Li %u
|
||||
.It %u
|
||||
expanded to the invoking user's login name
|
||||
.It Li %%
|
||||
.It %%
|
||||
two consecutive
|
||||
.Ql %
|
||||
characters are collapsed into a single
|
||||
@ -645,7 +652,7 @@ may be either a user name or a numeric user-ID
|
||||
prefixed with the
|
||||
.Ql #
|
||||
character (e.g.,
|
||||
.Li #0
|
||||
.Ql #0
|
||||
for UID 0).
|
||||
When running commands as a UID, many shells require that the
|
||||
.Ql #
|
||||
@ -676,9 +683,7 @@ For the
|
||||
.Em sudoers
|
||||
plugin, this extends the
|
||||
.Nm
|
||||
timeout for another
|
||||
.Li @timeout@
|
||||
minutes by default, but does not run a command.
|
||||
timeout for another @timeout@ minutes by default, but does not run a command.
|
||||
Not all security policies support cached credentials.
|
||||
.It Fl -
|
||||
The
|
||||
@ -712,9 +717,9 @@ If the
|
||||
option is set in
|
||||
.Em sudoers ,
|
||||
the command to be run has the
|
||||
.Li SETENV
|
||||
.Dv SETENV
|
||||
tag set or the command matched is
|
||||
.Li ALL ,
|
||||
.Sy ALL ,
|
||||
the user may set variables that would otherwise be forbidden.
|
||||
See
|
||||
.Xr sudoers @mansectform@
|
||||
@ -911,7 +916,7 @@ run in a new pty,
|
||||
may execute the command directly instead of running it as a child process.
|
||||
.Ss Plugins
|
||||
Plugins may be specified via
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
directives in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
@ -922,7 +927,7 @@ binary.
|
||||
If no
|
||||
.Xr sudo.conf @mansectform@
|
||||
file is present, or if it doesn't contain any
|
||||
.Li Plugin
|
||||
.Em Plugin
|
||||
lines,
|
||||
.Nm
|
||||
will use
|
||||
@ -1011,9 +1016,9 @@ By default,
|
||||
.Nm
|
||||
will only log the command it explicitly runs.
|
||||
If a user runs a command such as
|
||||
.Li sudo su
|
||||
.Ql sudo su
|
||||
or
|
||||
.Li sudo sh ,
|
||||
.Ql sudo sh ,
|
||||
subsequent commands run from that shell are not subject to
|
||||
.Nm sudo Ns 's
|
||||
security policy.
|
||||
@ -1096,7 +1101,7 @@ or when
|
||||
is enabled in
|
||||
.Em sudoers
|
||||
and
|
||||
.Em HOME
|
||||
.Ev HOME
|
||||
is not present in the
|
||||
.Em env_keep
|
||||
list.
|
||||
@ -1138,8 +1143,7 @@ Default editor to use in
|
||||
.It Ev SUDO_GID
|
||||
Set to the group-ID of the user who invoked sudo.
|
||||
.It Ev SUDO_PROMPT
|
||||
Used as the default password prompt unless
|
||||
the
|
||||
Used as the default password prompt unless the
|
||||
.Fl p
|
||||
option was specified.
|
||||
.It Ev SUDO_PS1
|
||||
@ -1206,7 +1210,7 @@ $ sudo shutdown -r +15 "quick reboot"
|
||||
.Pp
|
||||
To make a usage listing of the directories in the /home partition.
|
||||
The commands are run in a sub-shell to allow the
|
||||
.Li cd
|
||||
.Ql cd
|
||||
command and file redirection to work.
|
||||
.Bd -literal -offset 4n
|
||||
$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
|
||||
@ -1374,7 +1378,7 @@ plugin's
|
||||
functionality.
|
||||
.Pp
|
||||
It is not meaningful to run the
|
||||
.Li cd
|
||||
.Ql cd
|
||||
command directly via sudo, e.g.,
|
||||
.Bd -literal -offset 4n
|
||||
$ sudo cd /usr/local/protected
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -93,7 +93,7 @@ message TimeSpec {
|
||||
A
|
||||
\fITimeSpec\fR
|
||||
is the equivalent of a POSIX
|
||||
\fRstruct timespec\fR,
|
||||
\fIstruct timespec\fR,
|
||||
containing seconds and nanoseconds members.
|
||||
The
|
||||
\fItv_sec\fR
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDO_LOGSRV.PROTO @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -87,7 +87,7 @@ message TimeSpec {
|
||||
A
|
||||
.Em TimeSpec
|
||||
is the equivalent of a POSIX
|
||||
.Li struct timespec ,
|
||||
.Vt struct timespec ,
|
||||
containing seconds and nanoseconds members.
|
||||
The
|
||||
.Em tv_sec
|
||||
@ -237,10 +237,10 @@ If the command was terminated by a signal, this is set to the
|
||||
name of the signal without the leading
|
||||
.Dq SIG .
|
||||
For example,
|
||||
.Li INT ,
|
||||
.Li TERM ,
|
||||
.Li KILL ,
|
||||
.Li SEGV .
|
||||
.Dv INT ,
|
||||
.Dv TERM ,
|
||||
.Dv KILL ,
|
||||
.Dv SEGV .
|
||||
.It error
|
||||
A message from the client indicating that the command was terminated
|
||||
unexpectedly due to an error.
|
||||
@ -397,9 +397,9 @@ should be calculated using a monotonic clock where possible.
|
||||
The signal name without the leading
|
||||
.Dq SIG .
|
||||
For example,
|
||||
.Li STOP ,
|
||||
.Li TSTP ,
|
||||
.Li CONT .
|
||||
.Dv STOP ,
|
||||
.Dv TSTP ,
|
||||
.Dv CONT .
|
||||
.El
|
||||
.Sh Server Messages
|
||||
A
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -168,14 +168,16 @@ will enable the TCP keepalive socket option on the client connection.
|
||||
This enables the periodic transmission of keepalive messages to the client.
|
||||
If the client does not respond to a message in time, the connection will
|
||||
be closed.
|
||||
Defaults to true.
|
||||
Defaults to
|
||||
\fItrue\fR.
|
||||
.TP 10n
|
||||
timeout = number
|
||||
The amount of time, in seconds,
|
||||
\fBsudo_logsrvd\fR
|
||||
will wait for the client to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
\fI30\fR.
|
||||
.TP 10n
|
||||
tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
@ -202,7 +204,7 @@ authority, the
|
||||
setting must be set to a CA bundle that contains the CA certificate
|
||||
used to generate the client certificate.
|
||||
The default value is
|
||||
\fRfalse\fR.
|
||||
\fIfalse\fR.
|
||||
.TP 10n
|
||||
tls_ciphers_v12 = string
|
||||
A list of ciphers to use for connections secured by TLS version 1.2 only,
|
||||
@ -214,7 +216,7 @@ section in
|
||||
openssl-ciphers(1)
|
||||
for full details.
|
||||
The default value is
|
||||
\fRHIGH:!aNULL\fR
|
||||
\(lqHIGH:!aNULL\(rq
|
||||
which consists of encryption cipher suites with key lengths larger than
|
||||
128 bits, and some cipher suites with 128-bit keys.
|
||||
Cipher suites that offer no authentication are excluded.
|
||||
@ -241,7 +243,8 @@ TLS_AES_128_CCM_8_SHA256
|
||||
.RE
|
||||
.RS 10n
|
||||
.sp
|
||||
The default cipher suite is TLS_AES_256_GCM_SHA384.
|
||||
The default cipher suite is
|
||||
\(lqTLS_AES_256_GCM_SHA384\(rq.
|
||||
.RE
|
||||
.PD
|
||||
.TP 10n
|
||||
@ -274,7 +277,8 @@ configuration is changed.
|
||||
If false, no verification is performed of the server certificate.
|
||||
When using self-signed certificates without a certificate authority,
|
||||
this setting should be set to false.
|
||||
The default value is true.
|
||||
The default value is
|
||||
\fItrue\fR.
|
||||
.SS "relay"
|
||||
The
|
||||
\fIrelay\fR
|
||||
@ -301,7 +305,8 @@ setting controls the amount of time
|
||||
\fBsudo_logsrvd\fR
|
||||
will wait for the relay to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
\fI30\fR.
|
||||
.TP 10n
|
||||
relay_dir = path
|
||||
The directory in which log messages are temporarily stored before they
|
||||
@ -339,7 +344,8 @@ lines are specified, the first available relay host will be used.
|
||||
retry_interval = number
|
||||
The number of seconds to wait after a connection error before making
|
||||
a new attempt to forward a message to a relay host.
|
||||
The default value is 30 seconds.
|
||||
The default value is
|
||||
\fI30\fR.
|
||||
.TP 10n
|
||||
store_first = boolean
|
||||
If true,
|
||||
@ -365,7 +371,8 @@ The amount of time, in seconds,
|
||||
\fBsudo_logsrvd\fR
|
||||
will wait for the relay server to respond after a connection has succeeded.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
\fI30\fR.
|
||||
.TP 10n
|
||||
tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
@ -455,7 +462,7 @@ If set, I/O logs will be compressed using
|
||||
Enabling compression can make it harder to view the logs in real-time as
|
||||
the program is executing due to buffering.
|
||||
The default value is
|
||||
\fRfalse\fR.
|
||||
\fIfalse\fR.
|
||||
.TP 10n
|
||||
iolog_dir = path
|
||||
The top-level directory to use when constructing the path
|
||||
@ -471,30 +478,30 @@ escape sequences are supported:
|
||||
.RS 10n
|
||||
.PD 0
|
||||
.TP 6n
|
||||
\fR%{seq}\fR
|
||||
%{seq}
|
||||
expanded to a monotonically increasing base-36 sequence number, such as 0100A5,
|
||||
where every two digits are used to form a new directory, e.g.,
|
||||
\fI01/00/A5\fR
|
||||
.PD
|
||||
.TP 6n
|
||||
\fR%{user}\fR
|
||||
%{user}
|
||||
expanded to the invoking user's login name
|
||||
.TP 6n
|
||||
\fR%{group}\fR
|
||||
%{group}
|
||||
expanded to the name of the invoking user's real group-ID
|
||||
.TP 6n
|
||||
\fR%{runas_user}\fR
|
||||
%{runas_user}
|
||||
expanded to the login name of the user the command will
|
||||
be run as (e.g., root)
|
||||
.TP 6n
|
||||
\fR%{runas_group}\fR
|
||||
%{runas_group}
|
||||
expanded to the group name of the user the command will
|
||||
be run as (e.g., wheel)
|
||||
.TP 6n
|
||||
\fR%{hostname}\fR
|
||||
%{hostname}
|
||||
expanded to the local host name without the domain name
|
||||
.TP 6n
|
||||
\fR%{command}\fR
|
||||
%{command}
|
||||
expanded to the base name of the command being run
|
||||
.PP
|
||||
In addition, any escape sequences supported by the system's
|
||||
@ -516,7 +523,7 @@ It is possible for
|
||||
\fIiolog_file\fR
|
||||
to contain directory components.
|
||||
The default value is
|
||||
\fR%{seq}\fR.
|
||||
\(lq%{seq}\(rq.
|
||||
.sp
|
||||
See the
|
||||
\fIiolog_dir\fR
|
||||
@ -526,9 +533,9 @@ escape sequences.
|
||||
.sp
|
||||
In addition to the escape sequences, path names that end in six or
|
||||
more
|
||||
\fRX\fRs
|
||||
\fIX\fRs
|
||||
will have the
|
||||
\fRX\fRs
|
||||
\fIX\fRs
|
||||
replaced with a unique combination of digits and letters, similar to the
|
||||
mktemp(3)
|
||||
function.
|
||||
@ -542,7 +549,7 @@ overwritten unless
|
||||
\fIiolog_file\fR
|
||||
ends in six or
|
||||
more
|
||||
\fRX\fRs.
|
||||
\fIX\fRs.
|
||||
.TP 10n
|
||||
iolog_flush = boolean
|
||||
If set, I/O log data is flushed to disk after each write instead of
|
||||
@ -553,7 +560,7 @@ of I/O log compression.
|
||||
I/O logs are always flushed before sending a commit point to the client
|
||||
regardless of this setting.
|
||||
The default value is
|
||||
\fRtrue\fR.
|
||||
\fItrue\fR.
|
||||
.TP 10n
|
||||
iolog_group = name
|
||||
The group name to look up when setting the group-ID on new I/O log
|
||||
@ -579,7 +586,7 @@ When creating I/O log directories, search (execute) bits are added
|
||||
to match the read and write bits specified by
|
||||
\fIiolog_mode\fR.
|
||||
The default value is
|
||||
\fR0600\fR.
|
||||
\fI0600\fR.
|
||||
.TP 10n
|
||||
iolog_user = name
|
||||
The user name to look up when setting the owner of new
|
||||
@ -599,7 +606,7 @@ the password will still be present in the I/O log.
|
||||
If
|
||||
\fIlog_passwords\fR
|
||||
is set to
|
||||
\fRfalse\fR,
|
||||
\fIfalse\fR,
|
||||
\fBsudo_logsrvd\fR
|
||||
will attempt to prevent passwords from being logged.
|
||||
It does this by using the regular expressions in
|
||||
@ -617,16 +624,16 @@ when the
|
||||
option is set), only the
|
||||
first character of the password will be replaced in the I/O log.
|
||||
The default value is
|
||||
\fRtrue\fR.
|
||||
\fItrue\fR.
|
||||
.TP 10n
|
||||
maxseq = number
|
||||
The maximum sequence number that will be substituted for the
|
||||
\(lq\fR%{seq}\fR\(rq
|
||||
\(lq%{seq}\(rq
|
||||
escape in the I/O log file (see the
|
||||
\fIiolog_dir\fR
|
||||
description above for more information).
|
||||
While the value substituted for
|
||||
\(lq\fR%{seq}\fR\(rq
|
||||
\(lq%{seq}\(rq
|
||||
is in base 36,
|
||||
\fImaxseq\fR
|
||||
itself should be expressed in decimal.
|
||||
@ -634,7 +641,8 @@ Values larger than 2176782336 (which corresponds to the
|
||||
base 36 sequence number
|
||||
\(lqZZZZZZ\(rq)
|
||||
will be silently truncated to 2176782336.
|
||||
The default value is 2176782336.
|
||||
The default value is
|
||||
\fI2176782336\fR.
|
||||
.TP 10n
|
||||
passprompt_regex = string
|
||||
One or more POSIX extended regular expressions used to
|
||||
@ -669,7 +677,8 @@ log_exit = boolean
|
||||
If true,
|
||||
\fBsudo_logsrvd\fR
|
||||
will log an event when a command exits or is terminated by a signal.
|
||||
Defaults to false.
|
||||
Defaults to
|
||||
\fIfalse\fR.
|
||||
.TP 6n
|
||||
log_format = string
|
||||
The event log format.
|
||||
@ -691,7 +700,7 @@ syslog(3).
|
||||
facility = string
|
||||
Syslog facility if syslog is being used for logging.
|
||||
Defaults to
|
||||
\fR@logfac@\fR.
|
||||
\fI@logfac@\fR.
|
||||
.sp
|
||||
The following syslog facilities are supported:
|
||||
\fBauthpriv\fR
|
||||
@ -714,7 +723,7 @@ accept_priority = string
|
||||
Syslog priority to use when the user is allowed to run a command and
|
||||
authentication is successful.
|
||||
Defaults to
|
||||
\fR@goodpri@\fR.
|
||||
\fI@goodpri@\fR.
|
||||
.sp
|
||||
The following syslog priorities are supported:
|
||||
\fBalert\fR,
|
||||
@ -735,7 +744,7 @@ reject_priority = string
|
||||
Syslog priority to use when the user is not allowed to run a command or
|
||||
when authentication is unsuccessful.
|
||||
Defaults to
|
||||
\fR@badpri@\fR.
|
||||
\fI@badpri@\fR.
|
||||
.sp
|
||||
See
|
||||
\fIaccept_priority\fR
|
||||
@ -744,7 +753,7 @@ for the list of supported syslog priorities.
|
||||
alert_priority = string
|
||||
Syslog priority to use for event log alert messages received from the client.
|
||||
Defaults to
|
||||
\fR@badpri@\fR.
|
||||
\fI@badpri@\fR.
|
||||
.sp
|
||||
See
|
||||
\fIaccept_priority\fR
|
||||
@ -779,7 +788,7 @@ server_facility = string
|
||||
Syslog facility if syslog is being used for server warning messages.
|
||||
See above for a list of supported facilities.
|
||||
Defaults to
|
||||
\fRdaemon\fR
|
||||
\fIdaemon\fR
|
||||
.SS "logfile"
|
||||
The
|
||||
\fIlogfile\fR
|
||||
@ -800,10 +809,12 @@ Formatting is performed via the system's
|
||||
strftime(3)
|
||||
function so any escape sequences supported by that function will be expanded.
|
||||
The default value is
|
||||
\(lq\fR%h %e %T\fR\(rq
|
||||
\(lq%h %e %T\(rq
|
||||
which produces dates like
|
||||
\(lqOct 3 07:15:24\(rq
|
||||
in the C locale.
|
||||
in the
|
||||
\(oqC\(cq
|
||||
locale.
|
||||
.SH "FILES"
|
||||
.TP 26n
|
||||
\fI@sysconfdir@/sudo_logsrvd.conf\fR
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDO_LOGSRVD.CONF @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -152,13 +152,15 @@ will enable the TCP keepalive socket option on the client connection.
|
||||
This enables the periodic transmission of keepalive messages to the client.
|
||||
If the client does not respond to a message in time, the connection will
|
||||
be closed.
|
||||
Defaults to true.
|
||||
Defaults to
|
||||
.Em true .
|
||||
.It timeout = number
|
||||
The amount of time, in seconds,
|
||||
.Nm sudo_logsrvd
|
||||
will wait for the client to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
.Em 30 .
|
||||
.It tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
to use instead of the system's default certificate authority database
|
||||
@ -182,7 +184,7 @@ authority, the
|
||||
setting must be set to a CA bundle that contains the CA certificate
|
||||
used to generate the client certificate.
|
||||
The default value is
|
||||
.Li false .
|
||||
.Em false .
|
||||
.It tls_ciphers_v12 = string
|
||||
A list of ciphers to use for connections secured by TLS version 1.2 only,
|
||||
separated by a colon
|
||||
@ -193,7 +195,7 @@ section in
|
||||
.Xr openssl-ciphers 1
|
||||
for full details.
|
||||
The default value is
|
||||
.Li HIGH:!aNULL
|
||||
.Dq HIGH:!aNULL
|
||||
which consists of encryption cipher suites with key lengths larger than
|
||||
128 bits, and some cipher suites with 128-bit keys.
|
||||
Cipher suites that offer no authentication are excluded.
|
||||
@ -212,7 +214,8 @@ but should include the following:
|
||||
.It TLS_AES_128_CCM_8_SHA256
|
||||
.El
|
||||
.Pp
|
||||
The default cipher suite is TLS_AES_256_GCM_SHA384.
|
||||
The default cipher suite is
|
||||
.Dq TLS_AES_256_GCM_SHA384 .
|
||||
.It tls_dhparams = path
|
||||
The path to a file containing custom Diffie-Hellman parameters in PEM format.
|
||||
This file can be created with the following command:
|
||||
@ -235,7 +238,8 @@ configuration is changed.
|
||||
If false, no verification is performed of the server certificate.
|
||||
When using self-signed certificates without a certificate authority,
|
||||
this setting should be set to false.
|
||||
The default value is true.
|
||||
The default value is
|
||||
.Em true .
|
||||
.El
|
||||
.Ss relay
|
||||
The
|
||||
@ -263,7 +267,8 @@ setting controls the amount of time
|
||||
.Nm sudo_logsrvd
|
||||
will wait for the relay to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
.Em 30 .
|
||||
.It relay_dir = path
|
||||
The directory in which log messages are temporarily stored before they
|
||||
are sent to the relay host.
|
||||
@ -298,7 +303,8 @@ lines are specified, the first available relay host will be used.
|
||||
.It retry_interval = number
|
||||
The number of seconds to wait after a connection error before making
|
||||
a new attempt to forward a message to a relay host.
|
||||
The default value is 30 seconds.
|
||||
The default value is
|
||||
.Em 30 .
|
||||
.It store_first = boolean
|
||||
If true,
|
||||
.Nm sudo_logsrvd
|
||||
@ -321,7 +327,8 @@ The amount of time, in seconds,
|
||||
.Nm sudo_logsrvd
|
||||
will wait for the relay server to respond after a connection has succeeded.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
The default value is
|
||||
.Em 30 .
|
||||
.It tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
to use instead of the system's default certificate authority database
|
||||
@ -404,7 +411,7 @@ If set, I/O logs will be compressed using
|
||||
Enabling compression can make it harder to view the logs in real-time as
|
||||
the program is executing due to buffering.
|
||||
The default value is
|
||||
.Li false .
|
||||
.Em false .
|
||||
.It iolog_dir = path
|
||||
The top-level directory to use when constructing the path
|
||||
name for the I/O log directory.
|
||||
@ -416,23 +423,23 @@ The following percent
|
||||
.Pq Ql %
|
||||
escape sequences are supported:
|
||||
.Bl -tag -width 4n
|
||||
.It Li %{seq}
|
||||
.It %{seq}
|
||||
expanded to a monotonically increasing base-36 sequence number, such as 0100A5,
|
||||
where every two digits are used to form a new directory, e.g.,
|
||||
.Pa 01/00/A5
|
||||
.It Li %{user}
|
||||
.It %{user}
|
||||
expanded to the invoking user's login name
|
||||
.It Li %{group}
|
||||
.It %{group}
|
||||
expanded to the name of the invoking user's real group-ID
|
||||
.It Li %{runas_user}
|
||||
.It %{runas_user}
|
||||
expanded to the login name of the user the command will
|
||||
be run as (e.g., root)
|
||||
.It Li %{runas_group}
|
||||
.It %{runas_group}
|
||||
expanded to the group name of the user the command will
|
||||
be run as (e.g., wheel)
|
||||
.It Li %{hostname}
|
||||
.It %{hostname}
|
||||
expanded to the local host name without the domain name
|
||||
.It Li %{command}
|
||||
.It %{command}
|
||||
expanded to the base name of the command being run
|
||||
.El
|
||||
.Pp
|
||||
@ -453,7 +460,7 @@ It is possible for
|
||||
.Em iolog_file
|
||||
to contain directory components.
|
||||
The default value is
|
||||
.Li %{seq} .
|
||||
.Dq %{seq} .
|
||||
.Pp
|
||||
See the
|
||||
.Em iolog_dir
|
||||
@ -463,9 +470,9 @@ escape sequences.
|
||||
.Pp
|
||||
In addition to the escape sequences, path names that end in six or
|
||||
more
|
||||
.Li X Ns s
|
||||
.Em X Ns s
|
||||
will have the
|
||||
.Li X Ns s
|
||||
.Em X Ns s
|
||||
replaced with a unique combination of digits and letters, similar to the
|
||||
.Xr mktemp 3
|
||||
function.
|
||||
@ -479,7 +486,7 @@ overwritten unless
|
||||
.Em iolog_file
|
||||
ends in six or
|
||||
more
|
||||
.Li X Ns s .
|
||||
.Em X Ns s .
|
||||
.It iolog_flush = boolean
|
||||
If set, I/O log data is flushed to disk after each write instead of
|
||||
buffering it.
|
||||
@ -489,7 +496,7 @@ of I/O log compression.
|
||||
I/O logs are always flushed before sending a commit point to the client
|
||||
regardless of this setting.
|
||||
The default value is
|
||||
.Li true .
|
||||
.Em true .
|
||||
.It iolog_group = name
|
||||
The group name to look up when setting the group-ID on new I/O log
|
||||
files and directories.
|
||||
@ -513,7 +520,7 @@ When creating I/O log directories, search (execute) bits are added
|
||||
to match the read and write bits specified by
|
||||
.Em iolog_mode .
|
||||
The default value is
|
||||
.Li 0600 .
|
||||
.Em 0600 .
|
||||
.It iolog_user = name
|
||||
The user name to look up when setting the owner of new
|
||||
I/O log files and directories.
|
||||
@ -531,7 +538,7 @@ the password will still be present in the I/O log.
|
||||
If
|
||||
.Em log_passwords
|
||||
is set to
|
||||
.Li false ,
|
||||
.Em false ,
|
||||
.Nm sudo_logsrvd
|
||||
will attempt to prevent passwords from being logged.
|
||||
It does this by using the regular expressions in
|
||||
@ -549,15 +556,15 @@ when the
|
||||
option is set), only the
|
||||
first character of the password will be replaced in the I/O log.
|
||||
The default value is
|
||||
.Li true .
|
||||
.Em true .
|
||||
.It maxseq = number
|
||||
The maximum sequence number that will be substituted for the
|
||||
.Dq Li %{seq}
|
||||
.Dq %{seq}
|
||||
escape in the I/O log file (see the
|
||||
.Em iolog_dir
|
||||
description above for more information).
|
||||
While the value substituted for
|
||||
.Dq Li %{seq}
|
||||
.Dq %{seq}
|
||||
is in base 36,
|
||||
.Em maxseq
|
||||
itself should be expressed in decimal.
|
||||
@ -565,7 +572,8 @@ Values larger than 2176782336 (which corresponds to the
|
||||
base 36 sequence number
|
||||
.Dq ZZZZZZ )
|
||||
will be silently truncated to 2176782336.
|
||||
The default value is 2176782336.
|
||||
The default value is
|
||||
.Em 2176782336 .
|
||||
.It passprompt_regex = string
|
||||
One or more POSIX extended regular expressions used to
|
||||
match password prompts in the terminal output when
|
||||
@ -599,7 +607,8 @@ The default value is
|
||||
If true,
|
||||
.Nm sudo_logsrvd
|
||||
will log an event when a command exits or is terminated by a signal.
|
||||
Defaults to false.
|
||||
Defaults to
|
||||
.Em false .
|
||||
.It log_format = string
|
||||
The event log format.
|
||||
Supported log formats are
|
||||
@ -621,7 +630,7 @@ section configures how events are logged via
|
||||
.It facility = string
|
||||
Syslog facility if syslog is being used for logging.
|
||||
Defaults to
|
||||
.Li @logfac@ .
|
||||
.Em @logfac@ .
|
||||
.Pp
|
||||
The following syslog facilities are supported:
|
||||
.Sy authpriv
|
||||
@ -643,7 +652,7 @@ and
|
||||
Syslog priority to use when the user is allowed to run a command and
|
||||
authentication is successful.
|
||||
Defaults to
|
||||
.Li @goodpri@ .
|
||||
.Em @goodpri@ .
|
||||
.Pp
|
||||
The following syslog priorities are supported:
|
||||
.Sy alert ,
|
||||
@ -663,7 +672,7 @@ will disable logging of successful commands.
|
||||
Syslog priority to use when the user is not allowed to run a command or
|
||||
when authentication is unsuccessful.
|
||||
Defaults to
|
||||
.Li @badpri@ .
|
||||
.Em @badpri@ .
|
||||
.Pp
|
||||
See
|
||||
.Em accept_priority
|
||||
@ -671,7 +680,7 @@ for the list of supported syslog priorities.
|
||||
.It alert_priority = string
|
||||
Syslog priority to use for event log alert messages received from the client.
|
||||
Defaults to
|
||||
.Li @badpri@ .
|
||||
.Em @badpri@ .
|
||||
.Pp
|
||||
See
|
||||
.Em accept_priority
|
||||
@ -704,7 +713,7 @@ JSON-format log entries are never split and are not affected by
|
||||
Syslog facility if syslog is being used for server warning messages.
|
||||
See above for a list of supported facilities.
|
||||
Defaults to
|
||||
.Li daemon
|
||||
.Em daemon
|
||||
.El
|
||||
.Ss logfile
|
||||
The
|
||||
@ -725,10 +734,12 @@ Formatting is performed via the system's
|
||||
.Xr strftime 3
|
||||
function so any escape sequences supported by that function will be expanded.
|
||||
The default value is
|
||||
.Dq Li "%h %e %T"
|
||||
.Dq "%h %e %T"
|
||||
which produces dates like
|
||||
.Dq Oct 3 07:15:24
|
||||
in the C locale.
|
||||
in the
|
||||
.Ql C
|
||||
locale.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width 24n
|
||||
|
@ -117,7 +117,7 @@ section.
|
||||
.SS "Debugging sudo_logsrvd"
|
||||
\fBsudo_logsrvd\fR
|
||||
supports a flexible debugging framework that is configured via
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
lines in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
|
@ -112,7 +112,7 @@ section.
|
||||
.Ss Debugging sudo_logsrvd
|
||||
.Nm
|
||||
supports a flexible debugging framework that is configured via
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
lines in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_PLUGIN_PYTHON" "5" "June 6, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_PLUGIN_PYTHON" "5" "September 11, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -96,9 +96,9 @@ When the plugin loads,
|
||||
will create an instance of this class and call the methods.
|
||||
The actual methods required depent on the type of the plugin,
|
||||
but most return an
|
||||
\(lqint\(rq
|
||||
\fIint\fR
|
||||
result code, as documented in
|
||||
sudo_plugin(@mansectsu@),
|
||||
sudo_plugin(@mansectform@),
|
||||
that indicates whether or not the method was successful.
|
||||
The Python sudo module defines the following constants to improve readability:
|
||||
.RS 4n
|
||||
@ -120,12 +120,12 @@ l l.
|
||||
.RE
|
||||
.PP
|
||||
If a function returns
|
||||
\fINone\fR
|
||||
\fRNone\fR
|
||||
(for example, if it does not call return),
|
||||
it will be considered to have returned
|
||||
\fRsudo.RC.OK\fR.
|
||||
If an exception is raised (other than sudo.PluginException), the backtrace will be
|
||||
shown to the user and the plugin function will return
|
||||
If an exception is raised (other than sudo.PluginException), the
|
||||
backtrace will be shown to the user and the plugin function will return
|
||||
\fRsudo.RC.ERROR\fR.
|
||||
If that is not acceptable, you must catch the exception and handle it yourself.
|
||||
.PP
|
||||
@ -151,7 +151,7 @@ Running the Python interpreter and bridging between C and Python is
|
||||
handled by the
|
||||
\fBsudo\fR
|
||||
plugin
|
||||
\fRpython_plugin.so\fR.
|
||||
\fIpython_plugin.so\fR.
|
||||
This shared object can be loaded like any other dynamic
|
||||
\fBsudo\fR
|
||||
plugin and should receive the path and the class name of the Python
|
||||
@ -219,7 +219,7 @@ sudo.conf(@mansectform@).
|
||||
.PP
|
||||
A policy plugin may have the following member functions:
|
||||
.TP 6n
|
||||
\fBconstructor\fR
|
||||
\fIconstructor\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
@ -235,7 +235,9 @@ as member variables in the object.
|
||||
.sp
|
||||
The constructor matches the
|
||||
\fBopen\fR()
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.TP 6n
|
||||
@ -279,7 +281,7 @@ documentation in
|
||||
sudo_plugin(@mansectform@).
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBcheck_policy\fR
|
||||
\fIcheck_policy\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
check_policy(self, argv: Tuple[str, ...], env_add: Tuple[str, ...])
|
||||
@ -367,7 +369,7 @@ format.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBinit_session\fR
|
||||
\fIinit_session\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
init_session(self, user_pwd: Tuple, user_env: Tuple[str, ...])
|
||||
@ -387,8 +389,9 @@ The function arguments are as follows:
|
||||
.TP 6n
|
||||
\fIuser_pwd\fR
|
||||
A tuple describing the user's passwd entry.
|
||||
Convertible to pwd.struct_passwd or
|
||||
\fINone\fR
|
||||
Convertible to
|
||||
\fIpwd.struct_passwd or\fR
|
||||
\fRNone\fR
|
||||
if the user is not present in the password database.
|
||||
.sp
|
||||
Example conversion:
|
||||
@ -437,7 +440,7 @@ If this is omitted, no changes will be made to
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBlist\fR
|
||||
\fIlist\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
list(self, argv: Tuple[str, ...], is_verbose: int, user: str)
|
||||
@ -451,7 +454,7 @@ The function arguments are as follows:
|
||||
.TP 6n
|
||||
\fIargv\fR
|
||||
If not set to
|
||||
\fINone\fR,
|
||||
\fRNone\fR,
|
||||
an argument vector describing a command the user wishes to check
|
||||
against the policy.
|
||||
.TP 6n
|
||||
@ -461,14 +464,14 @@ Flag indicating whether to list in verbose mode or not.
|
||||
\fIuser\fR
|
||||
The name of a different user to list privileges for if the policy allows it.
|
||||
If
|
||||
\fINone\fR,
|
||||
\fRNone\fR,
|
||||
the plugin should list the privileges of the invoking user.
|
||||
.PD 0
|
||||
.PP
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBvalidate\fR
|
||||
\fIvalidate\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
validate(self)
|
||||
@ -479,7 +482,7 @@ validate(self)
|
||||
For policy plugins that cache authentication credentials, this function is used to validate and cache the credentials (optional).
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBinvalidate\fR
|
||||
\fIinvalidate\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
invalidate(self, remove: int)
|
||||
@ -499,7 +502,7 @@ invalidating them.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBshow_version\fR
|
||||
\fIshow_version\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
show_version(self, is_verbose: int)
|
||||
@ -524,7 +527,7 @@ is run as the root user.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBclose\fR
|
||||
\fIclose\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -537,7 +540,9 @@ Called when a command finishes executing.
|
||||
.sp
|
||||
Works the same as the
|
||||
\fBclose\fR()
|
||||
function in the C sudo plugin API, except that it only gets called if
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API, except that it only gets called if
|
||||
\fBsudo\fR
|
||||
attempts to execute the command.
|
||||
.sp
|
||||
@ -569,8 +574,10 @@ Plugin python_policy python_plugin.so \e
|
||||
.RE
|
||||
.fi
|
||||
.PP
|
||||
Be aware, however, that you cannot enable the Python policy plugin
|
||||
in addition to another policy plugin, such as
|
||||
Only one policy plugin can be enabled at a time so you must disable
|
||||
any other policy plugin listed in
|
||||
\fI@sysconfdir@/sudo.conf\fR,
|
||||
such as
|
||||
sudoers(@mansectform@).
|
||||
.SS "I/O plugin API"
|
||||
I/O plugins must be registered in
|
||||
@ -588,7 +595,7 @@ Currently only 8 python I/O plugins can be loaded at once.
|
||||
.PP
|
||||
An I/O plugin may have the following member functions:
|
||||
.TP 6n
|
||||
\fBconstructor\fR
|
||||
\fIconstructor\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
@ -604,7 +611,9 @@ as member variables in the object.
|
||||
.sp
|
||||
The constructor matches the
|
||||
\fBopen\fR()
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.TP 6n
|
||||
@ -648,7 +657,7 @@ documentation in
|
||||
sudo_plugin(@mansectform@).
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBopen\fR
|
||||
\fIopen\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
open(self, argv: Tuple[str, ...],
|
||||
@ -661,13 +670,15 @@ Receives the command the user wishes to run.
|
||||
.sp
|
||||
Works the same as the
|
||||
\fBopen\fR()
|
||||
function in the C sudo plugin API except that:
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API except that:
|
||||
.sp
|
||||
.RS 10n
|
||||
.PD 0
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
It only gets called before the user would execute some command
|
||||
It only gets called when there is a command to be executed
|
||||
(and not for a version query for example).
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
@ -708,7 +719,7 @@ If the function returns
|
||||
no I/O will be sent to the plugin.
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBlog_ttyin\fR, \fBlog_ttyout\fR, \fBlog_stdin\fR, \fBlog_stdout\fR, \fBlog_stderr\fR
|
||||
\fIlog_ttyin\fR, \fIlog_ttyout\fR, \fIlog_stdin\fR, \fIlog_stdout\fR, \fIlog_stderr\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
log_ttyin(self, buf: str) -> int
|
||||
@ -736,8 +747,8 @@ constants.
|
||||
.sp
|
||||
If
|
||||
\fRsudo.RC.ERROR\fR
|
||||
is returned, the running command will be terminated and all of the plugin's logging
|
||||
functions will be disabled.
|
||||
is returned, the running command will be terminated and all of the
|
||||
plugin's logging functions will be disabled.
|
||||
Other I/O logging plugins will still receive any remaining
|
||||
input or output that has not yet been processed.
|
||||
.sp
|
||||
@ -751,7 +762,7 @@ the command will be terminated and the data will not be written to the
|
||||
terminal, though it will still be sent to any other I/O logging plugins.
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBchange_winsize\fR
|
||||
\fIchange_winsize\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
change_winsize(self, line: int, cols: int) -> int
|
||||
@ -772,7 +783,7 @@ The number of columns of the terminal.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBlog_suspend\fR
|
||||
\fIlog_suspend\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
log_suspend(self, signo: int) -> int
|
||||
@ -793,7 +804,7 @@ if the command was resumed.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBshow_version\fR
|
||||
\fIshow_version\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
show_version(self, is_verbose: int)
|
||||
@ -817,7 +828,7 @@ is run as the root user.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBclose\fR
|
||||
\fIclose\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -825,11 +836,13 @@ close(self, exit_status: int, error: int) -> None
|
||||
.RE
|
||||
.fi
|
||||
.RS 6n
|
||||
Called when a command execution finished.
|
||||
Called when a command finishes execution.
|
||||
.sp
|
||||
Works the same as the
|
||||
\fBclose\fR()
|
||||
function in the C sudo plugin API, except that it only gets called if
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API, except that it only gets called if
|
||||
\fBsudo\fR
|
||||
attempts to execute the command.
|
||||
.sp
|
||||
@ -849,7 +862,7 @@ system call, otherwise 0.
|
||||
.RE
|
||||
.PD
|
||||
.SS "I/O plugin example"
|
||||
Sudo ships a Python I/O plugin example.
|
||||
Sudo ships with a Python I/O plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
\fI@sysconfdir@/sudo.conf\fR:
|
||||
.nf
|
||||
@ -874,9 +887,9 @@ Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class>
|
||||
Sudo supports loading multiple audit plugins.
|
||||
Currently only 8 python audit plugins can be loaded at once.
|
||||
.PP
|
||||
An audit plugin may have the following member functions (all of them are optional):
|
||||
An audit plugin may have the following member functions (all of which are optional):
|
||||
.TP 6n
|
||||
\fBconstructor\fR
|
||||
\fIconstructor\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
@ -890,7 +903,9 @@ as member variables in the object.
|
||||
.sp
|
||||
The constructor matches the
|
||||
\fBopen\fR()
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.TP 6n
|
||||
@ -926,7 +941,7 @@ format.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBopen\fR
|
||||
\fIopen\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
open(self, submit_optind: int,
|
||||
@ -949,7 +964,7 @@ The argument vector sudo was invoked with, including all command line options.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBclose\fR
|
||||
\fIclose\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -964,7 +979,9 @@ The function arguments are as follows:
|
||||
.TP 6n
|
||||
\fIstatus_type\fR
|
||||
The type of status being passed.
|
||||
One of the sudo.EXIT_REASON.* constants.
|
||||
One of the
|
||||
\fRsudo.EXIT_REASON.*\fR
|
||||
constants.
|
||||
.TP 6n
|
||||
\fIstatus\fR
|
||||
Depending on the value of
|
||||
@ -973,11 +990,11 @@ this value is either
|
||||
ignored, the command's exit status as returned by the
|
||||
wait(2)
|
||||
system call, the value of
|
||||
\fRerrno\fR
|
||||
\fIerrno\fR
|
||||
set by the
|
||||
execve(2)
|
||||
system call, or the value of
|
||||
\fRerrno\fR
|
||||
\fIerrno\fR
|
||||
resulting from an error in the
|
||||
\fBsudo\fR
|
||||
front-end.
|
||||
@ -986,7 +1003,7 @@ front-end.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBshow_version\fR
|
||||
\fIshow_version\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
show_version(self, is_verbose: int) -> int
|
||||
@ -1011,7 +1028,7 @@ is run as the root user.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBaccept\fR
|
||||
\fIaccept\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
accept(self, plugin_name: str, plugin_type: int, command_info: Tuple[str, ...],
|
||||
@ -1075,7 +1092,7 @@ The environment the command will be run with.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBreject\fR
|
||||
\fIreject\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
reject(self, plugin_name: str, plugin_type: int, audit_msg: str,
|
||||
@ -1109,7 +1126,7 @@ front-end.
|
||||
audit_msg
|
||||
An optional string describing the reason the command was rejected by the plugin.
|
||||
If the plugin did not provide a reason, audit_msg will be
|
||||
\fINone\fR
|
||||
\fRNone\fR.
|
||||
.TP 6n
|
||||
command_info
|
||||
A vector of information describing the rejected command.
|
||||
@ -1121,7 +1138,7 @@ manual for possible values.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBerror\fR
|
||||
\fIerror\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -1153,7 +1170,7 @@ front-end.
|
||||
audit_msg
|
||||
An optional string describing the plugin error.
|
||||
If the plugin did not provide a description, it will be
|
||||
\fINone\fR
|
||||
\fRNone\fR.
|
||||
.TP 6n
|
||||
command_info
|
||||
A vector of information describing the command.
|
||||
@ -1165,7 +1182,7 @@ manual for possible values.
|
||||
.RE
|
||||
.PD
|
||||
.SS "Audit plugin example"
|
||||
Sudo ships a Python Audit plugin example.
|
||||
Sudo ships with a Python Audit plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
\fI@sysconfdir@/sudo.conf\fR:
|
||||
.nf
|
||||
@ -1194,7 +1211,7 @@ Currently only 8 python approval plugins can be loaded at once.
|
||||
.PP
|
||||
An approval plugin may have the following member functions:
|
||||
.TP 6n
|
||||
\fBconstructor\fR
|
||||
\fIconstructor\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
@ -1210,7 +1227,9 @@ as member variables in the object.
|
||||
.sp
|
||||
The constructor matches the
|
||||
\fBopen\fR()
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API.
|
||||
.sp
|
||||
The function arguments are as follows:
|
||||
.TP 6n
|
||||
@ -1254,7 +1273,7 @@ The argument vector sudo was invoked with, including all command line options.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBshow_version\fR
|
||||
\fIshow_version\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
show_version(self, is_verbose: int) -> int
|
||||
@ -1262,10 +1281,11 @@ show_version(self, is_verbose: int) -> int
|
||||
.fi
|
||||
.RS 6n
|
||||
.sp
|
||||
Display the version. (Same as for all the other plugins.)
|
||||
Display the version.
|
||||
(Same as for all the other plugins.)
|
||||
.RE
|
||||
.TP 6n
|
||||
\fBcheck\fR
|
||||
\fIcheck\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -1306,7 +1326,7 @@ The environment the command will be run with.
|
||||
.RE
|
||||
.PD
|
||||
.SS "Approval plugin example"
|
||||
Sudo ships a Python Approval plugin example.
|
||||
Sudo ships with a Python Approval plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
\fI@sysconfdir@/sudo.conf\fR:
|
||||
.nf
|
||||
@ -1337,7 +1357,7 @@ Currently, only a single group plugin can be registered in
|
||||
.PP
|
||||
A group provider plugin may have the following member functions:
|
||||
.TP 6n
|
||||
\fBconstructor\fR
|
||||
\fIconstructor\fR
|
||||
.nf
|
||||
.RS 6n
|
||||
__init__(self, args: Tuple[str, ...], version: str)
|
||||
@ -1366,7 +1386,7 @@ The version of the Python Group Plugin API.
|
||||
.RE
|
||||
.PD
|
||||
.TP 6n
|
||||
\fBquery\fR
|
||||
\fIquery\fR
|
||||
.br
|
||||
.nf
|
||||
.RS 6n
|
||||
@ -1402,7 +1422,7 @@ is not present in the password database,
|
||||
will be
|
||||
\fRNULL\fR.
|
||||
.SS "Group plugin example"
|
||||
Sudo ships a Python group plugin example.
|
||||
Sudo ships with a Python group plugin example.
|
||||
To try it, register it in the
|
||||
\fIsudoers\fR
|
||||
file by adding the following lines:
|
||||
@ -1419,7 +1439,7 @@ The example plugin will tell
|
||||
\fBsudo\fR
|
||||
that the user
|
||||
\fItest\fR
|
||||
is part of the non-unix group
|
||||
is part of the non-Unix group
|
||||
\fImygroup\fR.
|
||||
If you add a rule that uses this group, it will affect the
|
||||
\fItest\fR
|
||||
@ -1444,16 +1464,18 @@ written in Python.
|
||||
A Python plugin can interact with the user using the
|
||||
\fBsudo.conv\fR()
|
||||
function which displays one or more messages described by the
|
||||
\fBsudo.ConvMessage\fR
|
||||
\fRsudo.ConvMessage\fR
|
||||
class.
|
||||
This is the Python equivalent of the
|
||||
\fBconversation\fR()
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
\fBsudo\fR
|
||||
plugin API.
|
||||
A plugin should not attempt to read directly from the standard input or
|
||||
the user's tty (neither of which are guaranteed to exist).
|
||||
.PP
|
||||
The
|
||||
\fBsudo.ConvMessage\fR
|
||||
\fRsudo.ConvMessage\fR
|
||||
class specifies how the user interaction should occur:
|
||||
.nf
|
||||
.sp
|
||||
@ -1462,7 +1484,7 @@ sudo.ConvMessage(msg_type: int, msg: str, timeout: int)
|
||||
.RE
|
||||
.fi
|
||||
.PP
|
||||
\fBsudo.ConvMessage\fR
|
||||
\fRsudo.ConvMessage\fR
|
||||
member variables:
|
||||
.TP 6n
|
||||
\fImsg_type\fR
|
||||
@ -1474,7 +1496,7 @@ constants below.
|
||||
\fImsg\fR
|
||||
The message to display to the user.
|
||||
The caller must include a trailing newline in
|
||||
\fRmsg\fR
|
||||
\fImsg\fR
|
||||
if one is to be displayed.
|
||||
.TP 6n
|
||||
\fItimeout\fR
|
||||
@ -1493,25 +1515,25 @@ To specify the message type, the following constants are available:
|
||||
.PD 0
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.PROMPT_ECHO_OFF
|
||||
\fRsudo.CONV.PROMPT_ECHO_OFF\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.PROMPT_ECHO_ON
|
||||
\fRsudo.CONV.PROMPT_ECHO_ON\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.ERROR_MSG
|
||||
\fRsudo.CONV.ERROR_MSG\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.INFO_MSG
|
||||
\fRsudo.CONV.INFO_MSG\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.PROMPT_MASK
|
||||
\fRsudo.CONV.PROMPT_MASK\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.PROMPT_ECHO_OK
|
||||
\fRsudo.CONV.PROMPT_ECHO_OK\fR
|
||||
.TP 3n
|
||||
\fB\(bu\fR
|
||||
sudo.CONV.PREFER_TTY
|
||||
\fRsudo.CONV.PREFER_TTY\fR
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
@ -1534,7 +1556,7 @@ The function arguments are as follows:
|
||||
.TP 6n
|
||||
\fImessage(s)\fR
|
||||
One of more messages (of type
|
||||
\fBsudo.ConvMessage\fR),
|
||||
\fRsudo.ConvMessage\fR),
|
||||
each describing a conversation.
|
||||
At least one message is required.
|
||||
.TP 6n
|
||||
@ -1554,11 +1576,11 @@ The
|
||||
\fBsudo.conv\fR()
|
||||
function can raise the following exceptions:
|
||||
.TP 6n
|
||||
\fBsudo.SudoException\fR
|
||||
\fRsudo.SudoException\fR
|
||||
If the conversation fails, for example when the conversation function is not
|
||||
available.
|
||||
.TP 6n
|
||||
\fBsudo.ConversationInterrupted\fR
|
||||
\fRsudo.ConversationInterrupted\fR
|
||||
If the conversation function returns an error, e.g., the timeout passed
|
||||
or the user interrupted the conversation by pressing control-C.
|
||||
.SS "Conversation example"
|
||||
@ -1618,7 +1640,7 @@ debug system.
|
||||
\fIEnabling debugging in sudo.conf\fR
|
||||
.PP
|
||||
To enable debug messages, add a
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
line to
|
||||
sudo.conf(@mansectform@)
|
||||
with the program set to
|
||||
@ -1710,21 +1732,21 @@ l l l.
|
||||
.PP
|
||||
\fBsudo.conf name\fR \fBPython constant\fR \fBdescription\fR
|
||||
.PP
|
||||
crit sudo.DEBUG.CRIT only critical messages
|
||||
crit \fRsudo.DEBUG.CRIT\fR only critical messages
|
||||
.PP
|
||||
err sudo.DEBUG.ERROR
|
||||
err \fRsudo.DEBUG.ERROR\fR
|
||||
.PP
|
||||
warn sudo.DEBUG.WARN
|
||||
warn \fRsudo.DEBUG.WARN\fR
|
||||
.PP
|
||||
notice sudo.DEBUG.NOTICE
|
||||
notice \fRsudo.DEBUG.NOTICE\fR
|
||||
.PP
|
||||
diag sudo.DEBUG.DIAG
|
||||
diag \fRsudo.DEBUG.DIAG\fR
|
||||
.PP
|
||||
info sudo.DEBUG.INFO
|
||||
info \fRsudo.DEBUG.INFO\fR
|
||||
.PP
|
||||
trace sudo.DEBUG.TRACE
|
||||
trace \fRsudo.DEBUG.TRACE\fR
|
||||
.PP
|
||||
debug sudo.DEBUG.DEBUG very extreme verbose debugging
|
||||
debug \fRsudo.DEBUG.DEBUG\fR very extreme verbose debugging
|
||||
.TE
|
||||
.PP
|
||||
\fIUsing the logging module\fR
|
||||
@ -1737,11 +1759,11 @@ The log handler of sudo will map each Python log level of a message to
|
||||
the appropriate sudo debug level.
|
||||
The sudo debug system will only receive messages that are not filtered
|
||||
out by the Python loggers.
|
||||
For example, the log level of the python logger will be an additional filter
|
||||
for the log messages, and is usually very different from what level is set in sudo.conf
|
||||
for the sudo debug system.
|
||||
For example, the log level of the python logger will be an additional
|
||||
filter for the log messages, and is usually very different from
|
||||
what level is set in sudo.conf for the sudo debug system.
|
||||
.SS "Debug example"
|
||||
Sudo ships an example debug plugin by default.
|
||||
Sudo ships with an example debug plugin.
|
||||
To try it, register it by adding the following lines to
|
||||
\fI@sysconfdir@/sudo.conf\fR:
|
||||
.nf
|
||||
@ -1816,12 +1838,13 @@ This is how the plugin API accepts options and settings.
|
||||
.SH "PLUGIN API CHANGELOG (Python)"
|
||||
None yet
|
||||
.SH "LIMITATIONS"
|
||||
Only a maximum number of 8 python I/O plugins can be loaded at once.
|
||||
A maximum of 8 python I/O plugins can be loaded at once.
|
||||
If
|
||||
\fI@sysconfdir@/sudo.conf\fR
|
||||
contains more, those will be rejected with a warning message.
|
||||
.PP
|
||||
The Event API and the hook function API is currently not accessible for Python plugins.
|
||||
The Event API and the hook function API is currently not accessible
|
||||
for Python plugins.
|
||||
.SH "SEE ALSO"
|
||||
sudo.conf(@mansectform@),
|
||||
sudo_plugin(@mansectform@),
|
||||
@ -1849,7 +1872,7 @@ If you believe you have found a bug in
|
||||
you can submit a bug report at https://bugzilla.sudo.ws/
|
||||
.SH "SECURITY CONSIDERATIONS"
|
||||
All Python plugin handling is implemented inside the
|
||||
\fRpython_plugin.so\fR
|
||||
\fIpython_plugin.so\fR
|
||||
dynamic plugin.
|
||||
Therefore, if no Python plugin is registered in
|
||||
sudo.conf(@mansectform@)
|
||||
@ -1875,7 +1898,7 @@ accidentally importing such file would make it possible for any user
|
||||
However, during development of a plugin this might not be very convenient.
|
||||
The
|
||||
sudo.conf(@mansectform@)
|
||||
\fRdeveloper_mode\fR
|
||||
\fIdeveloper_mode\fR
|
||||
option can be used to disable it.
|
||||
For example:
|
||||
.RS 6n
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd June 6, 2022
|
||||
.Dd September 11, 2022
|
||||
.Dt SUDO_PLUGIN_PYTHON @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -85,9 +85,9 @@ When the plugin loads,
|
||||
will create an instance of this class and call the methods.
|
||||
The actual methods required depent on the type of the plugin,
|
||||
but most return an
|
||||
.Dq int
|
||||
.Vt int
|
||||
result code, as documented in
|
||||
.Xr sudo_plugin @mansectsu@ ,
|
||||
.Xr sudo_plugin @mansectform@ ,
|
||||
that indicates whether or not the method was successful.
|
||||
The Python sudo module defines the following constants to improve readability:
|
||||
.Bl -column "sudo.RC.USAGE_ERROR" "XXX" -offset 4n
|
||||
@ -100,12 +100,12 @@ The Python sudo module defines the following constants to improve readability:
|
||||
.El
|
||||
.Pp
|
||||
If a function returns
|
||||
.Em None
|
||||
.Dv None
|
||||
(for example, if it does not call return),
|
||||
it will be considered to have returned
|
||||
.Dv sudo.RC.OK .
|
||||
If an exception is raised (other than sudo.PluginException), the backtrace will be
|
||||
shown to the user and the plugin function will return
|
||||
If an exception is raised (other than sudo.PluginException), the
|
||||
backtrace will be shown to the user and the plugin function will return
|
||||
.Dv sudo.RC.ERROR .
|
||||
If that is not acceptable, you must catch the exception and handle it yourself.
|
||||
.Pp
|
||||
@ -128,7 +128,7 @@ Running the Python interpreter and bridging between C and Python is
|
||||
handled by the
|
||||
.Nm sudo
|
||||
plugin
|
||||
.Li python_plugin.so .
|
||||
.Pa python_plugin.so .
|
||||
This shared object can be loaded like any other dynamic
|
||||
.Nm sudo
|
||||
plugin and should receive the path and the class name of the Python
|
||||
@ -187,8 +187,8 @@ Currently, only a single policy plugin may be specified in
|
||||
.Pp
|
||||
A policy plugin may have the following member functions:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy constructor
|
||||
.Bd -literal
|
||||
.It Fa constructor
|
||||
.Bd -literal -compact
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
version: str, user_info: Tuple[str, ...],
|
||||
plugin_options: Tuple[str, ...])
|
||||
@ -200,7 +200,9 @@ as member variables in the object.
|
||||
.Pp
|
||||
The constructor matches the
|
||||
.Fn open
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API.
|
||||
.Pp
|
||||
The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
@ -239,7 +241,7 @@ see the policy plugin
|
||||
.Fn open
|
||||
documentation in
|
||||
.Xr sudo_plugin @mansectform@ .
|
||||
.It Sy check_policy
|
||||
.It Fa check_policy
|
||||
.Bd -literal -compact
|
||||
check_policy(self, argv: Tuple[str, ...], env_add: Tuple[str, ...])
|
||||
.Ed
|
||||
@ -314,7 +316,7 @@ tuple of strings in
|
||||
.Dq key=value
|
||||
format.
|
||||
.El
|
||||
.It Sy init_session
|
||||
.It Fa init_session
|
||||
.Bd -literal -compact
|
||||
init_session(self, user_pwd: Tuple, user_env: Tuple[str, ...])
|
||||
.Ed
|
||||
@ -331,8 +333,9 @@ The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It Fa user_pwd
|
||||
A tuple describing the user's passwd entry.
|
||||
Convertible to pwd.struct_passwd or
|
||||
.Em None
|
||||
Convertible to
|
||||
.Vt pwd.struct_passwd or
|
||||
.Dv None
|
||||
if the user is not present in the password database.
|
||||
.Pp
|
||||
Example conversion:
|
||||
@ -371,7 +374,7 @@ environment in
|
||||
If this is omitted, no changes will be made to
|
||||
.Fa user_env .
|
||||
.El
|
||||
.It Sy list
|
||||
.It Fa list
|
||||
.Bd -literal -compact
|
||||
list(self, argv: Tuple[str, ...], is_verbose: int, user: str)
|
||||
.Ed
|
||||
@ -382,7 +385,7 @@ The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It Fa argv
|
||||
If not set to
|
||||
.Em None ,
|
||||
.Dv None ,
|
||||
an argument vector describing a command the user wishes to check
|
||||
against the policy.
|
||||
.It Fa is_verbose
|
||||
@ -390,16 +393,16 @@ Flag indicating whether to list in verbose mode or not.
|
||||
.It Fa user
|
||||
The name of a different user to list privileges for if the policy allows it.
|
||||
If
|
||||
.Em None ,
|
||||
.Dv None ,
|
||||
the plugin should list the privileges of the invoking user.
|
||||
.El
|
||||
.It Sy validate
|
||||
.It Fa validate
|
||||
.Bd -literal -compact
|
||||
validate(self)
|
||||
.Ed
|
||||
.Pp
|
||||
For policy plugins that cache authentication credentials, this function is used to validate and cache the credentials (optional).
|
||||
.It Sy invalidate
|
||||
.It Fa invalidate
|
||||
.Bd -literal -compact
|
||||
invalidate(self, remove: int)
|
||||
.Ed
|
||||
@ -412,7 +415,7 @@ The function arguments are as follows:
|
||||
If this flag is set, the plugin may remove the credentials instead of simply
|
||||
invalidating them.
|
||||
.El
|
||||
.It Sy show_version
|
||||
.It Fa show_version
|
||||
.Bd -literal -compact
|
||||
show_version(self, is_verbose: int)
|
||||
.Ed
|
||||
@ -430,7 +433,7 @@ Currently this is 1 if
|
||||
.Ql sudo -V
|
||||
is run as the root user.
|
||||
.El
|
||||
.It Sy close
|
||||
.It Fa close
|
||||
.Bd -literal -compact
|
||||
close(self, exit_status: int, error: int)
|
||||
.Ed
|
||||
@ -439,7 +442,9 @@ Called when a command finishes executing.
|
||||
.Pp
|
||||
Works the same as the
|
||||
.Fn close
|
||||
function in the C sudo plugin API, except that it only gets called if
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API, except that it only gets called if
|
||||
.Nm sudo
|
||||
attempts to execute the command.
|
||||
.Pp
|
||||
@ -464,8 +469,10 @@ Plugin python_policy python_plugin.so \e
|
||||
ClassName=SudoPolicyPlugin
|
||||
.Ed
|
||||
.Pp
|
||||
Be aware, however, that you cannot enable the Python policy plugin
|
||||
in addition to another policy plugin, such as
|
||||
Only one policy plugin can be enabled at a time so you must disable
|
||||
any other policy plugin listed in
|
||||
.Pa @sysconfdir@/sudo.conf ,
|
||||
such as
|
||||
.Xr sudoers @mansectform@ .
|
||||
.Ss I/O plugin API
|
||||
I/O plugins must be registered in
|
||||
@ -480,7 +487,7 @@ Currently only 8 python I/O plugins can be loaded at once.
|
||||
.Pp
|
||||
An I/O plugin may have the following member functions:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy constructor
|
||||
.It Fa constructor
|
||||
.Bd -literal -compact
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
version: str, user_info: Tuple[str, ...],
|
||||
@ -493,7 +500,9 @@ as member variables in the object.
|
||||
.Pp
|
||||
The constructor matches the
|
||||
.Fn open
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API.
|
||||
.Pp
|
||||
The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
@ -532,7 +541,7 @@ see the I/O plugin
|
||||
.Fn open
|
||||
documentation in
|
||||
.Xr sudo_plugin @mansectform@ .
|
||||
.It Sy open
|
||||
.It Fa open
|
||||
.Bd -literal -compact
|
||||
open(self, argv: Tuple[str, ...],
|
||||
command_info: Tuple[str, ...]) -> int
|
||||
@ -542,11 +551,13 @@ Receives the command the user wishes to run.
|
||||
.Pp
|
||||
Works the same as the
|
||||
.Fn open
|
||||
function in the C sudo plugin API except that:
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API except that:
|
||||
.Pp
|
||||
.Bl -bullet -compact -offset 4n -width 1n
|
||||
.It
|
||||
It only gets called before the user would execute some command
|
||||
It only gets called when there is a command to be executed
|
||||
(and not for a version query for example).
|
||||
.It
|
||||
Other arguments of the C API
|
||||
@ -583,7 +594,7 @@ constants.
|
||||
If the function returns
|
||||
.Dv sudo.RC.REJECT ,
|
||||
no I/O will be sent to the plugin.
|
||||
.It Sy log_ttyin , log_ttyout , log_stdin , log_stdout , log_stderr
|
||||
.It Fa log_ttyin , log_ttyout , log_stdin , log_stdout , log_stderr
|
||||
.Bd -literal -compact
|
||||
log_ttyin(self, buf: str) -> int
|
||||
log_ttyout(self, buf: str) -> int
|
||||
@ -609,8 +620,8 @@ constants.
|
||||
.Pp
|
||||
If
|
||||
.Dv sudo.RC.ERROR
|
||||
is returned, the running command will be terminated and all of the plugin's logging
|
||||
functions will be disabled.
|
||||
is returned, the running command will be terminated and all of the
|
||||
plugin's logging functions will be disabled.
|
||||
Other I/O logging plugins will still receive any remaining
|
||||
input or output that has not yet been processed.
|
||||
.Pp
|
||||
@ -622,7 +633,7 @@ If an output logging function rejects the data by returning
|
||||
.Dv sudo.RC.REJECT ,
|
||||
the command will be terminated and the data will not be written to the
|
||||
terminal, though it will still be sent to any other I/O logging plugins.
|
||||
.It Sy change_winsize
|
||||
.It Fa change_winsize
|
||||
.Bd -literal -compact
|
||||
change_winsize(self, line: int, cols: int) -> int
|
||||
.Ed
|
||||
@ -635,7 +646,7 @@ The number of lines of the terminal.
|
||||
.It Fa cols
|
||||
The number of columns of the terminal.
|
||||
.El
|
||||
.It Sy log_suspend
|
||||
.It Fa log_suspend
|
||||
.Bd -literal -compact
|
||||
log_suspend(self, signo: int) -> int
|
||||
.Ed
|
||||
@ -648,7 +659,7 @@ The number of the signal that caused the command to be suspended or
|
||||
.Dv SIGCONT
|
||||
if the command was resumed.
|
||||
.El
|
||||
.It Sy show_version
|
||||
.It Fa show_version
|
||||
.Bd -literal -compact
|
||||
show_version(self, is_verbose: int)
|
||||
.Ed
|
||||
@ -665,15 +676,17 @@ Currently this is 1 if
|
||||
.Ql sudo -V
|
||||
is run as the root user.
|
||||
.El
|
||||
.It Sy close
|
||||
.It Fa close
|
||||
.Bd -literal -compact
|
||||
close(self, exit_status: int, error: int) -> None
|
||||
.Ed
|
||||
Called when a command execution finished.
|
||||
Called when a command finishes execution.
|
||||
.Pp
|
||||
Works the same as the
|
||||
.Fn close
|
||||
function in the C sudo plugin API, except that it only gets called if
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API, except that it only gets called if
|
||||
.Nm sudo
|
||||
attempts to execute the command.
|
||||
.Pp
|
||||
@ -689,7 +702,7 @@ system call, otherwise 0.
|
||||
.El
|
||||
.El
|
||||
.Ss I/O plugin example
|
||||
Sudo ships a Python I/O plugin example.
|
||||
Sudo ships with a Python I/O plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
.Pa @sysconfdir@/sudo.conf :
|
||||
.Bd -literal -offset 4n
|
||||
@ -708,9 +721,9 @@ Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class>
|
||||
Sudo supports loading multiple audit plugins.
|
||||
Currently only 8 python audit plugins can be loaded at once.
|
||||
.Pp
|
||||
An audit plugin may have the following member functions (all of them are optional):
|
||||
An audit plugin may have the following member functions (all of which are optional):
|
||||
.Bl -tag -width 4n
|
||||
.It Sy constructor
|
||||
.It Fa constructor
|
||||
.Bd -literal -compact
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...])
|
||||
@ -721,7 +734,9 @@ as member variables in the object.
|
||||
.Pp
|
||||
The constructor matches the
|
||||
.Fn open
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API.
|
||||
.Pp
|
||||
The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
@ -749,7 +764,7 @@ This is a tuple of strings, usually (but not necessarily) in
|
||||
.Dq key=value
|
||||
format.
|
||||
.El
|
||||
.It Sy open
|
||||
.It Fa open
|
||||
.Bd -literal -compact
|
||||
open(self, submit_optind: int,
|
||||
submit_argv: Tuple[str, ...]) -> int
|
||||
@ -764,7 +779,7 @@ that corresponds to the first entry that is not a command line option.
|
||||
.It Fa submit_argv
|
||||
The argument vector sudo was invoked with, including all command line options.
|
||||
.El
|
||||
.It Sy close
|
||||
.It Fa close
|
||||
.Bd -literal -compact
|
||||
close(self, status_type: int, status: int) -> None
|
||||
.Ed
|
||||
@ -775,7 +790,9 @@ The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It Fa status_type
|
||||
The type of status being passed.
|
||||
One of the sudo.EXIT_REASON.* constants.
|
||||
One of the
|
||||
.Dv sudo.EXIT_REASON.*
|
||||
constants.
|
||||
.It Fa status
|
||||
Depending on the value of
|
||||
.Fa status_type ,
|
||||
@ -783,16 +800,16 @@ this value is either
|
||||
ignored, the command's exit status as returned by the
|
||||
.Xr wait 2
|
||||
system call, the value of
|
||||
.Li errno
|
||||
.Va errno
|
||||
set by the
|
||||
.Xr execve 2
|
||||
system call, or the value of
|
||||
.Li errno
|
||||
.Va errno
|
||||
resulting from an error in the
|
||||
.Nm sudo
|
||||
front-end.
|
||||
.El
|
||||
.It Sy show_version
|
||||
.It Fa show_version
|
||||
.Bd -literal -compact
|
||||
show_version(self, is_verbose: int) -> int
|
||||
.Ed
|
||||
@ -810,7 +827,7 @@ Currently this is 1 if
|
||||
.Ql sudo -V
|
||||
is run as the root user.
|
||||
.El
|
||||
.It Sy accept
|
||||
.It Fa accept
|
||||
.Bd -literal -compact
|
||||
accept(self, plugin_name: str, plugin_type: int, command_info: Tuple[str, ...],
|
||||
run_argv: Tuple[str, ...], run_envp: Tuple[str, ...]) -> int
|
||||
@ -863,7 +880,7 @@ Argument vector describing a command that will be run.
|
||||
.It run_envp
|
||||
The environment the command will be run with.
|
||||
.El
|
||||
.It Sy reject
|
||||
.It Fa reject
|
||||
.Bd -literal -compact
|
||||
reject(self, plugin_name: str, plugin_type: int, audit_msg: str,
|
||||
command_info: Tuple[str, ...]) -> int
|
||||
@ -892,15 +909,14 @@ front-end.
|
||||
.It audit_msg
|
||||
An optional string describing the reason the command was rejected by the plugin.
|
||||
If the plugin did not provide a reason, audit_msg will be
|
||||
.Em None
|
||||
.
|
||||
.Dv None .
|
||||
.It command_info
|
||||
A vector of information describing the rejected command.
|
||||
See the
|
||||
.Xr sudo_plugin @mansectform@
|
||||
manual for possible values.
|
||||
.El
|
||||
.It Sy error
|
||||
.It Fa error
|
||||
.Bd -literal -compact
|
||||
error(self, plugin_name: str, plugin_type: int, audit_msg: str,
|
||||
command_info: Tuple[str, ...]) -> int
|
||||
@ -926,8 +942,7 @@ front-end.
|
||||
.It audit_msg
|
||||
An optional string describing the plugin error.
|
||||
If the plugin did not provide a description, it will be
|
||||
.Em None
|
||||
.
|
||||
.Dv None .
|
||||
.It command_info
|
||||
A vector of information describing the command.
|
||||
See the
|
||||
@ -936,7 +951,7 @@ manual for possible values.
|
||||
.El
|
||||
.El
|
||||
.Ss Audit plugin example
|
||||
Sudo ships a Python Audit plugin example.
|
||||
Sudo ships with a Python Audit plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
.Pa @sysconfdir@/sudo.conf :
|
||||
.Bd -literal -offset 4n
|
||||
@ -959,7 +974,7 @@ Currently only 8 python approval plugins can be loaded at once.
|
||||
.Pp
|
||||
An approval plugin may have the following member functions:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy constructor
|
||||
.It Fa constructor
|
||||
.Bd -literal -compact
|
||||
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
|
||||
version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...],
|
||||
@ -972,7 +987,9 @@ as member variables in the object.
|
||||
.Pp
|
||||
The constructor matches the
|
||||
.Fn open
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API.
|
||||
.Pp
|
||||
The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
@ -1006,13 +1023,14 @@ that corresponds to the first entry that is not a command line option.
|
||||
.It Fa submit_argv
|
||||
The argument vector sudo was invoked with, including all command line options.
|
||||
.El
|
||||
.It Sy show_version
|
||||
.It Fa show_version
|
||||
.Bd -literal -compact
|
||||
show_version(self, is_verbose: int) -> int
|
||||
.Ed
|
||||
.Pp
|
||||
Display the version. (Same as for all the other plugins.)
|
||||
.It Sy check
|
||||
Display the version.
|
||||
(Same as for all the other plugins.)
|
||||
.It Fa check
|
||||
.Bd -literal -compact
|
||||
check(self, command_info: Tuple[str, ...], run_argv: Tuple[str, ...],
|
||||
run_env: Tuple[str, ...]) -> int
|
||||
@ -1042,7 +1060,7 @@ The environment the command will be run with.
|
||||
.El
|
||||
.El
|
||||
.Ss Approval plugin example
|
||||
Sudo ships a Python Approval plugin example.
|
||||
Sudo ships with a Python Approval plugin example.
|
||||
To try it, register it by adding the following lines to
|
||||
.Pa @sysconfdir@/sudo.conf :
|
||||
.Bd -literal -offset 4n
|
||||
@ -1067,7 +1085,7 @@ Currently, only a single group plugin can be registered in
|
||||
.Pp
|
||||
A group provider plugin may have the following member functions:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy constructor
|
||||
.It Fa constructor
|
||||
.Bd -literal -compact
|
||||
__init__(self, args: Tuple[str, ...], version: str)
|
||||
.Ed
|
||||
@ -1088,7 +1106,7 @@ format).
|
||||
.It Fa version
|
||||
The version of the Python Group Plugin API.
|
||||
.El
|
||||
.It Sy query
|
||||
.It Fa query
|
||||
.Bd -literal -compact
|
||||
query(self, user: str, group: str, user_pwd: Tuple)
|
||||
.Ed
|
||||
@ -1118,7 +1136,7 @@ will be
|
||||
.Dv NULL .
|
||||
.El
|
||||
.Ss Group plugin example
|
||||
Sudo ships a Python group plugin example.
|
||||
Sudo ships with a Python group plugin example.
|
||||
To try it, register it in the
|
||||
.Em sudoers
|
||||
file by adding the following lines:
|
||||
@ -1132,7 +1150,7 @@ The example plugin will tell
|
||||
.Nm sudo
|
||||
that the user
|
||||
.Em test
|
||||
is part of the non-unix group
|
||||
is part of the non-Unix group
|
||||
.Em mygroup .
|
||||
If you add a rule that uses this group, it will affect the
|
||||
.Em test
|
||||
@ -1154,22 +1172,24 @@ written in Python.
|
||||
A Python plugin can interact with the user using the
|
||||
.Fn sudo.conv
|
||||
function which displays one or more messages described by the
|
||||
.Sy sudo.ConvMessage
|
||||
.Dv sudo.ConvMessage
|
||||
class.
|
||||
This is the Python equivalent of the
|
||||
.Fn conversation
|
||||
function in the C sudo plugin API.
|
||||
function in the C
|
||||
.Nm sudo
|
||||
plugin API.
|
||||
A plugin should not attempt to read directly from the standard input or
|
||||
the user's tty (neither of which are guaranteed to exist).
|
||||
.Pp
|
||||
The
|
||||
.Sy sudo.ConvMessage
|
||||
.Dv sudo.ConvMessage
|
||||
class specifies how the user interaction should occur:
|
||||
.Bd -literal -offset 4n
|
||||
sudo.ConvMessage(msg_type: int, msg: str, timeout: int)
|
||||
.Ed
|
||||
.Pp
|
||||
.Sy sudo.ConvMessage
|
||||
.Dv sudo.ConvMessage
|
||||
member variables:
|
||||
.Bl -tag -width 4n
|
||||
.It Fa msg_type
|
||||
@ -1180,7 +1200,7 @@ constants below.
|
||||
.It Fa msg
|
||||
The message to display to the user.
|
||||
The caller must include a trailing newline in
|
||||
.Li msg
|
||||
.Fa msg
|
||||
if one is to be displayed.
|
||||
.It Fa timeout
|
||||
Optional.
|
||||
@ -1197,19 +1217,19 @@ To specify the message type, the following constants are available:
|
||||
.Pp
|
||||
.Bl -bullet -compact -offset 4n -width 1n
|
||||
.It
|
||||
sudo.CONV.PROMPT_ECHO_OFF
|
||||
.Dv sudo.CONV.PROMPT_ECHO_OFF
|
||||
.It
|
||||
sudo.CONV.PROMPT_ECHO_ON
|
||||
.Dv sudo.CONV.PROMPT_ECHO_ON
|
||||
.It
|
||||
sudo.CONV.ERROR_MSG
|
||||
.Dv sudo.CONV.ERROR_MSG
|
||||
.It
|
||||
sudo.CONV.INFO_MSG
|
||||
.Dv sudo.CONV.INFO_MSG
|
||||
.It
|
||||
sudo.CONV.PROMPT_MASK
|
||||
.Dv sudo.CONV.PROMPT_MASK
|
||||
.It
|
||||
sudo.CONV.PROMPT_ECHO_OK
|
||||
.Dv sudo.CONV.PROMPT_ECHO_OK
|
||||
.It
|
||||
sudo.CONV.PREFER_TTY
|
||||
.Dv sudo.CONV.PREFER_TTY
|
||||
.El
|
||||
.Pp
|
||||
See the
|
||||
@ -1228,7 +1248,7 @@ The function arguments are as follows:
|
||||
.Bl -tag -width 4n
|
||||
.It Fa message(s)
|
||||
One of more messages (of type
|
||||
.Sy sudo.ConvMessage ) ,
|
||||
.Dv sudo.ConvMessage ) ,
|
||||
each describing a conversation.
|
||||
At least one message is required.
|
||||
.It Fa on_suspend
|
||||
@ -1247,10 +1267,10 @@ The
|
||||
.Fn sudo.conv
|
||||
function can raise the following exceptions:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy sudo.SudoException
|
||||
.It Dv sudo.SudoException
|
||||
If the conversation fails, for example when the conversation function is not
|
||||
available.
|
||||
.It Sy sudo.ConversationInterrupted
|
||||
.It Dv sudo.ConversationInterrupted
|
||||
If the conversation function returns an error, e.g., the timeout passed
|
||||
or the user interrupted the conversation by pressing control-C.
|
||||
.El
|
||||
@ -1305,7 +1325,7 @@ debug system.
|
||||
.Em Enabling debugging in sudo.conf
|
||||
.Pp
|
||||
To enable debug messages, add a
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
line to
|
||||
.Xr sudo.conf @mansectform@
|
||||
with the program set to
|
||||
@ -1380,14 +1400,14 @@ one or more messages to log
|
||||
.Em Available log levels:
|
||||
.Bl -column "name in sudo.conf" "Python constant" "only critical messages"
|
||||
.It Sy sudo.conf name Ta Sy Python constant Ta Sy description
|
||||
.It crit Ta sudo.DEBUG.CRIT Ta only critical messages
|
||||
.It err Ta sudo.DEBUG.ERROR Ta
|
||||
.It warn Ta sudo.DEBUG.WARN Ta
|
||||
.It notice Ta sudo.DEBUG.NOTICE Ta
|
||||
.It diag Ta sudo.DEBUG.DIAG Ta
|
||||
.It info Ta sudo.DEBUG.INFO Ta
|
||||
.It trace Ta sudo.DEBUG.TRACE Ta
|
||||
.It debug Ta sudo.DEBUG.DEBUG Ta very extreme verbose debugging
|
||||
.It crit Ta Dv sudo.DEBUG.CRIT Ta only critical messages
|
||||
.It err Ta Dv sudo.DEBUG.ERROR Ta
|
||||
.It warn Ta Dv sudo.DEBUG.WARN Ta
|
||||
.It notice Ta Dv sudo.DEBUG.NOTICE Ta
|
||||
.It diag Ta Dv sudo.DEBUG.DIAG Ta
|
||||
.It info Ta Dv sudo.DEBUG.INFO Ta
|
||||
.It trace Ta Dv sudo.DEBUG.TRACE Ta
|
||||
.It debug Ta Dv sudo.DEBUG.DEBUG Ta very extreme verbose debugging
|
||||
.El
|
||||
.Pp
|
||||
.Em Using the logging module
|
||||
@ -1400,11 +1420,11 @@ The log handler of sudo will map each Python log level of a message to
|
||||
the appropriate sudo debug level.
|
||||
The sudo debug system will only receive messages that are not filtered
|
||||
out by the Python loggers.
|
||||
For example, the log level of the python logger will be an additional filter
|
||||
for the log messages, and is usually very different from what level is set in sudo.conf
|
||||
for the sudo debug system.
|
||||
For example, the log level of the python logger will be an additional
|
||||
filter for the log messages, and is usually very different from
|
||||
what level is set in sudo.conf for the sudo debug system.
|
||||
.Ss Debug example
|
||||
Sudo ships an example debug plugin by default.
|
||||
Sudo ships with an example debug plugin.
|
||||
To try it, register it by adding the following lines to
|
||||
.Pa @sysconfdir@/sudo.conf :
|
||||
.Bd -literal -offset 4n
|
||||
@ -1470,12 +1490,13 @@ This is how the plugin API accepts options and settings.
|
||||
.Sh PLUGIN API CHANGELOG (Python)
|
||||
None yet
|
||||
.Sh LIMITATIONS
|
||||
Only a maximum number of 8 python I/O plugins can be loaded at once.
|
||||
A maximum of 8 python I/O plugins can be loaded at once.
|
||||
If
|
||||
.Pa @sysconfdir@/sudo.conf
|
||||
contains more, those will be rejected with a warning message.
|
||||
.Pp
|
||||
The Event API and the hook function API is currently not accessible for Python plugins.
|
||||
The Event API and the hook function API is currently not accessible
|
||||
for Python plugins.
|
||||
.Sh SEE ALSO
|
||||
.Xr sudo.conf @mansectform@ ,
|
||||
.Xr sudo_plugin @mansectform@ ,
|
||||
@ -1502,7 +1523,7 @@ If you believe you have found a bug in
|
||||
you can submit a bug report at https://bugzilla.sudo.ws/
|
||||
.Sh SECURITY CONSIDERATIONS
|
||||
All Python plugin handling is implemented inside the
|
||||
.Li python_plugin.so
|
||||
.Pa python_plugin.so
|
||||
dynamic plugin.
|
||||
Therefore, if no Python plugin is registered in
|
||||
.Xr sudo.conf @mansectform@
|
||||
@ -1528,7 +1549,7 @@ accidentally importing such file would make it possible for any user
|
||||
However, during development of a plugin this might not be very convenient.
|
||||
The
|
||||
.Xr sudo.conf @mansectform@
|
||||
.Li developer_mode
|
||||
.Em developer_mode
|
||||
option can be used to disable it.
|
||||
For example:
|
||||
.Dl Set developer_mode true
|
||||
|
@ -154,7 +154,7 @@ version and exit.
|
||||
.SS "Debugging sendlog"
|
||||
\fBsudo_sendlog\fR
|
||||
supports a flexible debugging framework that is configured via
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
lines in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
|
@ -139,7 +139,7 @@ version and exit.
|
||||
.Ss Debugging sendlog
|
||||
.Nm
|
||||
supports a flexible debugging framework that is configured via
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
lines in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDOERS.LDAP" "@mansectform@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDOERS.LDAP" "@mansectform@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -69,16 +69,16 @@ is no need for a specialized tool to check syntax.
|
||||
The
|
||||
\fIsudoers\fR
|
||||
configuration is contained in the
|
||||
\fRou=SUDOers\fR
|
||||
\(oqou=SUDOers\(cq
|
||||
LDAP container.
|
||||
.PP
|
||||
Sudo first looks for the
|
||||
\fRcn=defaults\fR
|
||||
\(oqcn=defaults\(cq
|
||||
entry in the SUDOers container.
|
||||
If found, the multi-valued
|
||||
\fRsudoOption\fR
|
||||
\fIsudoOption\fR
|
||||
attribute is parsed in the same manner as a global
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
line in
|
||||
\fI@sysconfdir@/sudoers\fR.
|
||||
In the following example, the
|
||||
@ -97,7 +97,7 @@ sudoOption: env_keep+=SSH_AUTH_SOCK
|
||||
.fi
|
||||
.PP
|
||||
The equivalent of a sudoer in LDAP is a
|
||||
\fRsudoRole\fR.
|
||||
\fIsudoRole\fR.
|
||||
It consists of the following attributes:
|
||||
.TP 6n
|
||||
\fBsudoUser\fR
|
||||
@ -120,36 +120,36 @@ Non-Unix group support is only available when an appropriate
|
||||
\fIgroup_plugin\fR
|
||||
is defined in the global
|
||||
\fIdefaults\fR
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
object.
|
||||
If a
|
||||
\fRsudoUser\fR
|
||||
\fIsudoUser\fR
|
||||
entry is preceded by an exclamation point,
|
||||
\(oq\&!\(cq,
|
||||
and the entry matches, the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
in which it resides will be ignored.
|
||||
Negated
|
||||
\fRsudoUser\fR
|
||||
\fIsudoUser\fR
|
||||
entries are only supported by version 1.9.9 or higher.
|
||||
.TP 6n
|
||||
\fBsudoHost\fR
|
||||
A host name, IP address, IP network, or host netgroup (prefixed with a
|
||||
\(oq+\(cq).
|
||||
The special value
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
will match any host.
|
||||
Host netgroups are matched using the host (both qualified and unqualified)
|
||||
and domain members only; the user member is not used when matching.
|
||||
If a
|
||||
\fRsudoHost\fR
|
||||
\fIsudoHost\fR
|
||||
entry is preceded by an exclamation point,
|
||||
\(oq\&!\(cq,
|
||||
and the entry matches, the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
in which it resides will be ignored.
|
||||
Negated
|
||||
\fRsudoHost\fR
|
||||
\fIsudoHost\fR
|
||||
entries are only supported by version 1.8.18 or higher.
|
||||
.TP 6n
|
||||
\fBsudoCommand\fR
|
||||
@ -160,7 +160,7 @@ If a command name is preceded by an exclamation point,
|
||||
the user will be prohibited from running that command.
|
||||
.sp
|
||||
The built-in command
|
||||
\(lq\fRsudoedit\fR\(rq
|
||||
\(lqsudoedit\(rq
|
||||
is used to permit a user to run
|
||||
\fBsudo\fR
|
||||
with the
|
||||
@ -169,13 +169,13 @@ option (or as
|
||||
\fBsudoedit\fR).
|
||||
It may take command line arguments just as a normal command does.
|
||||
Unlike other commands,
|
||||
\(lq\fRsudoedit\fR\(rq
|
||||
\(lqsudoedit\(rq
|
||||
is a built into
|
||||
\fBsudo\fR
|
||||
itself and must be specified in without a leading path.
|
||||
.sp
|
||||
The special value
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
will match any command.
|
||||
.sp
|
||||
If a command name is prefixed with a SHA-2 digest, it will
|
||||
@ -205,7 +205,7 @@ Command digests are only supported by version 1.8.7 or higher.
|
||||
\fBsudoOption\fR
|
||||
Identical in function to the global options described above, but
|
||||
specific to the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
in which it resides.
|
||||
.TP 6n
|
||||
\fBsudoRunAsUser\fR
|
||||
@ -217,30 +217,29 @@ or user netgroup (prefixed with a
|
||||
\(oq+\(cq)
|
||||
that contains a list of users that commands may be run as.
|
||||
The special value
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
will match any user.
|
||||
If a
|
||||
\fRsudoRunAsUser\fR
|
||||
\fIsudoRunAsUser\fR
|
||||
entry is preceded by an exclamation point,
|
||||
\(oq\&!\(cq,
|
||||
and the entry matches, the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
in which it resides will be ignored.
|
||||
If
|
||||
\fRsudoRunAsUser\fR
|
||||
\fIsudoRunAsUser\fR
|
||||
is specified but empty, it will match the invoking user.
|
||||
If neither
|
||||
\fRsudoRunAsUser\fR
|
||||
\fIsudoRunAsUser\fR
|
||||
nor
|
||||
\fRsudoRunAsGroup\fR
|
||||
\fIsudoRunAsGroup\fR
|
||||
are present, the value of the
|
||||
\fIrunas_default\fR
|
||||
\fRsudoOption\fR
|
||||
is used (defaults to
|
||||
\fR@runas_default@\fR).
|
||||
\fIsudoOption\fR
|
||||
is used (defaults to @runas_default@).
|
||||
.sp
|
||||
The
|
||||
\fRsudoRunAsUser\fR
|
||||
\fIsudoRunAsUser\fR
|
||||
attribute is only available in
|
||||
\fBsudo\fR
|
||||
versions
|
||||
@ -248,10 +247,10 @@ versions
|
||||
Older versions of
|
||||
\fBsudo\fR
|
||||
use the
|
||||
\fRsudoRunAs\fR
|
||||
\fIsudoRunAs\fR
|
||||
attribute instead.
|
||||
Negated
|
||||
\fRsudoRunAsUser\fR
|
||||
\fIsudoRunAsUser\fR
|
||||
entries are only supported by version 1.8.26 or higher.
|
||||
.TP 6n
|
||||
\fBsudoRunAsGroup\fR
|
||||
@ -259,34 +258,34 @@ A Unix group or group-ID (prefixed with
|
||||
\(oq#\(cq)
|
||||
that commands may be run as.
|
||||
The special value
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
will match any group.
|
||||
If a
|
||||
\fRsudoRunAsGroup\fR
|
||||
\fIsudoRunAsGroup\fR
|
||||
entry is preceded by an exclamation point,
|
||||
\(oq\&!\(cq,
|
||||
and the entry matches, the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
in which it resides will be ignored.
|
||||
.sp
|
||||
The
|
||||
\fRsudoRunAsGroup\fR
|
||||
\fIsudoRunAsGroup\fR
|
||||
attribute is only available in
|
||||
\fBsudo\fR
|
||||
versions
|
||||
1.7.0 and higher.
|
||||
Negated
|
||||
\fRsudoRunAsGroup\fR
|
||||
\fIsudoRunAsGroup\fR
|
||||
entries are only supported by version 1.8.26 or higher.
|
||||
.TP 6n
|
||||
\fBsudoNotBefore\fR
|
||||
A timestamp in the form
|
||||
\fRyyyymmddHHMMSSZ\fR
|
||||
\(oqyyyymmddHHMMSSZ\(cq
|
||||
that can be used to provide a start date/time for when the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
will be valid.
|
||||
If multiple
|
||||
\fRsudoNotBefore\fR
|
||||
\fIsudoNotBefore\fR
|
||||
entries are present, the earliest is used.
|
||||
Timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@ -294,7 +293,7 @@ The minute and seconds portions are optional, but some LDAP servers
|
||||
require that they be present (contrary to the RFC).
|
||||
.sp
|
||||
The
|
||||
\fRsudoNotBefore\fR
|
||||
\fIsudoNotBefore\fR
|
||||
attribute is only available in
|
||||
\fBsudo\fR
|
||||
versions 1.7.5 and higher and must be explicitly enabled via the
|
||||
@ -304,12 +303,12 @@ option in
|
||||
.TP 6n
|
||||
\fBsudoNotAfter\fR
|
||||
A timestamp in the form
|
||||
\fRyyyymmddHHMMSSZ\fR
|
||||
\(oqyyyymmddHHMMSSZ\(cq
|
||||
that indicates an expiration date/time, after which the
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
will no longer be valid.
|
||||
If multiple
|
||||
\fRsudoNotAfter\fR
|
||||
\fIsudoNotAfter\fR
|
||||
entries are present, the last one is used.
|
||||
Timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@ -317,7 +316,7 @@ The minute and seconds portions are optional, but some LDAP servers
|
||||
require that they be present (contrary to the RFC).
|
||||
.sp
|
||||
The
|
||||
\fRsudoNotAfter\fR
|
||||
\fIsudoNotAfter\fR
|
||||
attribute is only available in
|
||||
\fBsudo\fR
|
||||
versions
|
||||
@ -328,26 +327,26 @@ option in
|
||||
.TP 6n
|
||||
\fBsudoOrder\fR
|
||||
The
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
entries retrieved from the LDAP directory have no inherent order.
|
||||
The
|
||||
\fRsudoOrder\fR
|
||||
\fIsudoOrder\fR
|
||||
attribute is an integer (or floating point value for LDAP servers
|
||||
that support it) that is used to sort the matching entries.
|
||||
This allows LDAP-based sudoers entries to more closely mimic the behavior
|
||||
of the sudoers file, where the order of the entries influences the result.
|
||||
If multiple entries match, the entry with the highest
|
||||
\fRsudoOrder\fR
|
||||
\fIsudoOrder\fR
|
||||
attribute is chosen.
|
||||
This corresponds to the
|
||||
\(lqlast match\(rq
|
||||
behavior of the sudoers file.
|
||||
If the
|
||||
\fRsudoOrder\fR
|
||||
\fIsudoOrder\fR
|
||||
attribute is not present, a value of 0 is assumed.
|
||||
.sp
|
||||
The
|
||||
\fRsudoOrder\fR
|
||||
\fIsudoOrder\fR
|
||||
attribute is only available in
|
||||
\fBsudo\fR
|
||||
versions 1.7.5 and higher.
|
||||
@ -355,12 +354,12 @@ versions 1.7.5 and higher.
|
||||
Each attribute listed above should contain a single value, but there
|
||||
may be multiple instances of each attribute type.
|
||||
A
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
must contain at least one
|
||||
\fRsudoUser\fR,
|
||||
\fRsudoHost\fR,
|
||||
\fIsudoUser\fR,
|
||||
\fIsudoHost\fR,
|
||||
and
|
||||
\fRsudoCommand\fR.
|
||||
\fIsudoCommand\fR.
|
||||
.PP
|
||||
The following example allows users in group wheel to run any command
|
||||
on any host via
|
||||
@ -384,7 +383,7 @@ The first query is to parse the global options.
|
||||
The second is to match against the user's name and the groups that
|
||||
the user belongs to.
|
||||
(The special
|
||||
\fRALL\fR
|
||||
\fBALL\fR
|
||||
tag is matched in this query too.)
|
||||
If no match is returned for the user's name and groups, a third
|
||||
query returns all entries containing user netgroups and other
|
||||
@ -411,12 +410,12 @@ are as follows:
|
||||
.TP 5n
|
||||
1.\&
|
||||
Match all
|
||||
\fRnisNetgroup\fR
|
||||
\fInisNetgroup\fR
|
||||
records with a
|
||||
\fRnisNetgroupTriple\fR
|
||||
\fInisNetgroupTriple\fR
|
||||
containing the user, host, and NIS domain.
|
||||
The query will match
|
||||
\fRnisNetgroupTriple\fR
|
||||
\fInisNetgroupTriple\fR
|
||||
entries with either the short or long form of the host name or
|
||||
no host name specified in the tuple.
|
||||
If the NIS domain is set, the query will match only match entries
|
||||
@ -425,13 +424,13 @@ If the NIS domain is
|
||||
\fInot\fR
|
||||
set, a wildcard is used to match any domain name but be aware that the
|
||||
NIS schema used by some LDAP servers may not support wild cards for
|
||||
\fRnisNetgroupTriple\fR.
|
||||
\fInisNetgroupTriple\fR.
|
||||
.TP 5n
|
||||
2.\&
|
||||
Repeated queries are performed to find any nested
|
||||
\fRnisNetgroup\fR
|
||||
\fInisNetgroup\fR
|
||||
records with a
|
||||
\fRmemberNisNetgroup\fR
|
||||
\fImemberNisNetgroup\fR
|
||||
entry that refers to an already-matched record.
|
||||
.PP
|
||||
For sites with a large number of netgroups, using
|
||||
@ -465,7 +464,7 @@ returned in any specific order.
|
||||
.PP
|
||||
The order in which different entries are applied can be controlled
|
||||
using the
|
||||
\fRsudoOrder\fR
|
||||
\fIsudoOrder\fR
|
||||
attribute, but there is no way to guarantee the order of attributes
|
||||
within a specific entry.
|
||||
If there are conflicting command rules in an entry, the negative
|
||||
@ -519,18 +518,18 @@ These cannot be converted automatically.
|
||||
For example, a Cmnd_Alias in a
|
||||
\fIsudoers\fR
|
||||
file may be converted to a
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
that contains multiple commands.
|
||||
Multiple users and/or groups may be assigned to the
|
||||
\fRsudoRole\fR.
|
||||
\fIsudoRole\fR.
|
||||
.PP
|
||||
Also, host, user, runas, and command-based
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
entries are not supported.
|
||||
However, a
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
may contain one or more
|
||||
\fRsudoOption\fR
|
||||
\fIsudoOption\fR
|
||||
attributes which can often serve the same purpose.
|
||||
.PP
|
||||
Consider the following
|
||||
@ -590,7 +589,7 @@ Using a Unix group or netgroup in PAGERS rather than listing each
|
||||
user would make this easier to maintain.
|
||||
.PP
|
||||
Per-user
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
entries can be emulated by using one or more sudoOption attributes
|
||||
in a sudoRole.
|
||||
Consider the following
|
||||
@ -637,7 +636,7 @@ LDAP support, the
|
||||
schema must be
|
||||
installed on your LDAP server.
|
||||
In addition, be sure to index the
|
||||
\fRsudoUser\fR
|
||||
\fIsudoUser\fR
|
||||
attribute.
|
||||
.PP
|
||||
The
|
||||
@ -797,53 +796,51 @@ The default value is protocol version 3.
|
||||
\fBNETGROUP_BASE\fR \fIbase\fR
|
||||
The base DN to use when performing LDAP netgroup queries.
|
||||
Typically this is of the form
|
||||
\fRou=netgroup,dc=my-domain,dc=com\fR
|
||||
for the domain
|
||||
\fRmy-domain.com\fR.
|
||||
\(oqou=netgroup,dc=my-domain,dc=com\(cq
|
||||
for the domain my-domain.com.
|
||||
Multiple
|
||||
\fBNETGROUP_BASE\fR
|
||||
lines may be specified, in which case they are queried in the order specified.
|
||||
.sp
|
||||
This option can be used to query a user's netgroups directly via LDAP
|
||||
which is usually faster than fetching every
|
||||
\fRsudoRole\fR
|
||||
\fIsudoRole\fR
|
||||
object containing a
|
||||
\fRsudoUser\fR
|
||||
\fIsudoUser\fR
|
||||
that begins with a
|
||||
\(oq+\(cq
|
||||
prefix.
|
||||
The NIS schema used by some LDAP servers need a modification to
|
||||
support querying the
|
||||
\fRnisNetgroup\fR
|
||||
\fInisNetgroup\fR
|
||||
object by its
|
||||
\fRnisNetgroupTriple\fR
|
||||
\fInisNetgroupTriple\fR
|
||||
member.
|
||||
OpenLDAP's
|
||||
\fBslapd\fR
|
||||
requires the following change to the
|
||||
\fRnisNetgroupTriple\fR
|
||||
\fInisNetgroupTriple\fR
|
||||
attribute:
|
||||
.nf
|
||||
.sp
|
||||
.RS 10n
|
||||
attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
|
||||
DESC 'Netgroup triple'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
DESC 'Netgroup triple'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
.RE
|
||||
.fi
|
||||
.TP 6n
|
||||
\fBNETGROUP_SEARCH_FILTER\fR \fIldap_filter\fR
|
||||
An LDAP filter which is used to restrict the set of records returned
|
||||
when performing an LDAP netgroup query.
|
||||
Typically, this is of the
|
||||
form
|
||||
\fRattribute=value\fR
|
||||
Typically, this is of the form
|
||||
\(oqattribute=value\(cq
|
||||
or
|
||||
\fR(&(attribute=value)(attribute2=value2))\fR.
|
||||
\(oq(&(attribute=value)(attribute2=value2))\(cq.
|
||||
The default search filter is:
|
||||
\fRobjectClass=nisNetgroup\fR.
|
||||
\(oqobjectClass=nisNetgroup\(cq.
|
||||
If
|
||||
\fIldap_filter\fR
|
||||
is omitted, no search filter will be used.
|
||||
@ -928,10 +925,10 @@ This option is only relevant when using SASL authentication.
|
||||
If the
|
||||
\fBSSL\fR
|
||||
parameter is set to
|
||||
\fRon\fR,
|
||||
\fRtrue\fR,
|
||||
\fIon\fR,
|
||||
\fItrue\fR,
|
||||
or
|
||||
\fRyes\fR
|
||||
\fIyes\fR
|
||||
TLS (SSL) encryption is always used when communicating with the LDAP server.
|
||||
Typically, this involves connecting to the server on port 636 (ldaps).
|
||||
.TP 6n
|
||||
@ -939,7 +936,7 @@ Typically, this involves connecting to the server on port 636 (ldaps).
|
||||
If the
|
||||
\fBSSL\fR
|
||||
parameter is set to
|
||||
\fRstart_tls\fR,
|
||||
\fIstart_tls\fR,
|
||||
the LDAP server connection is initiated normally and TLS encryption is
|
||||
begun before the bind credentials are sent.
|
||||
This has the advantage of not requiring a dedicated port for encrypted
|
||||
@ -953,9 +950,8 @@ The base DN to use when performing
|
||||
\fBsudo\fR
|
||||
LDAP queries.
|
||||
Typically this is of the form
|
||||
\fRou=SUDOers,dc=my-domain,dc=com\fR
|
||||
for the domain
|
||||
\fRmy-domain.com\fR.
|
||||
\(oqou=SUDOers,dc=my-domain,dc=com\(cq
|
||||
for the domain my-domain.com.
|
||||
Multiple
|
||||
\fBSUDOERS_BASE\fR
|
||||
lines may be specified, in which case they are queried in the order specified.
|
||||
@ -997,20 +993,20 @@ when performing a
|
||||
LDAP query.
|
||||
Typically, this is of the
|
||||
form
|
||||
\fRattribute=value\fR
|
||||
\(oqattribute=value\(cq
|
||||
or
|
||||
\fR(&(attribute=value)(attribute2=value2))\fR.
|
||||
\(oq(&(attribute=value)(attribute2=value2))\(cq.
|
||||
The default search filter is:
|
||||
\fRobjectClass=sudoRole\fR.
|
||||
\(oqobjectClass=sudoRole\(cq.
|
||||
If
|
||||
\fIldap_filter\fR
|
||||
is omitted, no search filter will be used.
|
||||
.TP 6n
|
||||
\fBSUDOERS_TIMED\fR \fIon/true/yes/off/false/no\fR
|
||||
Whether or not to evaluate the
|
||||
\fRsudoNotBefore\fR
|
||||
\fIsudoNotBefore\fR
|
||||
and
|
||||
\fRsudoNotAfter\fR
|
||||
\fIsudoNotAfter\fR
|
||||
attributes that implement time-dependent sudoers entries.
|
||||
.TP 6n
|
||||
\fBTIMELIMIT\fR \fIseconds\fR
|
||||
@ -1062,11 +1058,11 @@ The certificate type depends on the LDAP libraries used.
|
||||
.PD 0
|
||||
.TP 6n
|
||||
OpenLDAP:
|
||||
\fRtls_cert /etc/ssl/client_cert.pem\fR
|
||||
\(oqtls_cert /etc/ssl/client_cert.pem\(cq
|
||||
.PD
|
||||
.TP 6n
|
||||
Netscape-derived:
|
||||
\fRtls_cert /var/ldap/cert7.db\fR
|
||||
\(oqtls_cert /var/ldap/cert7.db\(cq
|
||||
.TP 6n
|
||||
IBM LDAP:
|
||||
Unused, the key database specified by
|
||||
@ -1106,14 +1102,14 @@ The key type depends on the LDAP libraries used.
|
||||
.PD 0
|
||||
.TP 6n
|
||||
OpenLDAP:
|
||||
\fRtls_key /etc/ssl/client_key.pem\fR
|
||||
\(oqtls_key /etc/ssl/client_key.pem\(cq
|
||||
.PD
|
||||
.TP 6n
|
||||
Netscape-derived:
|
||||
\fRtls_key /var/ldap/key3.db\fR
|
||||
\(oqtls_key /var/ldap/key3.db\(cq
|
||||
.TP 6n
|
||||
IBM LDAP:
|
||||
\fRtls_key /usr/ldap/ldapkey.kdb\fR
|
||||
\(oqtls_key /usr/ldap/ldapkey.kdb\(cq
|
||||
.PP
|
||||
When using IBM LDAP libraries, this file may also contain
|
||||
Certificate Authority and client certificates and may be encrypted.
|
||||
@ -1171,15 +1167,15 @@ The
|
||||
must have the same path as the file specified by
|
||||
\fBTLS_KEY\fR,
|
||||
but use a
|
||||
\fR.sth\fR
|
||||
\(oq.sth\(cq
|
||||
file extension instead of
|
||||
\fR.kdb\fR,
|
||||
e.g.,
|
||||
\fRldapkey.sth\fR.
|
||||
\(oq.kdb\(cq,
|
||||
for example
|
||||
\(oqldapkey.sth\(cq.
|
||||
The default
|
||||
\fRldapkey.kdb\fR
|
||||
\(oqldapkey.kdb\(cq
|
||||
that ships with the IBM Tivoli Directory Server is encrypted with the password
|
||||
\fRssl_password\fR.
|
||||
\(oqssl_password\(cq.
|
||||
The
|
||||
\fIgsk8capicmd\fR
|
||||
utility can be used to manage the key database and create a
|
||||
@ -1251,9 +1247,9 @@ the latter being for servers that support TLS (SSL) encryption.
|
||||
If no
|
||||
\fIport\fR
|
||||
is specified, the default is port 389 for
|
||||
\fRldap://\fR
|
||||
\(oqldap://\(cq
|
||||
or port 636 for
|
||||
\fRldaps://\fR.
|
||||
\(oqldaps://\(cq.
|
||||
If no
|
||||
\fIhostname\fR
|
||||
is specified,
|
||||
@ -1266,9 +1262,9 @@ lines are treated identically to a
|
||||
\fBURI\fR
|
||||
line containing multiple entries.
|
||||
Only systems using the OpenSSL libraries support the mixing of
|
||||
\fRldap://\fR
|
||||
\(oqldap://\(cq
|
||||
and
|
||||
\fRldaps://\fR
|
||||
\(oqldaps://\(cq
|
||||
URIs.
|
||||
Both the Netscape-derived and IBM LDAP libraries used on most commercial
|
||||
versions of Unix are only capable of supporting one or the other.
|
||||
@ -1297,13 +1293,13 @@ to specify the
|
||||
\fIsudoers\fR
|
||||
search order.
|
||||
Sudo looks for a line beginning with
|
||||
\fRsudoers\fR:
|
||||
\fIsudoers\fR:
|
||||
and uses this to determine the search order.
|
||||
By default,
|
||||
\fBsudo\fR
|
||||
does not stop searching after the first match and later matches take
|
||||
precedence over earlier ones (unless
|
||||
\fR[SUCCESS=return]\fR
|
||||
\(oq[SUCCESS=return]\(cq
|
||||
is used, see below).
|
||||
The following sources are recognized:
|
||||
.PP
|
||||
@ -1322,14 +1318,14 @@ read sudoers from LDAP
|
||||
In addition, a subset of
|
||||
\fInsswitch.conf\fR-style
|
||||
action statements is supported, specifically
|
||||
\fR[SUCCESS=return]\fR
|
||||
\(oq[SUCCESS=return]\(cq
|
||||
and
|
||||
\fR[NOTFOUND=return]\fR.
|
||||
\(oq[NOTFOUND=return]\(cq.
|
||||
These will unconditionally terminate the search if the user was either
|
||||
found
|
||||
(\fR[SUCCESS=return]\fR)
|
||||
\(oq[SUCCESS=return]\(cq
|
||||
or not found
|
||||
(\fR[NOTFOUND=return]\fR)
|
||||
\(oq[NOTFOUND=return]\(cq
|
||||
in the immediately preceding source.
|
||||
Other action statements tokens are not supported, nor is test
|
||||
negation with
|
||||
@ -1420,11 +1416,11 @@ sudoers = ldap = auth, files
|
||||
.fi
|
||||
.PP
|
||||
In the above example, the
|
||||
\fRauth\fR
|
||||
\fIauth\fR
|
||||
qualifier only affects user lookups; both LDAP and
|
||||
\fIsudoers\fR
|
||||
will be queried for
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
entries.
|
||||
.PP
|
||||
If the
|
||||
@ -1449,9 +1445,9 @@ rules.
|
||||
To use SSSD as the
|
||||
\fIsudoers\fR
|
||||
source, you should use
|
||||
\fRsss\fR
|
||||
\fIsss\fR
|
||||
instead of
|
||||
\fRldap\fR
|
||||
\fIldap\fR
|
||||
for the sudoers entry in
|
||||
\fI@nsswitch_conf@\fR.
|
||||
The
|
||||
@ -1595,7 +1591,7 @@ Simply copy
|
||||
it to the schema directory (e.g.,
|
||||
\fI/etc/openldap/schema\fR),
|
||||
add the proper
|
||||
\fRinclude\fR
|
||||
\fIinclude\fR
|
||||
line in
|
||||
\fIslapd.conf\fR
|
||||
and restart
|
||||
@ -1610,9 +1606,9 @@ file instead.
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.1
|
||||
NAME 'sudoUser'
|
||||
DESC 'User(s) who may run sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseExactIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SUBSTR caseExactSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.2
|
||||
NAME 'sudoHost'
|
||||
@ -1642,14 +1638,14 @@ attributetype ( 1.3.6.1.4.1.15953.9.1.5
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.6
|
||||
NAME 'sudoRunAsUser'
|
||||
DESC 'User(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.7
|
||||
NAME 'sudoRunAsGroup'
|
||||
DESC 'Group(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.8
|
||||
NAME 'sudoNotBefore'
|
||||
@ -1666,11 +1662,11 @@ attributetype ( 1.3.6.1.4.1.15953.9.1.9
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.10
|
||||
NAME 'sudoOrder'
|
||||
DESC 'an integer to order the sudoRole entries'
|
||||
EQUALITY integerMatch
|
||||
ORDERING integerOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
|
||||
NAME 'sudoOrder'
|
||||
DESC 'an integer to order the sudoRole entries'
|
||||
EQUALITY integerMatch
|
||||
ORDERING integerOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
|
||||
DESC 'Sudoer Entries'
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDOERS.LDAP @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -67,16 +67,16 @@ is no need for a specialized tool to check syntax.
|
||||
The
|
||||
.Em sudoers
|
||||
configuration is contained in the
|
||||
.Li ou=SUDOers
|
||||
.Ql ou=SUDOers
|
||||
LDAP container.
|
||||
.Pp
|
||||
Sudo first looks for the
|
||||
.Li cn=defaults
|
||||
.Ql cn=defaults
|
||||
entry in the SUDOers container.
|
||||
If found, the multi-valued
|
||||
.Li sudoOption
|
||||
.Em sudoOption
|
||||
attribute is parsed in the same manner as a global
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
line in
|
||||
.Pa @sysconfdir@/sudoers .
|
||||
In the following example, the
|
||||
@ -92,7 +92,7 @@ sudoOption: env_keep+=SSH_AUTH_SOCK
|
||||
.Ed
|
||||
.Pp
|
||||
The equivalent of a sudoer in LDAP is a
|
||||
.Li sudoRole .
|
||||
.Em sudoRole .
|
||||
It consists of the following attributes:
|
||||
.Bl -tag -width 4n
|
||||
.It Sy sudoUser
|
||||
@ -115,35 +115,35 @@ Non-Unix group support is only available when an appropriate
|
||||
.Em group_plugin
|
||||
is defined in the global
|
||||
.Em defaults
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
object.
|
||||
If a
|
||||
.Li sudoUser
|
||||
.Em sudoUser
|
||||
entry is preceded by an exclamation point,
|
||||
.Ql \&! ,
|
||||
and the entry matches, the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
in which it resides will be ignored.
|
||||
Negated
|
||||
.Li sudoUser
|
||||
.Em sudoUser
|
||||
entries are only supported by version 1.9.9 or higher.
|
||||
.It Sy sudoHost
|
||||
A host name, IP address, IP network, or host netgroup (prefixed with a
|
||||
.Ql + ) .
|
||||
The special value
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
will match any host.
|
||||
Host netgroups are matched using the host (both qualified and unqualified)
|
||||
and domain members only; the user member is not used when matching.
|
||||
If a
|
||||
.Li sudoHost
|
||||
.Em sudoHost
|
||||
entry is preceded by an exclamation point,
|
||||
.Ql \&! ,
|
||||
and the entry matches, the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
in which it resides will be ignored.
|
||||
Negated
|
||||
.Li sudoHost
|
||||
.Em sudoHost
|
||||
entries are only supported by version 1.8.18 or higher.
|
||||
.It Sy sudoCommand
|
||||
A fully-qualified Unix command name with optional command line arguments,
|
||||
@ -153,7 +153,7 @@ If a command name is preceded by an exclamation point,
|
||||
the user will be prohibited from running that command.
|
||||
.Pp
|
||||
The built-in command
|
||||
.Dq Li sudoedit
|
||||
.Dq sudoedit
|
||||
is used to permit a user to run
|
||||
.Nm sudo
|
||||
with the
|
||||
@ -162,13 +162,13 @@ option (or as
|
||||
.Nm sudoedit ) .
|
||||
It may take command line arguments just as a normal command does.
|
||||
Unlike other commands,
|
||||
.Dq Li sudoedit
|
||||
.Dq sudoedit
|
||||
is a built into
|
||||
.Nm sudo
|
||||
itself and must be specified in without a leading path.
|
||||
.Pp
|
||||
The special value
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
will match any command.
|
||||
.Pp
|
||||
If a command name is prefixed with a SHA-2 digest, it will
|
||||
@ -192,7 +192,7 @@ Command digests are only supported by version 1.8.7 or higher.
|
||||
.It Sy sudoOption
|
||||
Identical in function to the global options described above, but
|
||||
specific to the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
in which it resides.
|
||||
.It Sy sudoRunAsUser
|
||||
A user name or user-ID (prefixed with
|
||||
@ -203,30 +203,29 @@ or user netgroup (prefixed with a
|
||||
.Ql + )
|
||||
that contains a list of users that commands may be run as.
|
||||
The special value
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
will match any user.
|
||||
If a
|
||||
.Li sudoRunAsUser
|
||||
.Em sudoRunAsUser
|
||||
entry is preceded by an exclamation point,
|
||||
.Ql \&! ,
|
||||
and the entry matches, the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
in which it resides will be ignored.
|
||||
If
|
||||
.Li sudoRunAsUser
|
||||
.Em sudoRunAsUser
|
||||
is specified but empty, it will match the invoking user.
|
||||
If neither
|
||||
.Li sudoRunAsUser
|
||||
.Em sudoRunAsUser
|
||||
nor
|
||||
.Li sudoRunAsGroup
|
||||
.Em sudoRunAsGroup
|
||||
are present, the value of the
|
||||
.Em runas_default
|
||||
.Li sudoOption
|
||||
is used (defaults to
|
||||
.Li @runas_default@ ) .
|
||||
.Em sudoOption
|
||||
is used (defaults to @runas_default@).
|
||||
.Pp
|
||||
The
|
||||
.Li sudoRunAsUser
|
||||
.Em sudoRunAsUser
|
||||
attribute is only available in
|
||||
.Nm sudo
|
||||
versions
|
||||
@ -234,43 +233,43 @@ versions
|
||||
Older versions of
|
||||
.Nm sudo
|
||||
use the
|
||||
.Li sudoRunAs
|
||||
.Em sudoRunAs
|
||||
attribute instead.
|
||||
Negated
|
||||
.Li sudoRunAsUser
|
||||
.Em sudoRunAsUser
|
||||
entries are only supported by version 1.8.26 or higher.
|
||||
.It Sy sudoRunAsGroup
|
||||
A Unix group or group-ID (prefixed with
|
||||
.Ql # )
|
||||
that commands may be run as.
|
||||
The special value
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
will match any group.
|
||||
If a
|
||||
.Li sudoRunAsGroup
|
||||
.Em sudoRunAsGroup
|
||||
entry is preceded by an exclamation point,
|
||||
.Ql \&! ,
|
||||
and the entry matches, the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
in which it resides will be ignored.
|
||||
.Pp
|
||||
The
|
||||
.Li sudoRunAsGroup
|
||||
.Em sudoRunAsGroup
|
||||
attribute is only available in
|
||||
.Nm sudo
|
||||
versions
|
||||
1.7.0 and higher.
|
||||
Negated
|
||||
.Li sudoRunAsGroup
|
||||
.Em sudoRunAsGroup
|
||||
entries are only supported by version 1.8.26 or higher.
|
||||
.It Sy sudoNotBefore
|
||||
A timestamp in the form
|
||||
.Li yyyymmddHHMMSSZ
|
||||
.Ql yyyymmddHHMMSSZ
|
||||
that can be used to provide a start date/time for when the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
will be valid.
|
||||
If multiple
|
||||
.Li sudoNotBefore
|
||||
.Em sudoNotBefore
|
||||
entries are present, the earliest is used.
|
||||
Timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@ -278,7 +277,7 @@ The minute and seconds portions are optional, but some LDAP servers
|
||||
require that they be present (contrary to the RFC).
|
||||
.Pp
|
||||
The
|
||||
.Li sudoNotBefore
|
||||
.Em sudoNotBefore
|
||||
attribute is only available in
|
||||
.Nm sudo
|
||||
versions 1.7.5 and higher and must be explicitly enabled via the
|
||||
@ -287,12 +286,12 @@ option in
|
||||
.Pa @ldap_conf@ .
|
||||
.It Sy sudoNotAfter
|
||||
A timestamp in the form
|
||||
.Li yyyymmddHHMMSSZ
|
||||
.Ql yyyymmddHHMMSSZ
|
||||
that indicates an expiration date/time, after which the
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
will no longer be valid.
|
||||
If multiple
|
||||
.Li sudoNotAfter
|
||||
.Em sudoNotAfter
|
||||
entries are present, the last one is used.
|
||||
Timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@ -300,7 +299,7 @@ The minute and seconds portions are optional, but some LDAP servers
|
||||
require that they be present (contrary to the RFC).
|
||||
.Pp
|
||||
The
|
||||
.Li sudoNotAfter
|
||||
.Em sudoNotAfter
|
||||
attribute is only available in
|
||||
.Nm sudo
|
||||
versions
|
||||
@ -310,26 +309,26 @@ option in
|
||||
.Pa @ldap_conf@ .
|
||||
.It Sy sudoOrder
|
||||
The
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
entries retrieved from the LDAP directory have no inherent order.
|
||||
The
|
||||
.Li sudoOrder
|
||||
.Em sudoOrder
|
||||
attribute is an integer (or floating point value for LDAP servers
|
||||
that support it) that is used to sort the matching entries.
|
||||
This allows LDAP-based sudoers entries to more closely mimic the behavior
|
||||
of the sudoers file, where the order of the entries influences the result.
|
||||
If multiple entries match, the entry with the highest
|
||||
.Li sudoOrder
|
||||
.Em sudoOrder
|
||||
attribute is chosen.
|
||||
This corresponds to the
|
||||
.Dq last match
|
||||
behavior of the sudoers file.
|
||||
If the
|
||||
.Li sudoOrder
|
||||
.Em sudoOrder
|
||||
attribute is not present, a value of 0 is assumed.
|
||||
.Pp
|
||||
The
|
||||
.Li sudoOrder
|
||||
.Em sudoOrder
|
||||
attribute is only available in
|
||||
.Nm sudo
|
||||
versions 1.7.5 and higher.
|
||||
@ -338,12 +337,12 @@ versions 1.7.5 and higher.
|
||||
Each attribute listed above should contain a single value, but there
|
||||
may be multiple instances of each attribute type.
|
||||
A
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
must contain at least one
|
||||
.Li sudoUser ,
|
||||
.Li sudoHost ,
|
||||
.Em sudoUser ,
|
||||
.Em sudoHost ,
|
||||
and
|
||||
.Li sudoCommand .
|
||||
.Em sudoCommand .
|
||||
.Pp
|
||||
The following example allows users in group wheel to run any command
|
||||
on any host via
|
||||
@ -364,7 +363,7 @@ The first query is to parse the global options.
|
||||
The second is to match against the user's name and the groups that
|
||||
the user belongs to.
|
||||
(The special
|
||||
.Li ALL
|
||||
.Sy ALL
|
||||
tag is matched in this query too.)
|
||||
If no match is returned for the user's name and groups, a third
|
||||
query returns all entries containing user netgroups and other
|
||||
@ -391,12 +390,12 @@ are as follows:
|
||||
.Bl -enum
|
||||
.It
|
||||
Match all
|
||||
.Li nisNetgroup
|
||||
.Em nisNetgroup
|
||||
records with a
|
||||
.Li nisNetgroupTriple
|
||||
.Em nisNetgroupTriple
|
||||
containing the user, host, and NIS domain.
|
||||
The query will match
|
||||
.Li nisNetgroupTriple
|
||||
.Em nisNetgroupTriple
|
||||
entries with either the short or long form of the host name or
|
||||
no host name specified in the tuple.
|
||||
If the NIS domain is set, the query will match only match entries
|
||||
@ -405,12 +404,12 @@ If the NIS domain is
|
||||
.Em not
|
||||
set, a wildcard is used to match any domain name but be aware that the
|
||||
NIS schema used by some LDAP servers may not support wild cards for
|
||||
.Li nisNetgroupTriple .
|
||||
.Em nisNetgroupTriple .
|
||||
.It
|
||||
Repeated queries are performed to find any nested
|
||||
.Li nisNetgroup
|
||||
.Em nisNetgroup
|
||||
records with a
|
||||
.Li memberNisNetgroup
|
||||
.Em memberNisNetgroup
|
||||
entry that refers to an already-matched record.
|
||||
.El
|
||||
.Pp
|
||||
@ -445,7 +444,7 @@ returned in any specific order.
|
||||
.Pp
|
||||
The order in which different entries are applied can be controlled
|
||||
using the
|
||||
.Li sudoOrder
|
||||
.Em sudoOrder
|
||||
attribute, but there is no way to guarantee the order of attributes
|
||||
within a specific entry.
|
||||
If there are conflicting command rules in an entry, the negative
|
||||
@ -496,18 +495,18 @@ These cannot be converted automatically.
|
||||
For example, a Cmnd_Alias in a
|
||||
.Em sudoers
|
||||
file may be converted to a
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
that contains multiple commands.
|
||||
Multiple users and/or groups may be assigned to the
|
||||
.Li sudoRole .
|
||||
.Em sudoRole .
|
||||
.Pp
|
||||
Also, host, user, runas, and command-based
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
entries are not supported.
|
||||
However, a
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
may contain one or more
|
||||
.Li sudoOption
|
||||
.Em sudoOption
|
||||
attributes which can often serve the same purpose.
|
||||
.Pp
|
||||
Consider the following
|
||||
@ -561,7 +560,7 @@ Using a Unix group or netgroup in PAGERS rather than listing each
|
||||
user would make this easier to maintain.
|
||||
.Pp
|
||||
Per-user
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
entries can be emulated by using one or more sudoOption attributes
|
||||
in a sudoRole.
|
||||
Consider the following
|
||||
@ -602,7 +601,7 @@ LDAP support, the
|
||||
schema must be
|
||||
installed on your LDAP server.
|
||||
In addition, be sure to index the
|
||||
.Li sudoUser
|
||||
.Em sudoUser
|
||||
attribute.
|
||||
.Pp
|
||||
The
|
||||
@ -748,49 +747,47 @@ The default value is protocol version 3.
|
||||
.It Sy NETGROUP_BASE Ar base
|
||||
The base DN to use when performing LDAP netgroup queries.
|
||||
Typically this is of the form
|
||||
.Li ou=netgroup,dc=my-domain,dc=com
|
||||
for the domain
|
||||
.Li my-domain.com .
|
||||
.Ql ou=netgroup,dc=my-domain,dc=com
|
||||
for the domain my-domain.com.
|
||||
Multiple
|
||||
.Sy NETGROUP_BASE
|
||||
lines may be specified, in which case they are queried in the order specified.
|
||||
.Pp
|
||||
This option can be used to query a user's netgroups directly via LDAP
|
||||
which is usually faster than fetching every
|
||||
.Li sudoRole
|
||||
.Em sudoRole
|
||||
object containing a
|
||||
.Li sudoUser
|
||||
.Em sudoUser
|
||||
that begins with a
|
||||
.Ql +
|
||||
prefix.
|
||||
The NIS schema used by some LDAP servers need a modification to
|
||||
support querying the
|
||||
.Li nisNetgroup
|
||||
.Em nisNetgroup
|
||||
object by its
|
||||
.Li nisNetgroupTriple
|
||||
.Em nisNetgroupTriple
|
||||
member.
|
||||
OpenLDAP's
|
||||
.Sy slapd
|
||||
requires the following change to the
|
||||
.Li nisNetgroupTriple
|
||||
.Em nisNetgroupTriple
|
||||
attribute:
|
||||
.Bd -literal -offset 4n
|
||||
attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
|
||||
DESC 'Netgroup triple'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
DESC 'Netgroup triple'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SUBSTR caseIgnoreIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
.Ed
|
||||
.It Sy NETGROUP_SEARCH_FILTER Ar ldap_filter
|
||||
An LDAP filter which is used to restrict the set of records returned
|
||||
when performing an LDAP netgroup query.
|
||||
Typically, this is of the
|
||||
form
|
||||
.Li attribute=value
|
||||
Typically, this is of the form
|
||||
.Ql attribute=value
|
||||
or
|
||||
.Li (&(attribute=value)(attribute2=value2)) .
|
||||
.Ql (&(attribute=value)(attribute2=value2)) .
|
||||
The default search filter is:
|
||||
.Li objectClass=nisNetgroup .
|
||||
.Ql objectClass=nisNetgroup .
|
||||
If
|
||||
.Ar ldap_filter
|
||||
is omitted, no search filter will be used.
|
||||
@ -867,17 +864,17 @@ This option is only relevant when using SASL authentication.
|
||||
If the
|
||||
.Sy SSL
|
||||
parameter is set to
|
||||
.Li on ,
|
||||
.Li true ,
|
||||
.Em on ,
|
||||
.Em true ,
|
||||
or
|
||||
.Li yes
|
||||
.Em yes
|
||||
TLS (SSL) encryption is always used when communicating with the LDAP server.
|
||||
Typically, this involves connecting to the server on port 636 (ldaps).
|
||||
.It Sy SSL Ar start_tls
|
||||
If the
|
||||
.Sy SSL
|
||||
parameter is set to
|
||||
.Li start_tls ,
|
||||
.Em start_tls ,
|
||||
the LDAP server connection is initiated normally and TLS encryption is
|
||||
begun before the bind credentials are sent.
|
||||
This has the advantage of not requiring a dedicated port for encrypted
|
||||
@ -890,9 +887,8 @@ The base DN to use when performing
|
||||
.Nm sudo
|
||||
LDAP queries.
|
||||
Typically this is of the form
|
||||
.Li ou=SUDOers,dc=my-domain,dc=com
|
||||
for the domain
|
||||
.Li my-domain.com .
|
||||
.Ql ou=SUDOers,dc=my-domain,dc=com
|
||||
for the domain my-domain.com.
|
||||
Multiple
|
||||
.Sy SUDOERS_BASE
|
||||
lines may be specified, in which case they are queried in the order specified.
|
||||
@ -932,19 +928,19 @@ when performing a
|
||||
LDAP query.
|
||||
Typically, this is of the
|
||||
form
|
||||
.Li attribute=value
|
||||
.Ql attribute=value
|
||||
or
|
||||
.Li (&(attribute=value)(attribute2=value2)) .
|
||||
.Ql (&(attribute=value)(attribute2=value2)) .
|
||||
The default search filter is:
|
||||
.Li objectClass=sudoRole .
|
||||
.Ql objectClass=sudoRole .
|
||||
If
|
||||
.Ar ldap_filter
|
||||
is omitted, no search filter will be used.
|
||||
.It Sy SUDOERS_TIMED Ar on/true/yes/off/false/no
|
||||
Whether or not to evaluate the
|
||||
.Li sudoNotBefore
|
||||
.Em sudoNotBefore
|
||||
and
|
||||
.Li sudoNotAfter
|
||||
.Em sudoNotAfter
|
||||
attributes that implement time-dependent sudoers entries.
|
||||
.It Sy TIMELIMIT Ar seconds
|
||||
The
|
||||
@ -987,9 +983,9 @@ be used to authenticate the client to the LDAP server.
|
||||
The certificate type depends on the LDAP libraries used.
|
||||
.Bl -tag -width 4n
|
||||
.It OpenLDAP:
|
||||
.Li tls_cert /etc/ssl/client_cert.pem
|
||||
.Ql tls_cert /etc/ssl/client_cert.pem
|
||||
.It Netscape-derived:
|
||||
.Li tls_cert /var/ldap/cert7.db
|
||||
.Ql tls_cert /var/ldap/cert7.db
|
||||
.It IBM LDAP:
|
||||
Unused, the key database specified by
|
||||
.Sy TLS_KEY
|
||||
@ -1023,11 +1019,11 @@ The private key must not be password-protected.
|
||||
The key type depends on the LDAP libraries used.
|
||||
.Bl -tag -width 4n
|
||||
.It OpenLDAP:
|
||||
.Li tls_key /etc/ssl/client_key.pem
|
||||
.Ql tls_key /etc/ssl/client_key.pem
|
||||
.It Netscape-derived:
|
||||
.Li tls_key /var/ldap/key3.db
|
||||
.Ql tls_key /var/ldap/key3.db
|
||||
.It IBM LDAP:
|
||||
.Li tls_key /usr/ldap/ldapkey.kdb
|
||||
.Ql tls_key /usr/ldap/ldapkey.kdb
|
||||
.El
|
||||
.Pp
|
||||
When using IBM LDAP libraries, this file may also contain
|
||||
@ -1079,15 +1075,15 @@ The
|
||||
must have the same path as the file specified by
|
||||
.Sy TLS_KEY ,
|
||||
but use a
|
||||
.Li .sth
|
||||
.Ql .sth
|
||||
file extension instead of
|
||||
.Li .kdb ,
|
||||
e.g.,
|
||||
.Li ldapkey.sth .
|
||||
.Ql .kdb ,
|
||||
for example
|
||||
.Ql ldapkey.sth .
|
||||
The default
|
||||
.Li ldapkey.kdb
|
||||
.Ql ldapkey.kdb
|
||||
that ships with the IBM Tivoli Directory Server is encrypted with the password
|
||||
.Li ssl_password .
|
||||
.Ql ssl_password .
|
||||
The
|
||||
.Em gsk8capicmd
|
||||
utility can be used to manage the key database and create a
|
||||
@ -1149,9 +1145,9 @@ the latter being for servers that support TLS (SSL) encryption.
|
||||
If no
|
||||
.Em port
|
||||
is specified, the default is port 389 for
|
||||
.Li ldap://
|
||||
.Ql ldap://
|
||||
or port 636 for
|
||||
.Li ldaps:// .
|
||||
.Ql ldaps:// .
|
||||
If no
|
||||
.Em hostname
|
||||
is specified,
|
||||
@ -1164,9 +1160,9 @@ lines are treated identically to a
|
||||
.Sy URI
|
||||
line containing multiple entries.
|
||||
Only systems using the OpenSSL libraries support the mixing of
|
||||
.Li ldap://
|
||||
.Ql ldap://
|
||||
and
|
||||
.Li ldaps://
|
||||
.Ql ldaps://
|
||||
URIs.
|
||||
Both the Netscape-derived and IBM LDAP libraries used on most commercial
|
||||
versions of Unix are only capable of supporting one or the other.
|
||||
@ -1194,13 +1190,13 @@ to specify the
|
||||
.Em sudoers
|
||||
search order.
|
||||
Sudo looks for a line beginning with
|
||||
.Li sudoers :
|
||||
.Em sudoers :
|
||||
and uses this to determine the search order.
|
||||
By default,
|
||||
.Nm sudo
|
||||
does not stop searching after the first match and later matches take
|
||||
precedence over earlier ones (unless
|
||||
.Li [SUCCESS=return]
|
||||
.Ql [SUCCESS=return]
|
||||
is used, see below).
|
||||
The following sources are recognized:
|
||||
.Pp
|
||||
@ -1215,14 +1211,14 @@ read sudoers from LDAP
|
||||
In addition, a subset of
|
||||
.Pa nsswitch.conf Ns -style
|
||||
action statements is supported, specifically
|
||||
.Li [SUCCESS=return]
|
||||
.Ql [SUCCESS=return]
|
||||
and
|
||||
.Li [NOTFOUND=return] .
|
||||
.Ql [NOTFOUND=return] .
|
||||
These will unconditionally terminate the search if the user was either
|
||||
found
|
||||
.Pq Li [SUCCESS=return]
|
||||
.Ql [SUCCESS=return]
|
||||
or not found
|
||||
.Pq Li [NOTFOUND=return]
|
||||
.Ql [NOTFOUND=return]
|
||||
in the immediately preceding source.
|
||||
Other action statements tokens are not supported, nor is test
|
||||
negation with
|
||||
@ -1292,11 +1288,11 @@ sudoers = ldap = auth, files
|
||||
.Ed
|
||||
.Pp
|
||||
In the above example, the
|
||||
.Li auth
|
||||
.Em auth
|
||||
qualifier only affects user lookups; both LDAP and
|
||||
.Em sudoers
|
||||
will be queried for
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
entries.
|
||||
.Pp
|
||||
If the
|
||||
@ -1318,9 +1314,9 @@ rules.
|
||||
To use SSSD as the
|
||||
.Em sudoers
|
||||
source, you should use
|
||||
.Li sss
|
||||
.Em sss
|
||||
instead of
|
||||
.Li ldap
|
||||
.Em ldap
|
||||
for the sudoers entry in
|
||||
.Pa @nsswitch_conf@ .
|
||||
The
|
||||
@ -1461,7 +1457,7 @@ Simply copy
|
||||
it to the schema directory (e.g.,
|
||||
.Pa /etc/openldap/schema ) ,
|
||||
add the proper
|
||||
.Li include
|
||||
.Em include
|
||||
line in
|
||||
.Pa slapd.conf
|
||||
and restart
|
||||
@ -1474,9 +1470,9 @@ file instead.
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.1
|
||||
NAME 'sudoUser'
|
||||
DESC 'User(s) who may run sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SUBSTR caseExactIA5SubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SUBSTR caseExactSubstringsMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.2
|
||||
NAME 'sudoHost'
|
||||
@ -1506,14 +1502,14 @@ attributetype ( 1.3.6.1.4.1.15953.9.1.5
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.6
|
||||
NAME 'sudoRunAsUser'
|
||||
DESC 'User(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.7
|
||||
NAME 'sudoRunAsGroup'
|
||||
DESC 'Group(s) impersonated by sudo'
|
||||
EQUALITY caseExactIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
EQUALITY caseExactMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.8
|
||||
NAME 'sudoNotBefore'
|
||||
@ -1530,11 +1526,11 @@ attributetype ( 1.3.6.1.4.1.15953.9.1.9
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.15953.9.1.10
|
||||
NAME 'sudoOrder'
|
||||
DESC 'an integer to order the sudoRole entries'
|
||||
EQUALITY integerMatch
|
||||
ORDERING integerOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
|
||||
NAME 'sudoOrder'
|
||||
DESC 'an integer to order the sudoRole entries'
|
||||
EQUALITY integerMatch
|
||||
ORDERING integerOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
|
||||
DESC 'Sudoer Entries'
|
||||
|
1526
docs/sudoers.man.in
1526
docs/sudoers.man.in
File diff suppressed because it is too large
Load Diff
1637
docs/sudoers.mdoc.in
1637
docs/sudoers.mdoc.in
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDOERS_TIMESTAMP" "@mansectform@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDOERS_TIMESTAMP" "@mansectform@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -29,7 +29,7 @@ plugin uses per-user time stamp files for credential caching.
|
||||
Once a user has been authenticated, they may use
|
||||
\fBsudo\fR
|
||||
without a password for a short period of time
|
||||
(\fR@timeout@\fR
|
||||
(\fI@timeout@\fR
|
||||
minutes unless overridden by the
|
||||
\fItimestamp_timeout\fR
|
||||
option)
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDOERS_TIMESTAMP @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -29,7 +29,7 @@ Once a user has been authenticated, they may use
|
||||
.Nm sudo
|
||||
without a password for a short period of time
|
||||
.Po
|
||||
.Li @timeout@
|
||||
.Em @timeout@
|
||||
minutes unless overridden by the
|
||||
.Em timestamp_timeout
|
||||
option
|
||||
@ -94,19 +94,19 @@ same file but are not inter-operable.
|
||||
The size of the record in bytes.
|
||||
.It type
|
||||
The record type, currently
|
||||
.Li TS_GLOBAL ,
|
||||
.Li TS_TTY ,
|
||||
.Dv TS_GLOBAL ,
|
||||
.Dv TS_TTY ,
|
||||
or
|
||||
.Li TS_PPID .
|
||||
.Dv TS_PPID .
|
||||
.It flags
|
||||
Zero or more record flags which can be bit-wise ORed together.
|
||||
Supported flags are
|
||||
.Li TS_DISABLED ,
|
||||
.Dv TS_DISABLED ,
|
||||
for records disabled via
|
||||
.Nm sudo
|
||||
.Fl k
|
||||
and
|
||||
.Li TS_ANYUID ,
|
||||
.Dv TS_ANYUID ,
|
||||
which is used only when matching records.
|
||||
.It auth_uid
|
||||
The user-ID that was used for authentication.
|
||||
@ -120,12 +120,12 @@ the default runas user or the target user.
|
||||
.It sid
|
||||
The ID of the user's terminal session, if present.
|
||||
The session ID is only used when matching records of type
|
||||
.Li TS_TTY .
|
||||
.Dv TS_TTY .
|
||||
.It start_time
|
||||
The start time of the session leader for records of type
|
||||
.Li TS_TTY
|
||||
.Dv TS_TTY
|
||||
or of the parent process for records of type
|
||||
.Li TS_PPID .
|
||||
.Dv TS_PPID .
|
||||
The
|
||||
.Em start_time
|
||||
is used to help prevent re-use of a time stamp record after a
|
||||
@ -157,10 +157,10 @@ option, no password is required.
|
||||
.It u.ttydev
|
||||
The device number of the terminal associated with the session for
|
||||
records of type
|
||||
.Li TS_TTY .
|
||||
.Dv TS_TTY .
|
||||
.It u.ppid
|
||||
The ID of the parent process for records of type
|
||||
.Li TS_PPID .
|
||||
.Dv TS_PPID .
|
||||
.El
|
||||
.Sh LOCKING
|
||||
In
|
||||
@ -174,7 +174,7 @@ of the entire file and the lock is held for a longer period of time.
|
||||
This scheme is described below.
|
||||
.Pp
|
||||
The first record in the time stamp file is of type
|
||||
.Li TS_LOCKEXCL
|
||||
.Dv TS_LOCKEXCL
|
||||
and is used as a
|
||||
.Em lock
|
||||
record to prevent more than one
|
||||
@ -182,7 +182,7 @@ record to prevent more than one
|
||||
process from adding a new record at the same time.
|
||||
Once the desired time stamp record has been located or created (and
|
||||
locked), the
|
||||
.Li TS_LOCKEXCL
|
||||
.Dv TS_LOCKEXCL
|
||||
record is unlocked.
|
||||
The lock on the individual time stamp record, however, is held until
|
||||
authentication is complete.
|
||||
@ -192,7 +192,7 @@ to avoid prompting for a password multiple times when it
|
||||
is used more than once in a pipeline.
|
||||
.Pp
|
||||
Records of type
|
||||
.Li TS_GLOBAL
|
||||
.Dv TS_GLOBAL
|
||||
cannot be locked for a long period of time since doing so would
|
||||
interfere with other
|
||||
.Nm sudo
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDOREPLAY" "@mansectsu@" "February 16, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.TH "SUDOREPLAY" "@mansectsu@" "September 13, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -50,7 +50,7 @@ The
|
||||
\fIID\fR
|
||||
should either be a six character sequence of digits and
|
||||
upper case letters, e.g.,
|
||||
\fR0100A5\fR
|
||||
\(lq0100A5\(rq
|
||||
or a path name.
|
||||
The
|
||||
\fIID\fR
|
||||
@ -76,8 +76,10 @@ with
|
||||
enabled in the
|
||||
\fIsudoers\fR
|
||||
file, a
|
||||
\fRTSID=ID\fR
|
||||
string is logged via syslog or to the
|
||||
\(lqTSID=ID\(rq
|
||||
string is logged via
|
||||
syslog(3)
|
||||
or to the
|
||||
\fBsudo\fR
|
||||
log file.
|
||||
The
|
||||
@ -400,7 +402,7 @@ This will be addressed in a future version of
|
||||
\fBsudoreplay\fR
|
||||
versions 1.8.4 and higher support a flexible debugging framework
|
||||
that is configured via
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
lines in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd February 16, 2022
|
||||
.Dd September 13, 2022
|
||||
.Dt SUDOREPLAY @mansectsu@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -48,7 +48,7 @@ The
|
||||
.Em ID
|
||||
should either be a six character sequence of digits and
|
||||
upper case letters, e.g.,
|
||||
.Li 0100A5
|
||||
.Dq 0100A5
|
||||
or a path name.
|
||||
The
|
||||
.Em ID
|
||||
@ -74,8 +74,10 @@ with
|
||||
enabled in the
|
||||
.Em sudoers
|
||||
file, a
|
||||
.Li TSID=ID
|
||||
string is logged via syslog or to the
|
||||
.Dq TSID=ID
|
||||
string is logged via
|
||||
.Xr syslog 3
|
||||
or to the
|
||||
.Nm sudo
|
||||
log file.
|
||||
The
|
||||
@ -363,7 +365,7 @@ This will be addressed in a future version of
|
||||
.Nm
|
||||
versions 1.8.4 and higher support a flexible debugging framework
|
||||
that is configured via
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
lines in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
|
@ -21,7 +21,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.TH "VISUDO" "@mansectsu@" "April 23, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.TH "VISUDO" "@mansectsu@" "October 4, 2022" "Sudo @PACKAGE_VERSION@" "System Manager's Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -30,7 +30,7 @@
|
||||
.SH "SYNOPSIS"
|
||||
.HP 7n
|
||||
\fBvisudo\fR
|
||||
[\fB\-chOPqsV\fR]
|
||||
[\fB\-chIOPqsV\fR]
|
||||
[[\fB\-f\fR]\ \fIsudoers\fR]
|
||||
.SH "DESCRIPTION"
|
||||
\fBvisudo\fR
|
||||
@ -208,6 +208,24 @@ option.
|
||||
\fB\-h\fR, \fB\--help\fR
|
||||
Display a short help message to the standard output and exit.
|
||||
.TP 12n
|
||||
\fB\-I\fR, \fB\--no-includes\fR
|
||||
Disable the editing of include files unless there is a pre-existing
|
||||
syntax error.
|
||||
By default,
|
||||
\fBvisudo\fR
|
||||
will edit the main
|
||||
\fIsudoers\fR
|
||||
file and any files included via
|
||||
\fI@include\fR
|
||||
or
|
||||
\fI#include\fR
|
||||
directives.
|
||||
Files included via
|
||||
\fI@includedir\fR
|
||||
or
|
||||
\fI#includedir\fR
|
||||
are never edited unless they contain a syntax error.
|
||||
.TP 12n
|
||||
\fB\-O\fR, \fB\--owner\fR
|
||||
Enforce the default ownership (user and group) of the
|
||||
\fIsudoers\fR
|
||||
@ -289,7 +307,7 @@ include file for syntax errors.
|
||||
\fBvisudo\fR
|
||||
versions 1.8.4 and higher support a flexible debugging framework
|
||||
that is configured via
|
||||
\fRDebug\fR
|
||||
\fIDebug\fR
|
||||
lines in the
|
||||
sudo.conf(@mansectform@)
|
||||
file.
|
||||
@ -450,7 +468,7 @@ file.
|
||||
The
|
||||
\fIsudoers\fR
|
||||
file contains a
|
||||
\fRDefaults\fR
|
||||
\fIDefaults\fR
|
||||
setting not recognized by
|
||||
\fBvisudo\fR.
|
||||
.SH "SEE ALSO"
|
||||
|
@ -20,7 +20,7 @@
|
||||
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
.\"
|
||||
.Dd April 23, 2022
|
||||
.Dd October 4, 2022
|
||||
.Dt VISUDO @mansectsu@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -28,7 +28,7 @@
|
||||
.Nd edit the sudoers file
|
||||
.Sh SYNOPSIS
|
||||
.Nm visudo
|
||||
.Op Fl chOPqsV
|
||||
.Op Fl chIOPqsV
|
||||
.Op Bo Fl f Bc Ar sudoers
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
@ -203,6 +203,23 @@ path can be specified without using the
|
||||
option.
|
||||
.It Fl h , -help
|
||||
Display a short help message to the standard output and exit.
|
||||
.It Fl I , -no-includes
|
||||
Disable the editing of include files unless there is a pre-existing
|
||||
syntax error.
|
||||
By default,
|
||||
.Nm
|
||||
will edit the main
|
||||
.Ar sudoers
|
||||
file and any files included via
|
||||
.Em @include
|
||||
or
|
||||
.Em #include
|
||||
directives.
|
||||
Files included via
|
||||
.Em @includedir
|
||||
or
|
||||
.Em #includedir
|
||||
are never edited unless they contain a syntax error.
|
||||
.It Fl O , -owner
|
||||
Enforce the default ownership (user and group) of the
|
||||
.Em sudoers
|
||||
@ -281,7 +298,7 @@ include file for syntax errors.
|
||||
.Nm
|
||||
versions 1.8.4 and higher support a flexible debugging framework
|
||||
that is configured via
|
||||
.Li Debug
|
||||
.Em Debug
|
||||
lines in the
|
||||
.Xr sudo.conf @mansectform@
|
||||
file.
|
||||
@ -430,7 +447,7 @@ file.
|
||||
The
|
||||
.Em sudoers
|
||||
file contains a
|
||||
.Li Defaults
|
||||
.Em Defaults
|
||||
setting not recognized by
|
||||
.Nm .
|
||||
.El
|
||||
|
@ -10,7 +10,7 @@
|
||||
(TAG_SET((nt).setenv) && (nt).setenv != (ot).setenv) || \
|
||||
(TAG_SET((nt).send_mail) && (nt).send_mail != (ot).send_mail))
|
||||
sv sw ta te tg th tr uk ur vi wa wo zh_CN zh_HK
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args ? py_args : py_empty, py_kwargs, "Ois|i:sudo.ConvMessage", keywords,
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args ? py_args : py_empty, py_kwargs, "Ois|i:sudo.ConvMessage", (char **)keywords,
|
||||
$ans = <STDIN>;
|
||||
if ($ans =~ /^[yY]/) {
|
||||
.nr BA @BAMAN@
|
||||
|
@ -1,4 +1,3 @@
|
||||
Ois
|
||||
SOM
|
||||
VAS
|
||||
alloced
|
||||
@ -8,8 +7,10 @@ ist
|
||||
numer
|
||||
pleas
|
||||
sav
|
||||
statics
|
||||
thur
|
||||
toke
|
||||
vas
|
||||
wit
|
||||
statics
|
||||
siz
|
||||
clen
|
||||
|
@ -72,6 +72,7 @@ struct InterceptHello
|
||||
/*
|
||||
* Sudo response to an InterceptHello from sudo_intercept.so.
|
||||
* The client uses the port number and token to connect back to sudo.
|
||||
* If log_only is set there is no InterceptResponse to a PolicyCheckRequest.
|
||||
*/
|
||||
struct HelloResponse
|
||||
{
|
||||
@ -79,10 +80,11 @@ struct HelloResponse
|
||||
uint64_t token_lo;
|
||||
uint64_t token_hi;
|
||||
int32_t portno;
|
||||
protobuf_c_boolean log_only;
|
||||
};
|
||||
#define HELLO_RESPONSE__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&hello_response__descriptor) \
|
||||
, 0, 0, 0 }
|
||||
, 0, 0, 0, 0 }
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2018, Dave Benson and the protobuf-c authors.
|
||||
* Copyright (c) 2008-2022, Dave Benson and the protobuf-c authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -794,13 +794,13 @@ protobuf_c_version_number(void);
|
||||
* The version of the protobuf-c headers, represented as a string using the same
|
||||
* format as protobuf_c_version().
|
||||
*/
|
||||
#define PROTOBUF_C_VERSION "1.4.0"
|
||||
#define PROTOBUF_C_VERSION "1.4.1"
|
||||
|
||||
/**
|
||||
* The version of the protobuf-c headers, represented as an integer using the
|
||||
* same format as protobuf_c_version_number().
|
||||
*/
|
||||
#define PROTOBUF_C_VERSION_NUMBER 1004000
|
||||
#define PROTOBUF_C_VERSION_NUMBER 1004001
|
||||
|
||||
/**
|
||||
* The minimum protoc-c version which works with the current version of the
|
||||
|
@ -37,45 +37,6 @@
|
||||
* Macros and functions that may be missing on some operating systems.
|
||||
*/
|
||||
|
||||
#ifndef __GNUC_PREREQ__
|
||||
# ifdef __GNUC__
|
||||
# define __GNUC_PREREQ__(ma, mi) \
|
||||
((__GNUC__ > (ma)) || (__GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)))
|
||||
# else
|
||||
# define __GNUC_PREREQ__(ma, mi) 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define away __attribute__ for non-gcc or old gcc */
|
||||
#if !defined(__attribute__) && !__GNUC_PREREQ__(2, 5)
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* For catching format string mismatches */
|
||||
#ifndef __printflike
|
||||
# if __GNUC_PREREQ__(3, 3)
|
||||
# define __printflike(f, v) __attribute__((__format__ (__printf__, f, v))) __attribute__((__nonnull__ (f)))
|
||||
# elif __GNUC_PREREQ__(2, 7)
|
||||
# define __printflike(f, v) __attribute__((__format__ (__printf__, f, v)))
|
||||
# else
|
||||
# define __printflike(f, v)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __printf0like
|
||||
# if __GNUC_PREREQ__(2, 7)
|
||||
# define __printf0like(f, v) __attribute__((__format__ (__printf__, f, v)))
|
||||
# else
|
||||
# define __printf0like(f, v)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef __format_arg
|
||||
# if __GNUC_PREREQ__(2, 7)
|
||||
# define __format_arg(f) __attribute__((__format_arg__ (f)))
|
||||
# else
|
||||
# define __format_arg(f)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FALLTHROUGH_ATTRIBUTE
|
||||
# define FALLTHROUGH __attribute__((__fallthrough__))
|
||||
#else
|
||||
@ -484,22 +445,22 @@ sudo_dso_public int sudo_futimens(int fd, const struct timespec *times);
|
||||
# define futimens(_a, _b) sudo_futimens((_a), (_b))
|
||||
#endif /* HAVE_FUTIMENS */
|
||||
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||
sudo_dso_public int sudo_snprintf(char *str, size_t n, char const *fmt, ...) __printflike(3, 4);
|
||||
sudo_dso_public int sudo_snprintf(char *str, size_t n, char const *fmt, ...) sudo_printflike(3, 4);
|
||||
# undef snprintf
|
||||
# define snprintf sudo_snprintf
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
#if !defined(HAVE_VSNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||
sudo_dso_public int sudo_vsnprintf(char *str, size_t n, const char *fmt, va_list ap) __printflike(3, 0);
|
||||
sudo_dso_public int sudo_vsnprintf(char *str, size_t n, const char *fmt, va_list ap) sudo_printflike(3, 0);
|
||||
# undef vsnprintf
|
||||
# define vsnprintf sudo_vsnprintf
|
||||
#endif /* HAVE_VSNPRINTF */
|
||||
#if !defined(HAVE_ASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||
sudo_dso_public int sudo_asprintf(char **str, char const *fmt, ...) __printflike(2, 3);
|
||||
sudo_dso_public int sudo_asprintf(char **str, char const *fmt, ...) sudo_printflike(2, 3);
|
||||
# undef asprintf
|
||||
# define asprintf sudo_asprintf
|
||||
#endif /* HAVE_ASPRINTF */
|
||||
#if !defined(HAVE_VASPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
|
||||
sudo_dso_public int sudo_vasprintf(char **str, const char *fmt, va_list ap) __printflike(2, 0);
|
||||
sudo_dso_public int sudo_vasprintf(char **str, const char *fmt, va_list ap) sudo_printflike(2, 0);
|
||||
# undef vasprintf
|
||||
# define vasprintf sudo_vasprintf
|
||||
#endif /* HAVE_VASPRINTF */
|
||||
@ -523,6 +484,11 @@ sudo_dso_public size_t sudo_strnlen(const char *str, size_t maxlen);
|
||||
# undef strnlen
|
||||
# define strnlen(_a, _b) sudo_strnlen((_a), (_b))
|
||||
#endif /* HAVE_STRNLEN */
|
||||
#ifndef HAVE_FCHOWNAT
|
||||
sudo_dso_public int sudo_fchownat(int dfd, const char *path, uid_t uid, gid_t gid, int flag);
|
||||
# undef fchownat
|
||||
# define fchownat(_a, _b, _c, _d, _e) sudo_fchownat((_a), (_b), (_c), (_d), (_e))
|
||||
#endif /* HAVE_FCHOWNAT */
|
||||
#ifndef HAVE_MEMRCHR
|
||||
sudo_dso_public void *sudo_memrchr(const void *s, int c, size_t n);
|
||||
# undef memrchr
|
||||
@ -533,14 +499,30 @@ sudo_dso_public int sudo_mkdirat(int dfd, const char *path, mode_t mode);
|
||||
# undef mkdirat
|
||||
# define mkdirat(_a, _b, _c) sudo_mkdirat((_a), (_b), (_c))
|
||||
#endif /* HAVE_MKDIRAT */
|
||||
#if !defined(HAVE_MKDTEMP) || !defined(HAVE_MKSTEMPS)
|
||||
#if !defined(HAVE_MKDTEMPAT) || !defined(HAVE_MKOSTEMPSAT)
|
||||
# if defined(HAVE_MKDTEMPAT_NP) && defined(HAVE_MKOSTEMPSAT_NP)
|
||||
# undef mkdtempat
|
||||
# define mkdtempat mkdtempat_np
|
||||
# undef mkostempsat
|
||||
# define mkostempsat mkostempsat_np
|
||||
# else
|
||||
sudo_dso_public char *sudo_mkdtemp(char *path);
|
||||
# undef mkdtemp
|
||||
# define mkdtemp(_a) sudo_mkdtemp((_a))
|
||||
# undef mkdtemp
|
||||
# define mkdtemp(_a) sudo_mkdtemp((_a))
|
||||
sudo_dso_public char *sudo_mkdtempat(int dfd, char *path);
|
||||
# undef mkdtempat
|
||||
# define mkdtempat(_a, _b) sudo_mkdtempat((_a), (_b))
|
||||
sudo_dso_public int sudo_mkostempsat(int dfd, char *path, int slen, int flags);
|
||||
# undef mkostempsat
|
||||
# define mkostempsat(_a, _b, _c, _d) sudo_mkostempsat((_a), (_b), (_c), (_d))
|
||||
sudo_dso_public int sudo_mkstemp(char *path);
|
||||
# undef mkstemp
|
||||
# define mkstemp(_a) sudo_mkstemp((_a))
|
||||
sudo_dso_public int sudo_mkstemps(char *path, int slen);
|
||||
# undef mkstemps
|
||||
# define mkstemps(_a, _b) sudo_mkstemps((_a), (_b))
|
||||
#endif /* !HAVE_MKDTEMP || !HAVE_MKSTEMPS */
|
||||
# undef mkstemps
|
||||
# define mkstemps(_a, _b) sudo_mkstemps((_a), (_b))
|
||||
# endif /* HAVE_MKDTEMPAT_NP || HAVE_MKOSTEMPSAT_NP */
|
||||
#endif /* !HAVE_MKDTEMPAT || !HAVE_MKOSTEMPSAT */
|
||||
#ifndef HAVE_NANOSLEEP
|
||||
sudo_dso_public int sudo_nanosleep(const struct timespec *timeout, struct timespec *remainder);
|
||||
#undef nanosleep
|
||||
|
@ -265,13 +265,13 @@ sudo_dso_public int sudo_debug_get_active_instance_v1(void);
|
||||
sudo_dso_public int sudo_debug_get_fds_v1(unsigned char **fds);
|
||||
sudo_dso_public int sudo_debug_get_instance_v1(const char *program);
|
||||
sudo_dso_public int sudo_debug_parse_flags_v1(struct sudo_conf_debug_file_list *debug_files, const char *entry);
|
||||
sudo_dso_public void sudo_debug_printf2_v1(const char *func, const char *file, int line, int level, const char *fmt, ...) __printf0like(5, 6);
|
||||
sudo_dso_public void sudo_debug_printf_nvm_v1(int pri, const char *fmt, ...) __printf0like(2, 3);
|
||||
sudo_dso_public void sudo_debug_printf2_v1(const char *func, const char *file, int line, int level, const char *fmt, ...) sudo_printf0like(5, 6);
|
||||
sudo_dso_public void sudo_debug_printf_nvm_v1(int pri, const char *fmt, ...) sudo_printf0like(2, 3);
|
||||
sudo_dso_public int sudo_debug_register_v1(const char *program, const char *const subsystems[], unsigned int ids[], struct sudo_conf_debug_file_list *debug_files);
|
||||
sudo_dso_public int sudo_debug_register_v2(const char *program, const char *const subsystems[], unsigned int ids[], struct sudo_conf_debug_file_list *debug_files, int minfd);
|
||||
sudo_dso_public int sudo_debug_set_active_instance_v1(int inst);
|
||||
sudo_dso_public void sudo_debug_update_fd_v1(int ofd, int nfd);
|
||||
sudo_dso_public void sudo_debug_vprintf2_v1(const char *func, const char *file, int line, int level, const char *fmt, va_list ap) __printf0like(5, 0);
|
||||
sudo_dso_public void sudo_debug_vprintf2_v1(const char *func, const char *file, int line, int level, const char *fmt, va_list ap) sudo_printf0like(5, 0);
|
||||
sudo_dso_public void sudo_debug_write2_v1(int fd, const char *func, const char *file, int line, const char *str, int len, int errnum);
|
||||
sudo_dso_public bool sudo_debug_needed_v1(int level);
|
||||
|
||||
|
@ -192,6 +192,9 @@ sudo_dso_public bool sudo_ev_got_break_v1(struct sudo_event_base *base);
|
||||
/* Return the base an event is associated with or NULL. */
|
||||
#define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
|
||||
|
||||
/* Set the base an event is associated with. */
|
||||
#define sudo_ev_set_base(_ev, _b) ((_ev)->base = (_b))
|
||||
|
||||
/* Magic pointer value to use self pointer as callback arg. */
|
||||
#define sudo_ev_self_cbarg() ((void *)-1)
|
||||
|
||||
|
@ -132,7 +132,7 @@ bool eventlog_accept(const struct eventlog *evlog, int flags, eventlog_json_call
|
||||
bool eventlog_exit(const struct eventlog *evlog, int flags);
|
||||
bool eventlog_alert(const struct eventlog *evlog, int flags, struct timespec *alert_time, const char *reason, const char *errstr);
|
||||
bool eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_json_callback_t info_cb, void *info);
|
||||
bool eventlog_store_json(struct json_container *json, const struct eventlog *evlog);
|
||||
bool eventlog_store_json(struct json_container *jsonc, const struct eventlog *evlog);
|
||||
size_t eventlog_writeln(FILE *fp, char *line, size_t len, size_t maxlen);
|
||||
void eventlog_free(struct eventlog *evlog);
|
||||
void eventlog_set_type(int type);
|
||||
|
@ -164,20 +164,20 @@ typedef bool (*sudo_warn_setlocale_t)(bool, int *);
|
||||
|
||||
sudo_dso_public int sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func);
|
||||
sudo_dso_public int sudo_fatal_callback_register_v1(sudo_fatal_callback_t func);
|
||||
sudo_dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgid) __format_arg(2);
|
||||
sudo_dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgid) sudo_attr_fmt_arg(2);
|
||||
sudo_dso_public void sudo_warn_set_locale_func_v1(sudo_warn_setlocale_t func);
|
||||
sudo_dso_public void sudo_fatal_nodebug_v1(const char *fmt, ...) __printf0like(1, 2) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_fatalx_nodebug_v1(const char *fmt, ...) __printflike(1, 2) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0) __attribute__((__noreturn__));
|
||||
sudo_dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) __printf0like(1, 2);
|
||||
sudo_dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) __printflike(1, 2);
|
||||
sudo_dso_public void sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3);
|
||||
sudo_dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0);
|
||||
sudo_dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0);
|
||||
sudo_dso_public void sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0);
|
||||
sudo_dso_public sudo_noreturn void sudo_fatal_nodebug_v1(const char *fmt, ...) sudo_printf0like(1, 2);
|
||||
sudo_dso_public sudo_noreturn void sudo_fatalx_nodebug_v1(const char *fmt, ...) sudo_printflike(1, 2);
|
||||
sudo_dso_public sudo_noreturn void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) sudo_printflike(2, 3);
|
||||
sudo_dso_public sudo_noreturn void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) sudo_printf0like(1, 0);
|
||||
sudo_dso_public sudo_noreturn void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) sudo_printflike(1, 0);
|
||||
sudo_dso_public sudo_noreturn void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) sudo_printflike(2, 0);
|
||||
sudo_dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) sudo_printf0like(1, 2);
|
||||
sudo_dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) sudo_printflike(1, 2);
|
||||
sudo_dso_public void sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) sudo_printflike(2, 3);
|
||||
sudo_dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) sudo_printf0like(1, 0);
|
||||
sudo_dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) sudo_printflike(1, 0);
|
||||
sudo_dso_public void sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) sudo_printflike(2, 0);
|
||||
sudo_dso_public void sudo_warn_set_conversation_v1(sudo_conv_t conv);
|
||||
|
||||
#define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a))
|
||||
|
@ -95,7 +95,7 @@ struct iolog_path_escape {
|
||||
};
|
||||
|
||||
/* host_port.c */
|
||||
bool iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp, char *defport, char *defport_tls);
|
||||
bool iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp, const char *defport, const char *defport_tls);
|
||||
|
||||
/* iolog_path.c */
|
||||
bool expand_iolog_path(const char *inpath, char *path, size_t pathlen, const struct iolog_path_escape *escapes, void *closure);
|
||||
@ -143,10 +143,10 @@ void iolog_set_maxseq(unsigned int maxval);
|
||||
void iolog_set_mode(mode_t mode);
|
||||
void iolog_set_owner(uid_t uid, uid_t gid);
|
||||
bool iolog_swapids(bool restore);
|
||||
bool iolog_mkdirs(char *path);
|
||||
bool iolog_mkdirs(const char *path);
|
||||
|
||||
/* iolog_filter.c */
|
||||
void *iolog_pwfilt_alloc();
|
||||
void *iolog_pwfilt_alloc(void);
|
||||
bool iolog_pwfilt_add(void *handle, const char *pattern);
|
||||
void iolog_pwfilt_free(void *handle);
|
||||
bool iolog_pwfilt_remove(void *handle, const char *pattern);
|
||||
|
@ -65,34 +65,34 @@ struct json_container {
|
||||
bool need_comma;
|
||||
};
|
||||
|
||||
sudo_dso_public bool sudo_json_init_v1(struct json_container *json, int indent, bool minimal, bool memfatal);
|
||||
sudo_dso_public bool sudo_json_init_v1(struct json_container *jsonc, int indent, bool minimal, bool memfatal);
|
||||
#define sudo_json_init(_a, _b, _c, _d) sudo_json_init_v1((_a), (_b), (_c), (_d))
|
||||
|
||||
sudo_dso_public void sudo_json_free_v1(struct json_container *json);
|
||||
sudo_dso_public void sudo_json_free_v1(struct json_container *jsonc);
|
||||
#define sudo_json_free(_a) sudo_json_free_v1((_a))
|
||||
|
||||
sudo_dso_public bool sudo_json_open_object_v1(struct json_container *json, const char *name);
|
||||
sudo_dso_public bool sudo_json_open_object_v1(struct json_container *jsonc, const char *name);
|
||||
#define sudo_json_open_object(_a, _b) sudo_json_open_object_v1((_a), (_b))
|
||||
|
||||
sudo_dso_public bool sudo_json_close_object_v1(struct json_container *json);
|
||||
sudo_dso_public bool sudo_json_close_object_v1(struct json_container *jsonc);
|
||||
#define sudo_json_close_object(_a) sudo_json_close_object_v1((_a))
|
||||
|
||||
sudo_dso_public bool sudo_json_open_array_v1(struct json_container *json, const char *name);
|
||||
sudo_dso_public bool sudo_json_open_array_v1(struct json_container *jsonc, const char *name);
|
||||
#define sudo_json_open_array(_a, _b) sudo_json_open_array_v1((_a), (_b))
|
||||
|
||||
sudo_dso_public bool sudo_json_close_array_v1(struct json_container *json);
|
||||
sudo_dso_public bool sudo_json_close_array_v1(struct json_container *jsonc);
|
||||
#define sudo_json_close_array(_a) sudo_json_close_array_v1((_a))
|
||||
|
||||
sudo_dso_public bool sudo_json_add_value_v1(struct json_container *json, const char *name, struct json_value *value);
|
||||
sudo_dso_public bool sudo_json_add_value_v1(struct json_container *jsonc, const char *name, struct json_value *value);
|
||||
#define sudo_json_add_value(_a, _b, _c) sudo_json_add_value_v1((_a), (_b), (_c))
|
||||
|
||||
sudo_dso_public bool sudo_json_add_value_as_object_v1(struct json_container *json, const char *name, struct json_value *value);
|
||||
sudo_dso_public bool sudo_json_add_value_as_object_v1(struct json_container *jsonc, const char *name, struct json_value *value);
|
||||
#define sudo_json_add_value_as_object(_a, _b, _c) sudo_json_add_value_as_object_v1((_a), (_b), (_c))
|
||||
|
||||
sudo_dso_public char *sudo_json_get_buf_v1(struct json_container *json);
|
||||
sudo_dso_public char *sudo_json_get_buf_v1(struct json_container *jsonc);
|
||||
#define sudo_json_get_buf(_a) sudo_json_get_buf_v1((_a))
|
||||
|
||||
sudo_dso_public unsigned int sudo_json_get_len_v1(struct json_container *json);
|
||||
sudo_dso_public unsigned int sudo_json_get_len_v1(struct json_container *jsonc);
|
||||
#define sudo_json_get_len(_a) sudo_json_get_len_v1((_a))
|
||||
|
||||
#endif /* SUDO_JSON_H */
|
||||
|
@ -38,8 +38,8 @@ typedef int (*sudo_lbuf_output_t)(const char *);
|
||||
|
||||
sudo_dso_public void sudo_lbuf_init_v1(struct sudo_lbuf *lbuf, sudo_lbuf_output_t output, int indent, const char *continuation, int cols);
|
||||
sudo_dso_public void sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf);
|
||||
sudo_dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) __printflike(2, 3);
|
||||
sudo_dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) __printflike(3, 4);
|
||||
sudo_dso_public bool sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) sudo_printflike(2, 3);
|
||||
sudo_dso_public bool sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) sudo_printflike(3, 4);
|
||||
sudo_dso_public void sudo_lbuf_print_v1(struct sudo_lbuf *lbuf);
|
||||
sudo_dso_public bool sudo_lbuf_error_v1(struct sudo_lbuf *lbuf);
|
||||
sudo_dso_public void sudo_lbuf_clearerr_v1(struct sudo_lbuf *lbuf);
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
/* API version major/minor */
|
||||
#define SUDO_API_VERSION_MAJOR 1
|
||||
#define SUDO_API_VERSION_MINOR 19
|
||||
#define SUDO_API_VERSION_MINOR 20
|
||||
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
|
||||
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
||||
|
||||
@ -165,7 +165,7 @@ struct policy_plugin {
|
||||
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||
char * const user_info[], char * const user_env[],
|
||||
char * const plugin_options[], const char **errstr);
|
||||
void (*close)(int exit_status, int error); /* wait status or error */
|
||||
@ -174,9 +174,9 @@ struct policy_plugin {
|
||||
char *env_add[], char **command_info[],
|
||||
char **argv_out[], char **user_env_out[], const char **errstr);
|
||||
int (*list)(int argc, char * const argv[], int verbose,
|
||||
const char *list_user, const char **errstr);
|
||||
const char *user, const char **errstr);
|
||||
int (*validate)(const char **errstr);
|
||||
void (*invalidate)(int remove);
|
||||
void (*invalidate)(int rmcred);
|
||||
int (*init_session)(struct passwd *pwd, char **user_env_out[],
|
||||
const char **errstr);
|
||||
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
|
||||
@ -190,7 +190,7 @@ struct io_plugin {
|
||||
unsigned int type; /* always SUDO_IO_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||
char * const user_info[], char * const command_info[],
|
||||
int argc, char * const argv[], char * const user_env[],
|
||||
char * const plugin_options[], const char **errstr);
|
||||
@ -223,7 +223,7 @@ struct audit_plugin {
|
||||
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const plugin_options[], const char **errstr);
|
||||
@ -249,7 +249,7 @@ struct approval_plugin {
|
||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||
unsigned int version; /* always SUDO_API_VERSION */
|
||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t sudo_printf, char * const settings[],
|
||||
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||
char * const user_info[], int submit_optind,
|
||||
char * const submit_argv[], char * const submit_envp[],
|
||||
char * const plugin_options[], const char **errstr);
|
||||
@ -279,7 +279,8 @@ struct approval_plugin {
|
||||
*/
|
||||
struct sudoers_group_plugin {
|
||||
unsigned int version;
|
||||
int (*init)(int version, sudo_printf_t sudo_printf, char *const argv[]);
|
||||
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||
char *const argv[]);
|
||||
void (*cleanup)(void);
|
||||
int (*query)(const char *user, const char *group, const struct passwd *pwd);
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2013-2018 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2013-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -247,6 +247,24 @@ sudo_dso_public const char *sudo_logpri2str_v1(int num);
|
||||
/* mkdir_parents.c */
|
||||
sudo_dso_public bool sudo_mkdir_parents_v1(const char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
||||
#define sudo_mkdir_parents(_a, _b, _c, _d, _e) sudo_mkdir_parents_v1((_a), (_b), (_c), (_d), (_e))
|
||||
sudo_dso_public int sudo_open_parent_dir_v1(const char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet);
|
||||
#define sudo_open_parent_dir(_a, _b, _c, _d, _e) sudo_open_parent_dir_v1((_a), (_b), (_c), (_d), (_e))
|
||||
|
||||
/* mmap_alloc.c */
|
||||
sudo_dso_public void *sudo_mmap_alloc_v1(size_t size) sudo_malloclike;
|
||||
#define sudo_mmap_alloc(_a) sudo_mmap_alloc_v1(_a)
|
||||
sudo_dso_public void *sudo_mmap_allocarray_v1(size_t count, size_t size) sudo_malloclike;
|
||||
#define sudo_mmap_allocarray(_a, _b) sudo_mmap_allocarray_v1((_a), (_b))
|
||||
sudo_dso_public char *sudo_mmap_strdup_v1(const char *str);
|
||||
#define sudo_mmap_strdup(_a) sudo_mmap_strdup_v1(_a)
|
||||
sudo_dso_public void sudo_mmap_free_v1(void *ptr);
|
||||
#define sudo_mmap_free(_a) sudo_mmap_free_v1(_a)
|
||||
sudo_dso_public int sudo_mmap_protect_v1(void *ptr);
|
||||
#define sudo_mmap_protect(_a) sudo_mmap_protect_v1(_a)
|
||||
|
||||
/* multiarch.c */
|
||||
sudo_dso_public char *sudo_stat_multiarch_v1(const char *path, struct stat *sb);
|
||||
#define sudo_stat_multiarch(_a, _b) sudo_stat_multiarch_v1((_a), (_b))
|
||||
|
||||
/* parseln.c */
|
||||
sudo_dso_public ssize_t sudo_parseln_v1(char **buf, size_t *bufsize, unsigned int *lineno, FILE *fp);
|
||||
@ -259,7 +277,7 @@ sudo_dso_public void initprogname2(const char *, const char * const *);
|
||||
|
||||
/* rcstr.c */
|
||||
sudo_dso_public char *sudo_rcstr_dup(const char *src);
|
||||
sudo_dso_public char *sudo_rcstr_alloc(size_t len);
|
||||
sudo_dso_public char *sudo_rcstr_alloc(size_t len) sudo_malloclike;
|
||||
sudo_dso_public char *sudo_rcstr_addref(const char *s);
|
||||
sudo_dso_public void sudo_rcstr_delref(const char *s);
|
||||
|
||||
@ -279,10 +297,14 @@ sudo_dso_public unsigned int sudo_pow2_roundup_v1(unsigned int len);
|
||||
#define SUDO_PATH_WORLD_WRITABLE -4
|
||||
#define SUDO_PATH_GROUP_WRITABLE -5
|
||||
struct stat;
|
||||
sudo_dso_public int sudo_secure_dir_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp);
|
||||
sudo_dso_public int sudo_secure_dir_v1(const char *path, uid_t uid, gid_t gid, struct stat *sb);
|
||||
#define sudo_secure_dir(_a, _b, _c, _d) sudo_secure_dir_v1((_a), (_b), (_c), (_d))
|
||||
sudo_dso_public int sudo_secure_file_v1(const char *path, uid_t uid, gid_t gid, struct stat *sbp);
|
||||
sudo_dso_public int sudo_secure_file_v1(const char *path, uid_t uid, gid_t gid, struct stat *sb);
|
||||
#define sudo_secure_file(_a, _b, _c, _d) sudo_secure_file_v1((_a), (_b), (_c), (_d))
|
||||
sudo_dso_public int sudo_secure_open_file_v1(const char *path, uid_t uid, gid_t gid, struct stat *sb, int *error);
|
||||
#define sudo_secure_open_file(_a, _b, _c, _d, _e) sudo_secure_open_file_v1((_a), (_b), (_c), (_d), (_e))
|
||||
sudo_dso_public int sudo_secure_open_dir_v1(const char *path, uid_t uid, gid_t gid, struct stat *sb, int *error);
|
||||
#define sudo_secure_open_dir(_a, _b, _c, _d, _e) sudo_secure_open_dir_v1((_a), (_b), (_c), (_d), (_e))
|
||||
|
||||
/* setgroups.c */
|
||||
sudo_dso_public int sudo_setgroups_v1(int ngids, const GETGROUPS_T *gids);
|
||||
@ -299,6 +321,8 @@ sudo_dso_public int sudo_strtobool_v1(const char *str);
|
||||
/* strtonum.c */
|
||||
/* Not versioned for historical reasons. */
|
||||
sudo_dso_public long long sudo_strtonum(const char *, long long, long long, const char **);
|
||||
/* Not currently exported. */
|
||||
long long sudo_strtonumx(const char *str, long long minval, long long maxval, char **endp, const char **errstrp);
|
||||
|
||||
/* strtoid.c */
|
||||
sudo_dso_public id_t sudo_strtoid_v1(const char *str, const char *sep, char **endp, const char **errstr);
|
||||
@ -325,6 +349,8 @@ sudo_dso_public bool sudo_term_raw_v1(int fd, int isig);
|
||||
#define sudo_term_raw(_a, _b) sudo_term_raw_v1((_a), (_b))
|
||||
sudo_dso_public bool sudo_term_restore_v1(int fd, bool flush);
|
||||
#define sudo_term_restore(_a, _b) sudo_term_restore_v1((_a), (_b))
|
||||
sudo_dso_public bool sudo_term_is_raw_v1(int fd);
|
||||
#define sudo_term_is_raw(_a) sudo_term_is_raw_v1((_a))
|
||||
|
||||
/* ttyname_dev.c */
|
||||
sudo_dso_public char *sudo_ttyname_dev_v1(dev_t tdev, char *name, size_t namelen);
|
||||
|
@ -33,6 +33,7 @@ incdir = $(top_srcdir)/include
|
||||
# Compiler & tools to use
|
||||
CC = @CC@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
GREP = @GREP@
|
||||
|
||||
# C preprocessor flags
|
||||
CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
|
||||
@ -93,11 +94,6 @@ CHECK_WRAP_OBJS = check_wrap.lo logwrap.lo
|
||||
|
||||
all: libsudo_eventlog.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend:
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/eventlog/Makefile.in
|
||||
@ -147,13 +143,16 @@ cppcheck:
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
fuzz:
|
||||
|
||||
check-fuzzer:
|
||||
|
||||
check: $(TEST_PROGS) check-fuzzer
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
|
@ -349,14 +349,14 @@ closefrom_nodebug(int lowfd)
|
||||
|
||||
#define MAX_MAILFLAGS 63
|
||||
|
||||
static void __attribute__((__noreturn__))
|
||||
static sudo_noreturn void
|
||||
exec_mailer(int pipein)
|
||||
{
|
||||
const struct eventlog_config *evl_conf = eventlog_getconf();
|
||||
char *last, *mflags, *p, *argv[MAX_MAILFLAGS + 1];
|
||||
const char *mpath = evl_conf->mailerpath;
|
||||
int i;
|
||||
char * const root_envp[] = {
|
||||
const char * const root_envp[] = {
|
||||
"HOME=/",
|
||||
"PATH=/usr/bin:/bin:/usr/sbin:/sbin",
|
||||
"LOGNAME=root",
|
||||
@ -409,7 +409,7 @@ exec_mailer(int pipein)
|
||||
}
|
||||
sudo_debug_exit(__func__, __FILE__, __LINE__, sudo_debug_subsys);
|
||||
if (evl_conf->mailuid == ROOT_UID)
|
||||
execve(mpath, argv, root_envp);
|
||||
execve(mpath, argv, (char **)root_envp);
|
||||
else
|
||||
execv(mpath, argv);
|
||||
syslog(LOG_ERR, _("unable to execute %s: %m"), mpath); // -V618
|
||||
@ -627,24 +627,24 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
||||
}
|
||||
|
||||
static bool
|
||||
json_add_timestamp(struct json_container *json, const char *name,
|
||||
json_add_timestamp(struct json_container *jsonc, const char *name,
|
||||
const struct timespec *ts, bool format_timestamp)
|
||||
{
|
||||
struct json_value json_value;
|
||||
int len;
|
||||
debug_decl(json_add_timestamp, SUDO_DEBUG_PLUGIN);
|
||||
|
||||
if (!sudo_json_open_object(json, name))
|
||||
if (!sudo_json_open_object(jsonc, name))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = ts->tv_sec;
|
||||
if (!sudo_json_add_value(json, "seconds", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "seconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = ts->tv_nsec;
|
||||
if (!sudo_json_add_value(json, "nanoseconds", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "nanoseconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (format_timestamp) {
|
||||
@ -660,7 +660,7 @@ json_add_timestamp(struct json_container *json, const char *name,
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = timebuf; // -V507
|
||||
if (!sudo_json_add_value(json, "iso8601", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "iso8601", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
}
|
||||
@ -671,13 +671,13 @@ json_add_timestamp(struct json_container *json, const char *name,
|
||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = timebuf; // -V507
|
||||
if (!sudo_json_add_value(json, "localtime", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "localtime", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sudo_json_close_object(json))
|
||||
if (!sudo_json_close_object(jsonc))
|
||||
goto oom;
|
||||
|
||||
debug_return_bool(true);
|
||||
@ -693,7 +693,7 @@ oom:
|
||||
* be stored and formatted by the caller.
|
||||
*/
|
||||
bool
|
||||
eventlog_store_json(struct json_container *json, const struct eventlog *evlog)
|
||||
eventlog_store_json(struct json_container *jsonc, const struct eventlog *evlog)
|
||||
{
|
||||
struct json_value json_value;
|
||||
size_t i;
|
||||
@ -712,112 +712,112 @@ eventlog_store_json(struct json_container *json, const struct eventlog *evlog)
|
||||
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->submituser;
|
||||
if (!sudo_json_add_value(json, "submituser", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "submituser", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (evlog->command != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->command;
|
||||
if (!sudo_json_add_value(json, "command", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "command", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->runuser != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->runuser;
|
||||
if (!sudo_json_add_value(json, "runuser", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "runuser", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->rungroup != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->rungroup;
|
||||
if (!sudo_json_add_value(json, "rungroup", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "rungroup", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->runchroot != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->runchroot;
|
||||
if (!sudo_json_add_value(json, "runchroot", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "runchroot", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->runcwd != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->runcwd;
|
||||
if (!sudo_json_add_value(json, "runcwd", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "runcwd", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->ttyname != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->ttyname;
|
||||
if (!sudo_json_add_value(json, "ttyname", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "ttyname", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->submithost != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->submithost;
|
||||
if (!sudo_json_add_value(json, "submithost", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "submithost", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->cwd != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->cwd;
|
||||
if (!sudo_json_add_value(json, "submitcwd", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "submitcwd", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->rungroup!= NULL && evlog->rungid != (gid_t)-1) {
|
||||
json_value.type = JSON_ID;
|
||||
json_value.u.id = evlog->rungid;
|
||||
if (!sudo_json_add_value(json, "rungid", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "rungid", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->runuid != (uid_t)-1) {
|
||||
json_value.type = JSON_ID;
|
||||
json_value.u.id = evlog->runuid;
|
||||
if (!sudo_json_add_value(json, "runuid", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "runuid", &json_value))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = evlog->columns;
|
||||
if (!sudo_json_add_value(json, "columns", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "columns", &json_value))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = evlog->lines;
|
||||
if (!sudo_json_add_value(json, "lines", &json_value))
|
||||
if (!sudo_json_add_value(jsonc, "lines", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (evlog->argv != NULL) {
|
||||
if (!sudo_json_open_array(json, "runargv"))
|
||||
if (!sudo_json_open_array(jsonc, "runargv"))
|
||||
goto oom;
|
||||
for (i = 0; (cp = evlog->argv[i]) != NULL; i++) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = cp;
|
||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||
goto oom;
|
||||
}
|
||||
if (!sudo_json_close_array(json))
|
||||
if (!sudo_json_close_array(jsonc))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (evlog->envp != NULL) {
|
||||
if (!sudo_json_open_array(json, "runenv"))
|
||||
if (!sudo_json_open_array(jsonc, "runenv"))
|
||||
goto oom;
|
||||
for (i = 0; (cp = evlog->envp[i]) != NULL; i++) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = cp;
|
||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||
goto oom;
|
||||
}
|
||||
if (!sudo_json_close_array(json))
|
||||
if (!sudo_json_close_array(jsonc))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
@ -829,9 +829,9 @@ oom:
|
||||
}
|
||||
|
||||
static bool
|
||||
default_json_cb(struct json_container *json, void *v)
|
||||
default_json_cb(struct json_container *jsonc, void *v)
|
||||
{
|
||||
return eventlog_store_json(json, v);
|
||||
return eventlog_store_json(jsonc, v);
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -840,7 +840,7 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
{
|
||||
eventlog_json_callback_t info_cb = args->json_info_cb;
|
||||
void *info = args->json_info;
|
||||
struct json_container json = { 0 };
|
||||
struct json_container jsonc = { 0 };
|
||||
struct json_value json_value;
|
||||
const char *time_str, *type_str;
|
||||
struct timespec now;
|
||||
@ -880,15 +880,15 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
debug_return_str(NULL);
|
||||
}
|
||||
|
||||
if (!sudo_json_init(&json, 4, compact, false))
|
||||
if (!sudo_json_init(&jsonc, 4, compact, false))
|
||||
goto bad;
|
||||
if (!sudo_json_open_object(&json, type_str))
|
||||
if (!sudo_json_open_object(&jsonc, type_str))
|
||||
goto bad;
|
||||
|
||||
if (evlog != NULL && evlog->uuid_str[0] != '\0') {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->uuid_str;
|
||||
if (!sudo_json_add_value(&json, "uuid", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "uuid", &json_value))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -907,7 +907,7 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
}
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = ereason ? ereason : args->reason;
|
||||
if (!sudo_json_add_value(&json, "reason", &json_value)) {
|
||||
if (!sudo_json_add_value(&jsonc, "reason", &json_value)) {
|
||||
free(ereason);
|
||||
goto bad;
|
||||
}
|
||||
@ -915,7 +915,7 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
}
|
||||
|
||||
/* Log event time on server (set earlier) */
|
||||
if (!json_add_timestamp(&json, "server_time", &now, true)) {
|
||||
if (!json_add_timestamp(&jsonc, "server_time", &now, true)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable format timestamp");
|
||||
goto bad;
|
||||
@ -923,7 +923,7 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
|
||||
/* Log event time from client */
|
||||
if (args->event_time != NULL) {
|
||||
if (!json_add_timestamp(&json, time_str, args->event_time, true)) {
|
||||
if (!json_add_timestamp(&jsonc, time_str, args->event_time, true)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable format timestamp");
|
||||
goto bad;
|
||||
@ -938,7 +938,7 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
}
|
||||
|
||||
if (sudo_timespecisset(&evlog->run_time)) {
|
||||
if (!json_add_timestamp(&json, "run_time", &evlog->run_time, false)) {
|
||||
if (!json_add_timestamp(&jsonc, "run_time", &evlog->run_time, false)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable format timestamp");
|
||||
goto bad;
|
||||
@ -947,17 +947,17 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
if (evlog->signal_name != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->signal_name;
|
||||
if (!sudo_json_add_value(&json, "signal", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "signal", &json_value))
|
||||
goto bad;
|
||||
|
||||
json_value.type = JSON_BOOL;
|
||||
json_value.u.boolean = evlog->dumped_core;
|
||||
if (!sudo_json_add_value(&json, "dumped_core", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "dumped_core", &json_value))
|
||||
goto bad;
|
||||
}
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = evlog->exit_value;
|
||||
if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "exit_value", &json_value))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@ -966,18 +966,18 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
if (evlog->peeraddr != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->peeraddr;
|
||||
if (!sudo_json_add_value(&json, "peeraddr", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "peeraddr", &json_value))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (evlog->iolog_path != NULL) {
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = evlog->iolog_path;
|
||||
if (!sudo_json_add_value(&json, "iolog_path", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "iolog_path", &json_value))
|
||||
goto bad;
|
||||
|
||||
if (sudo_timespecisset(&evlog->iolog_offset)) {
|
||||
if (!json_add_timestamp(&json, "iolog_offset", &evlog->iolog_offset, false)) {
|
||||
if (!json_add_timestamp(&jsonc, "iolog_offset", &evlog->iolog_offset, false)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable format timestamp");
|
||||
goto bad;
|
||||
@ -988,23 +988,23 @@ format_json(int event_type, struct eventlog_args *args,
|
||||
|
||||
/* Write log info. */
|
||||
if (info != NULL) {
|
||||
if (!info_cb(&json, info))
|
||||
if (!info_cb(&jsonc, info))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!sudo_json_close_object(&json))
|
||||
if (!sudo_json_close_object(&jsonc))
|
||||
goto bad;
|
||||
|
||||
/* Caller is responsible for freeing the buffer. */
|
||||
debug_return_str(sudo_json_get_buf(&json));
|
||||
debug_return_str(sudo_json_get_buf(&jsonc));
|
||||
|
||||
bad:
|
||||
sudo_json_free(&json);
|
||||
sudo_json_free(&jsonc);
|
||||
debug_return_str(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Log a message to syslog, pre-pending the username and splitting the
|
||||
* Log a message to syslog, prepending the username and splitting the
|
||||
* message into parts if it is longer than syslog_maxlen.
|
||||
*/
|
||||
static bool
|
||||
|
@ -35,7 +35,7 @@
|
||||
size_t
|
||||
eventlog_writeln(FILE *fp, char *line, size_t linelen, size_t maxlen)
|
||||
{
|
||||
char *indent = "";
|
||||
const char *indent = "";
|
||||
char *beg = line;
|
||||
char *end;
|
||||
int len;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
|
@ -88,11 +88,6 @@ POBJS = $(IOBJS:.i=.plog)
|
||||
|
||||
all: libsudo_fuzzstub.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend:
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/fuzzstub/Makefile.in
|
||||
@ -139,6 +134,9 @@ cppcheck:
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
fuzz:
|
||||
|
||||
check-fuzzer:
|
||||
|
@ -35,6 +35,7 @@ cross_compiling = @CROSS_COMPILING@
|
||||
CC = @CC@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
SHA1SUM = @SHA1SUM@
|
||||
GREP = @GREP@
|
||||
SED = @SED@
|
||||
|
||||
# Libraries
|
||||
@ -140,11 +141,6 @@ FUZZ_IOLOG_TIMING_CORPUS = $(srcdir)/regress/corpus/seed/timing/timing.*
|
||||
|
||||
all: libsudo_iolog.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend:
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/iolog/Makefile.in
|
||||
@ -204,7 +200,7 @@ fuzz_iolog_json_seed_corpus.zip:
|
||||
rm -rf $$tdir
|
||||
|
||||
run-fuzz_iolog_json: fuzz_iolog_json
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -231,7 +227,7 @@ fuzz_iolog_legacy_seed_corpus.zip:
|
||||
rm -rf $$tdir
|
||||
|
||||
run-fuzz_iolog_legacy: fuzz_iolog_legacy
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -258,7 +254,7 @@ fuzz_iolog_timing_seed_corpus.zip:
|
||||
rm -rf $$tdir
|
||||
|
||||
run-fuzz_iolog_timing: fuzz_iolog_timing
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -305,11 +301,14 @@ cppcheck:
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
fuzz: run-fuzz_iolog_json run-fuzz_iolog_legacy run-fuzz_iolog_timing
|
||||
|
||||
check-fuzzer: $(FUZZ_PROGS)
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -328,7 +327,7 @@ check-fuzzer: $(FUZZ_PROGS)
|
||||
|
||||
check: $(TEST_PROGS) check-fuzzer
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -498,13 +497,15 @@ fuzz_iolog_timing.plog: fuzz_iolog_timing.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/fuzz/fuzz_iolog_timing.c --i-file $< --output-file $@
|
||||
host_port.lo: $(srcdir)/host_port.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/host_port.c
|
||||
host_port.i: $(srcdir)/host_port.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_iolog.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
host_port.plog: host_port.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/host_port.c --i-file $< --output-file $@
|
||||
|
@ -16,7 +16,12 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
@ -30,6 +35,7 @@
|
||||
#include "sudo_debug.h"
|
||||
#include "sudo_gettext.h"
|
||||
#include "sudo_util.h"
|
||||
#include "sudo_iolog.h"
|
||||
|
||||
/*
|
||||
* Parse a string in the form host[:port] where host can also be
|
||||
@ -38,7 +44,7 @@
|
||||
*/
|
||||
bool
|
||||
iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp,
|
||||
char *defport, char *defport_tls)
|
||||
const char *defport, const char *defport_tls)
|
||||
{
|
||||
char *flags, *port, *host = str;
|
||||
bool ret = false;
|
||||
@ -87,7 +93,7 @@ iolog_parse_host_port(char *str, char **hostp, char **portp, bool *tlsp,
|
||||
}
|
||||
|
||||
if (port == NULL)
|
||||
port = tls ? defport_tls : defport;
|
||||
port = tls ? (char *)defport_tls : (char *)defport;
|
||||
else if (*port == '\0')
|
||||
goto done;
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <config.h>
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
# if defined(HAVE_WOLFSSL)
|
||||
@ -188,7 +188,7 @@ matches_common_name(const char *hostname, const char *ipaddr, const X509 *cert,
|
||||
{
|
||||
X509_NAME_ENTRY *common_name_entry = NULL;
|
||||
ASN1_STRING *common_name_asn1 = NULL;
|
||||
int common_name_loc = -1;
|
||||
int common_name_loc;
|
||||
debug_decl(matches_common_name, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Find the position of the CN field in the Subject field of the certificate */
|
||||
@ -268,7 +268,7 @@ matches_subject_alternative_name(const char *hostname, const char *ipaddr, const
|
||||
{
|
||||
HostnameValidationResult result = MatchNotFound;
|
||||
int i;
|
||||
int san_names_nb = -1;
|
||||
int san_names_nb;
|
||||
STACK_OF(GENERAL_NAME) *san_names = NULL;
|
||||
debug_decl(matches_subject_alternative_name, SUDO_DEBUG_UTIL);
|
||||
|
||||
|
@ -153,34 +153,34 @@ iolog_write_info_file_legacy(int dfd, struct eventlog *evlog)
|
||||
static bool
|
||||
iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
||||
{
|
||||
struct json_container json;
|
||||
struct json_container jsonc;
|
||||
struct json_value json_value;
|
||||
bool ret = false;
|
||||
FILE *fp = NULL;
|
||||
int fd = -1;
|
||||
debug_decl(iolog_write_info_file_json, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!sudo_json_init(&json, 4, false, false))
|
||||
if (!sudo_json_init(&jsonc, 4, false, false))
|
||||
debug_return_bool(false);
|
||||
|
||||
/* Timestamp */
|
||||
if (!sudo_json_open_object(&json, "timestamp"))
|
||||
if (!sudo_json_open_object(&jsonc, "timestamp"))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = evlog->submit_time.tv_sec;
|
||||
if (!sudo_json_add_value(&json, "seconds", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "seconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = evlog->submit_time.tv_nsec;
|
||||
if (!sudo_json_add_value(&json, "nanoseconds", &json_value))
|
||||
if (!sudo_json_add_value(&jsonc, "nanoseconds", &json_value))
|
||||
goto oom;
|
||||
|
||||
if (!sudo_json_close_object(&json))
|
||||
if (!sudo_json_close_object(&jsonc))
|
||||
goto oom;
|
||||
|
||||
if (!eventlog_store_json(&json, evlog))
|
||||
if (!eventlog_store_json(&jsonc, evlog))
|
||||
goto done;
|
||||
|
||||
fd = iolog_openat(dfd, "log.json", O_CREAT|O_TRUNC|O_WRONLY);
|
||||
@ -197,7 +197,7 @@ iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
||||
}
|
||||
fd = -1;
|
||||
|
||||
fprintf(fp, "{%s\n}\n", sudo_json_get_buf(&json));
|
||||
fprintf(fp, "{%s\n}\n", sudo_json_get_buf(&jsonc));
|
||||
fflush(fp);
|
||||
if (ferror(fp)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
@ -211,7 +211,7 @@ iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
||||
oom:
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
done:
|
||||
sudo_json_free(&json);
|
||||
sudo_json_free(&jsonc);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (fd != -1)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -46,7 +46,7 @@
|
||||
* Create directory and any parent directories as needed.
|
||||
*/
|
||||
bool
|
||||
iolog_mkdirs(char *path)
|
||||
iolog_mkdirs(const char *path)
|
||||
{
|
||||
const mode_t iolog_filemode = iolog_get_file_mode();
|
||||
const mode_t iolog_dirmode = iolog_get_dir_mode();
|
||||
@ -96,29 +96,33 @@ iolog_mkdirs(char *path)
|
||||
/* umask must not be more restrictive than the file modes. */
|
||||
omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
|
||||
|
||||
ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
|
||||
if (!ok && errno == EACCES) {
|
||||
ok = false;
|
||||
if (dfd != -1)
|
||||
close(dfd);
|
||||
dfd = sudo_open_parent_dir(path, iolog_uid, iolog_gid, iolog_dirmode, true);
|
||||
if (dfd == -1 && errno == EACCES) {
|
||||
/* Try again as the I/O log owner (for NFS). */
|
||||
uid_changed = iolog_swapids(false);
|
||||
if (uid_changed)
|
||||
ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
|
||||
dfd = sudo_open_parent_dir(path, -1, -1, iolog_dirmode, false);
|
||||
}
|
||||
if (ok) {
|
||||
if (dfd != -1) {
|
||||
/* Create final path component. */
|
||||
const char *base = sudo_basename(path);
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
|
||||
"mkdir %s, mode 0%o", path, (unsigned int) iolog_dirmode);
|
||||
ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
|
||||
ok = mkdirat(dfd, base, iolog_dirmode) == 0 || errno == EEXIST;
|
||||
if (!ok) {
|
||||
if (errno == EACCES && !uid_changed) {
|
||||
/* Try again as the I/O log owner (for NFS). */
|
||||
uid_changed = iolog_swapids(false);
|
||||
if (uid_changed)
|
||||
ok = mkdir(path, iolog_dirmode) == 0 || errno == EEXIST;
|
||||
ok = mkdirat(dfd, base, iolog_dirmode) == 0 || errno == EEXIST;
|
||||
}
|
||||
if (!ok)
|
||||
sudo_warn(U_("unable to mkdir %s"), path);
|
||||
} else {
|
||||
if (chown(path, iolog_uid, iolog_gid) != 0) {
|
||||
if (fchownat(dfd, base, iolog_uid, iolog_gid, AT_SYMLINK_NOFOLLOW) != 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||
"%s: unable to chown %d:%d %s", __func__,
|
||||
(int)iolog_uid, (int)iolog_gid, path);
|
||||
|
@ -52,36 +52,40 @@ iolog_mkdtemp(char *path)
|
||||
const mode_t iolog_dirmode = iolog_get_dir_mode();
|
||||
const uid_t iolog_uid = iolog_get_uid();
|
||||
const gid_t iolog_gid = iolog_get_gid();
|
||||
bool ok, uid_changed = false;
|
||||
bool ok = false, uid_changed = false;
|
||||
mode_t omask;
|
||||
int dfd;
|
||||
debug_decl(iolog_mkdtemp, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* umask must not be more restrictive than the file modes. */
|
||||
omask = umask(ACCESSPERMS & ~(iolog_filemode|iolog_dirmode));
|
||||
|
||||
ok = sudo_mkdir_parents(path, iolog_uid, iolog_gid, iolog_dirmode, true);
|
||||
if (!ok && errno == EACCES) {
|
||||
dfd = sudo_open_parent_dir(path, iolog_uid, iolog_gid, iolog_dirmode, true);
|
||||
if (dfd == -1 && errno == EACCES) {
|
||||
/* Try again as the I/O log owner (for NFS). */
|
||||
uid_changed = iolog_swapids(false);
|
||||
if (uid_changed)
|
||||
ok = sudo_mkdir_parents(path, -1, -1, iolog_dirmode, false);
|
||||
dfd = sudo_open_parent_dir(path, -1, -1, iolog_dirmode, false);
|
||||
}
|
||||
if (ok) {
|
||||
if (dfd != -1) {
|
||||
/* Create final path component. */
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
|
||||
"mkdtemp %s", path);
|
||||
/* We cannot retry mkdtemp() so always open as iolog user */
|
||||
if (!uid_changed)
|
||||
uid_changed = iolog_swapids(false);
|
||||
if (mkdtemp(path) == NULL) {
|
||||
if (mkdtempat(dfd, path) == NULL) {
|
||||
sudo_warn(U_("unable to mkdir %s"), path);
|
||||
ok = false;
|
||||
} else {
|
||||
if (chmod(path, iolog_dirmode) != 0) {
|
||||
/* Not a fatal error, pre-existing mode is 0700. */
|
||||
sudo_warn(U_("unable to change mode of %s to 0%o"),
|
||||
path, (unsigned int)iolog_dirmode);
|
||||
}
|
||||
ok = true;
|
||||
}
|
||||
close(dfd);
|
||||
}
|
||||
|
||||
umask(omask);
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
#include "iolog_json.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
|
||||
static FILE *
|
||||
open_data(const uint8_t *data, size_t size)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "sudo_plugin.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
|
||||
static FILE *
|
||||
open_data(const uint8_t *data, size_t size)
|
||||
{
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "sudo_plugin.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
|
||||
static int
|
||||
fuzz_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
||||
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
|
||||
|
@ -45,8 +45,8 @@ struct host_port_test {
|
||||
const char *host; /* parsed host */
|
||||
const char *port; /* parsed port */
|
||||
bool tls; /* parsed TLS flag */
|
||||
char *defport; /* default port */
|
||||
char *defport_tls; /* default port */
|
||||
const char *defport; /* default port */
|
||||
const char *defport_tls; /* default port */
|
||||
bool ret; /* return value */
|
||||
};
|
||||
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
sudo_dso_public int main(int argc, char *argv[]);
|
||||
|
||||
bool
|
||||
json_print_object(struct json_container *json, struct json_object *object)
|
||||
static bool
|
||||
json_print_object(struct json_container *jsonc, struct json_object *object)
|
||||
{
|
||||
struct json_item *item;
|
||||
struct json_value json_value;
|
||||
@ -46,40 +46,40 @@ json_print_object(struct json_container *json, struct json_object *object)
|
||||
case JSON_STRING:
|
||||
json_value.type = JSON_STRING;
|
||||
json_value.u.string = item->u.string;
|
||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||
goto oom;
|
||||
break;
|
||||
case JSON_NUMBER:
|
||||
json_value.type = JSON_NUMBER;
|
||||
json_value.u.number = item->u.number;
|
||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||
goto oom;
|
||||
break;
|
||||
case JSON_OBJECT:
|
||||
if (!sudo_json_open_object(json, item->name))
|
||||
if (!sudo_json_open_object(jsonc, item->name))
|
||||
goto oom;
|
||||
if (!json_print_object(json, &item->u.child))
|
||||
if (!json_print_object(jsonc, &item->u.child))
|
||||
goto done;
|
||||
if (!sudo_json_close_object(json))
|
||||
if (!sudo_json_close_object(jsonc))
|
||||
goto oom;
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
if (!sudo_json_open_array(json, item->name))
|
||||
if (!sudo_json_open_array(jsonc, item->name))
|
||||
goto oom;
|
||||
if (!json_print_object(json, &item->u.child))
|
||||
if (!json_print_object(jsonc, &item->u.child))
|
||||
goto done;
|
||||
if (!sudo_json_close_array(json))
|
||||
if (!sudo_json_close_array(jsonc))
|
||||
goto oom;
|
||||
break;
|
||||
case JSON_BOOL:
|
||||
json_value.type = JSON_BOOL;
|
||||
json_value.u.boolean = item->u.boolean;
|
||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||
goto oom;
|
||||
break;
|
||||
case JSON_NULL:
|
||||
json_value.type = JSON_NULL;
|
||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
||||
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||
goto oom;
|
||||
break;
|
||||
default:
|
||||
@ -98,7 +98,7 @@ done:
|
||||
}
|
||||
|
||||
static bool
|
||||
json_format(struct json_container *json, struct json_object *object)
|
||||
json_format(struct json_container *jsonc, struct json_object *object)
|
||||
{
|
||||
struct json_item *item;
|
||||
bool ret = false;
|
||||
@ -111,7 +111,7 @@ json_format(struct json_container *json, struct json_object *object)
|
||||
}
|
||||
object = &item->u.child;
|
||||
|
||||
if (!json_print_object(json, object))
|
||||
if (!json_print_object(jsonc, object))
|
||||
goto done;
|
||||
|
||||
ret = true;
|
||||
@ -129,7 +129,7 @@ usage(void)
|
||||
}
|
||||
|
||||
static bool
|
||||
compare(FILE *fp, const char *infile, struct json_container *json)
|
||||
compare(FILE *fp, const char *infile, struct json_container *jsonc)
|
||||
{
|
||||
const char *cp;
|
||||
unsigned int lineno = 0;
|
||||
@ -137,7 +137,7 @@ compare(FILE *fp, const char *infile, struct json_container *json)
|
||||
char *line = NULL;
|
||||
ssize_t len;
|
||||
|
||||
cp = sudo_json_get_buf(json);
|
||||
cp = sudo_json_get_buf(jsonc);
|
||||
|
||||
while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
|
||||
lineno++;
|
||||
@ -192,7 +192,7 @@ main(int argc, char *argv[])
|
||||
usage();
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
struct json_container json;
|
||||
struct json_container jsonc;
|
||||
const char *infile = argv[i];
|
||||
const char *outfile = argv[i];
|
||||
const char *cp;
|
||||
@ -202,7 +202,7 @@ main(int argc, char *argv[])
|
||||
|
||||
ntests++;
|
||||
|
||||
if (!sudo_json_init(&json, 4, false, true)) {
|
||||
if (!sudo_json_init(&jsonc, 4, false, true)) {
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
@ -219,7 +219,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Format as pretty-printed JSON */
|
||||
if (!json_format(&json, &root)) {
|
||||
if (!json_format(&jsonc, &root)) {
|
||||
errors++;
|
||||
goto next;
|
||||
}
|
||||
@ -237,18 +237,18 @@ main(int argc, char *argv[])
|
||||
|
||||
/* Compare output to expected output. */
|
||||
rewind(outfp);
|
||||
if (!compare(outfp, outfile, &json))
|
||||
if (!compare(outfp, outfile, &jsonc))
|
||||
errors++;
|
||||
|
||||
/* Write the formatted output to stdout for -c (cat) */
|
||||
if (cat) {
|
||||
fprintf(stdout, "{%s\n}\n", sudo_json_get_buf(&json));
|
||||
fprintf(stdout, "{%s\n}\n", sudo_json_get_buf(&jsonc));
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
next:
|
||||
free_json_items(&root.items);
|
||||
sudo_json_free(&json);
|
||||
sudo_json_free(&jsonc);
|
||||
if (infp != NULL)
|
||||
fclose(infp);
|
||||
if (outfp != NULL && outfp != infp)
|
||||
|
@ -66,7 +66,7 @@ int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char testdir[] = "mkpath.XXXXXX";
|
||||
char *rmargs[] = { "rm", "-rf", NULL, NULL };
|
||||
const char *rmargs[] = { "rm", "-rf", NULL, NULL };
|
||||
int ch, status, ntests = 0, errors = 0;
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "check_iolog_mkpath");
|
||||
@ -97,7 +97,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Clean up (avoid running via shell) */
|
||||
execvp("rm", rmargs);
|
||||
execvp("rm", (char **)rmargs);
|
||||
wait(&status);
|
||||
|
||||
return errors;
|
||||
|
@ -49,7 +49,7 @@ static struct parse_delay_test {
|
||||
/*
|
||||
* Test iolog_parse_delay()
|
||||
*/
|
||||
void
|
||||
static void
|
||||
test_parse_delay(int *ntests, int *nerrors)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -106,7 +106,7 @@ static struct adjust_delay_test {
|
||||
/*
|
||||
* Test iolog_adjust_delay()
|
||||
*/
|
||||
void
|
||||
static void
|
||||
test_adjust_delay(int *ntests, int *nerrors)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -86,11 +86,6 @@ GENERATED = log_server.pb-c.h log_server.pb-c.c
|
||||
|
||||
all: liblogsrv.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend:
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/logsrv/Makefile.in
|
||||
@ -149,7 +144,9 @@ splint:
|
||||
cppcheck:
|
||||
cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
pvs-log-files:
|
||||
|
||||
pvs-studio:
|
||||
|
||||
fuzz:
|
||||
|
||||
@ -185,8 +182,5 @@ cleandir: realclean
|
||||
log_server.pb-c.lo: $(srcdir)/log_server.pb-c.c $(incdir)/log_server.pb-c.h \
|
||||
$(incdir)/protobuf-c/protobuf-c.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/log_server.pb-c.c
|
||||
log_server.pb-c.i: $(srcdir)/log_server.pb-c.c $(incdir)/log_server.pb-c.h \
|
||||
$(incdir)/protobuf-c/protobuf-c.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
log_server.pb-c.plog: log_server.pb-c.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/log_server.pb-c.c --i-file $< --output-file $@
|
||||
log_server.pb-c.plog: $(srcdir)/log_server.pb-c.c
|
||||
touch $@
|
||||
|
@ -81,11 +81,6 @@ POBJS = $(IOBJS:.i=.plog)
|
||||
|
||||
all: libprotobuf-c.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend:
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/protobuf-c/Makefile.in
|
||||
@ -144,7 +139,9 @@ splint:
|
||||
cppcheck:
|
||||
cppcheck $(CPPCHECK_OPTS) -I$(incdir) -I$(top_builddir) -I$(top_srcdir) $(srcdir)/*.c
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
pvs-log-files:
|
||||
|
||||
pvs-studio:
|
||||
|
||||
fuzz:
|
||||
|
||||
@ -173,11 +170,11 @@ cleandir: realclean
|
||||
.PHONY: clean mostlyclean distclean cleandir clobber realclean
|
||||
|
||||
# Autogenerated dependencies, do not modify
|
||||
protobuf-c.lo: $(srcdir)/protobuf-c.c $(incdir)/protobuf-c/protobuf-c.h \
|
||||
$(top_builddir)/config.h
|
||||
protobuf-c.lo: $(srcdir)/protobuf-c.c $(incdir)/compat/endian.h \
|
||||
$(incdir)/protobuf-c/protobuf-c.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/protobuf-c.c
|
||||
protobuf-c.i: $(srcdir)/protobuf-c.c $(incdir)/protobuf-c/protobuf-c.h \
|
||||
$(top_builddir)/config.h
|
||||
protobuf-c.i: $(srcdir)/protobuf-c.c $(incdir)/compat/endian.h \
|
||||
$(incdir)/protobuf-c/protobuf-c.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
protobuf-c.plog: protobuf-c.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/protobuf-c.c --i-file $< --output-file $@
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors.
|
||||
* Copyright (c) 2008-2022, Dave Benson and the protobuf-c authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -2618,14 +2618,14 @@ parse_required_member(ScannedMember *scanned_member,
|
||||
return FALSE;
|
||||
|
||||
def_mess = scanned_member->field->default_value;
|
||||
if (len >= pref_len) {
|
||||
if (len >= pref_len)
|
||||
subm = protobuf_c_message_unpack(scanned_member->field->descriptor,
|
||||
allocator,
|
||||
len - pref_len,
|
||||
data + pref_len);
|
||||
} else {
|
||||
else
|
||||
subm = NULL;
|
||||
}
|
||||
|
||||
if (maybe_clear &&
|
||||
*pmessage != NULL &&
|
||||
*pmessage != def_mess)
|
||||
@ -3246,6 +3246,9 @@ protobuf_c_message_unpack(const ProtobufCMessageDescriptor *desc,
|
||||
/* allocate space for repeated fields, also check that all required fields have been set */
|
||||
for (f = 0; f < desc->n_fields; f++) {
|
||||
const ProtobufCFieldDescriptor *field = desc->fields + f;
|
||||
if (field == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (field->label == PROTOBUF_C_LABEL_REPEATED) {
|
||||
size_t siz =
|
||||
sizeof_elt_in_repeated_array(field->type);
|
||||
|
@ -55,6 +55,7 @@ CPP = @CPP@
|
||||
HOSTCPP = @CPP_FOR_BUILD@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
SHA1SUM = @SHA1SUM@
|
||||
GREP = @GREP@
|
||||
SED = @SED@
|
||||
AWK = @AWK@
|
||||
|
||||
@ -110,10 +111,10 @@ PVS_IGNORE = 'V707,V011,V002,V536'
|
||||
PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE)
|
||||
|
||||
# Regression tests
|
||||
TEST_PROGS = conf_test hltq_test parseln_test progname_test \
|
||||
TEST_PROGS = conf_test hltq_test parseln_test progname_test parse_gids_test \
|
||||
getgids getgrouplist_test multiarch_test open_parent_dir_test \
|
||||
strsplit_test strtobool_test strtoid_test strtomode_test \
|
||||
strtonum_test parse_gids_test getgids getgrouplist_test \
|
||||
uuid_test @COMPAT_TEST_PROGS@
|
||||
strtonum_test uuid_test @COMPAT_TEST_PROGS@
|
||||
TEST_LIBS = @LIBS@
|
||||
TEST_LDFLAGS = @LDFLAGS@
|
||||
TEST_VERBOSE =
|
||||
@ -143,11 +144,11 @@ SHELL = @SHELL@
|
||||
|
||||
LTOBJS = basename.lo @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \
|
||||
gettime.lo getgrouplist.lo gidlist.lo json.lo lbuf.lo locking.lo \
|
||||
logfac.lo logpri.lo mkdir_parents.lo parseln.lo progname.lo rcstr.lo \
|
||||
regex.lo roundup.lo secure_path.lo setgroups.lo strsplit.lo \
|
||||
strtobool.lo strtoid.lo strtomode.lo strtonum.lo sudo_conf.lo \
|
||||
sudo_debug.lo sudo_dso.lo term.lo ttyname_dev.lo \
|
||||
ttysize.lo uuid.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
logfac.lo logpri.lo mkdir_parents.lo mmap_alloc.lo multiarch.lo \
|
||||
parseln.lo progname.lo rcstr.lo regex.lo roundup.lo secure_path.lo \
|
||||
setgroups.lo strsplit.lo strtobool.lo strtoid.lo strtomode.lo \
|
||||
strtonum.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo term.lo \
|
||||
ttyname_dev.lo ttysize.lo uuid.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
|
||||
IOBJS = $(LTOBJS:.lo=.i)
|
||||
|
||||
@ -171,6 +172,10 @@ GLOBTEST_OBJS = globtest.lo glob.lo
|
||||
|
||||
GETDELIM_TEST_OBJS = getdelim_test.lo getdelim.lo
|
||||
|
||||
MULTIARCH_TEST_OBJS = multiarch_test.lo multiarch.lo
|
||||
|
||||
OPEN_PARENT_DIR_TEST_OBJS = open_parent_dir_test.lo mkdir_parents.lo
|
||||
|
||||
STRTOBOOL_TEST_OBJS = strtobool_test.lo strtobool.lo
|
||||
|
||||
STRTOMODE_TEST_OBJS = strtomode_test.lo strtomode.lo
|
||||
@ -197,11 +202,6 @@ FUZZ_SUDO_CONF_CORPUS = $(srcdir)/regress/corpus/seed/sudo_conf/sudo.conf.*
|
||||
|
||||
all: libsudo_util.la
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
depend: siglist.c signame.c
|
||||
$(scriptdir)/mkdep.pl --srcdir=$(abs_top_srcdir) \
|
||||
--builddir=$(abs_top_builddir) lib/util/Makefile.in
|
||||
@ -287,6 +287,12 @@ hltq_test: $(HLTQ_TEST_OBJS) libsudo_util.la
|
||||
mktemp_test: $(MKTEMP_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(MKTEMP_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
multiarch_test: $(MULTIARCH_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(MULTIARCH_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
open_parent_dir_test: $(OPEN_PARENT_DIR_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(OPEN_PARENT_DIR_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
parseln_test: $(PARSELN_TEST_OBJS) libsudo_util.la
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(PARSELN_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(HARDENING_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
|
||||
|
||||
@ -336,7 +342,7 @@ fuzz_sudo_conf_seed_corpus.zip:
|
||||
rm -rf $$tdir
|
||||
|
||||
run-fuzz_sudo_conf: fuzz_sudo_conf
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -395,11 +401,14 @@ cppcheck:
|
||||
|
||||
pvs-log-files: $(POBJS)
|
||||
|
||||
pvs-studio: $(POBJS)
|
||||
plog-converter $(PVS_LOG_OPTS) $(POBJS)
|
||||
|
||||
fuzz: run-fuzz_sudo_conf
|
||||
|
||||
check-fuzzer: $(FUZZ_PROGS)
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -415,7 +424,7 @@ check-fuzzer: $(FUZZ_PROGS)
|
||||
# Note: some regress checks are run from srcdir for consistent error messages
|
||||
check: $(TEST_PROGS) check-fuzzer
|
||||
@if test X"$(cross_compiling)" != X"yes"; then \
|
||||
if locale -a 2>&1 | grep '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
if locale -a 2>&1 | $(GREP) '^C.UTF-8$$' >/dev/null 2>&1; then \
|
||||
LC_ALL=C.UTF-8; export LC_ALL; \
|
||||
else \
|
||||
LC_ALL=C; export LC_ALL; \
|
||||
@ -440,9 +449,9 @@ check: $(TEST_PROGS) check-fuzzer
|
||||
if test -f globtest; then \
|
||||
mkdir -p `$(SED) 's@/[^/]*$$@@' $(srcdir)/regress/glob/files | sort -u`; \
|
||||
touch `cat $(srcdir)/regress/glob/files`; \
|
||||
chmod 0755 `grep '/r[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
chmod 0444 `grep '/s[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
chmod 0711 `grep '/t[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
chmod 0755 `$(GREP) '/r[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
chmod 0444 `$(GREP) '/s[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
chmod 0711 `$(GREP) '/t[^/]*$$' $(srcdir)/regress/glob/files`; \
|
||||
./globtest $(srcdir)/regress/glob/globtest.in || rval=`expr $$rval + $$?`; \
|
||||
rm -rf fake; \
|
||||
fi; \
|
||||
@ -456,6 +465,8 @@ check: $(TEST_PROGS) check-fuzzer
|
||||
./strsig_test || rval=`expr $$rval + $$?`; \
|
||||
fi; \
|
||||
./getgrouplist_test || rval=`expr $$rval + $$?`; \
|
||||
./multiarch_test || rval=`expr $$rval + $$?`; \
|
||||
./open_parent_dir_test || rval=`expr $$rval + $$?`; \
|
||||
./strtobool_test || rval=`expr $$rval + $$?`; \
|
||||
./strtoid_test || rval=`expr $$rval + $$?`; \
|
||||
./strtomode_test || rval=`expr $$rval + $$?`; \
|
||||
@ -704,6 +715,14 @@ fchmodat.i: $(srcdir)/fchmodat.c $(incdir)/sudo_compat.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fchmodat.plog: fchmodat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fchmodat.c --i-file $< --output-file $@
|
||||
fchownat.lo: $(srcdir)/fchownat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/fchownat.c
|
||||
fchownat.i: $(srcdir)/fchownat.c $(incdir)/sudo_compat.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fchownat.plog: fchownat.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/fchownat.c --i-file $< --output-file $@
|
||||
fnm_test.lo: $(srcdir)/regress/fnmatch/fnm_test.c $(incdir)/compat/fnmatch.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
@ -1088,6 +1107,38 @@ mktemp_test.i: $(srcdir)/regress/mktemp/mktemp_test.c \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
mktemp_test.plog: mktemp_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/mktemp/mktemp_test.c --i-file $< --output-file $@
|
||||
mmap_alloc.lo: $(srcdir)/mmap_alloc.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/mmap_alloc.c
|
||||
mmap_alloc.i: $(srcdir)/mmap_alloc.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
mmap_alloc.plog: mmap_alloc.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/mmap_alloc.c --i-file $< --output-file $@
|
||||
multiarch.lo: $(srcdir)/multiarch.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/multiarch.c
|
||||
multiarch.i: $(srcdir)/multiarch.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
multiarch.plog: multiarch.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/multiarch.c --i-file $< --output-file $@
|
||||
multiarch_test.lo: $(srcdir)/regress/multiarch/multiarch_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/regress/multiarch/multiarch_test.c
|
||||
multiarch_test.i: $(srcdir)/regress/multiarch/multiarch_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
multiarch_test.plog: multiarch_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/multiarch/multiarch_test.c --i-file $< --output-file $@
|
||||
nanosleep.lo: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
@ -1098,6 +1149,20 @@ nanosleep.i: $(srcdir)/nanosleep.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
nanosleep.plog: nanosleep.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/nanosleep.c --i-file $< --output-file $@
|
||||
open_parent_dir_test.lo: \
|
||||
$(srcdir)/regress/open_parent_dir/open_parent_dir_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/regress/open_parent_dir/open_parent_dir_test.c
|
||||
open_parent_dir_test.i: \
|
||||
$(srcdir)/regress/open_parent_dir/open_parent_dir_test.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
open_parent_dir_test.plog: open_parent_dir_test.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/open_parent_dir/open_parent_dir_test.c --i-file $< --output-file $@
|
||||
openat.lo: $(srcdir)/openat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/openat.c
|
||||
openat.i: $(srcdir)/openat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
|
||||
@ -1276,10 +1341,12 @@ signame.i: signame.c
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
signame.plog: signame.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file signame.c --i-file $< --output-file $@
|
||||
snprintf.lo: $(srcdir)/snprintf.c $(incdir)/sudo_compat.h \
|
||||
snprintf.lo: $(srcdir)/snprintf.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/snprintf.c
|
||||
snprintf.i: $(srcdir)/snprintf.c $(incdir)/sudo_compat.h \
|
||||
snprintf.i: $(srcdir)/snprintf.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_util.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
snprintf.plog: snprintf.i
|
||||
@ -1488,11 +1555,13 @@ sudo_debug.i: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
sudo_debug.plog: sudo_debug.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_debug.c --i-file $< --output-file $@
|
||||
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(top_builddir)/config.h
|
||||
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(HARDENING_CFLAGS) $(srcdir)/sudo_dso.c
|
||||
sudo_dso.i: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(top_builddir)/config.h
|
||||
sudo_dso.i: $(srcdir)/sudo_dso.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
sudo_dso.plog: sudo_dso.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_dso.c --i-file $< --output-file $@
|
||||
|
@ -52,8 +52,8 @@
|
||||
|
||||
struct aix_limit {
|
||||
int resource;
|
||||
char *soft;
|
||||
char *hard;
|
||||
const char *soft;
|
||||
const char *hard;
|
||||
int factor;
|
||||
};
|
||||
|
||||
@ -68,11 +68,11 @@ static struct aix_limit aix_limits[] = {
|
||||
};
|
||||
|
||||
static int
|
||||
aix_getlimit(char *user, char *lim, int *valp)
|
||||
aix_getlimit(const char *user, const char *lim, int *valp)
|
||||
{
|
||||
debug_decl(aix_getlimit, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (getuserattr(user, lim, valp, SEC_INT) != 0)
|
||||
if (getuserattr((char *)user, (char *)lim, valp, SEC_INT) != 0)
|
||||
debug_return_int(-1);
|
||||
debug_return_int(0);
|
||||
}
|
||||
@ -169,7 +169,7 @@ aix_getauthregistry_v1(char *user, char *saved_registry)
|
||||
sudo_warn("%s", U_("unable to open userdb"));
|
||||
goto done;
|
||||
}
|
||||
ret = getuserattr(user, S_REGISTRY, ®istry, SEC_CHAR);
|
||||
ret = getuserattr(user, (char *)S_REGISTRY, ®istry, SEC_CHAR);
|
||||
if (ret == 0) {
|
||||
/* sizeof(authdb_t) is guaranteed to be 16 */
|
||||
if (strlcpy(saved_registry, registry, 16) >= 16) {
|
||||
|
@ -143,14 +143,14 @@ _rs_rekey(unsigned char *dat, size_t datlen)
|
||||
}
|
||||
/* immediately reinit for backtracking resistance */
|
||||
_rs_init(rs_buf, KEYSZ + IVSZ);
|
||||
memset(rs_buf, 0, KEYSZ + IVSZ); // -V512
|
||||
memset(rs_buf, 0, KEYSZ + IVSZ); // -V::512, 1086
|
||||
rs_have = sizeof(rs_buf) - KEYSZ - IVSZ;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_random_buf(void *_buf, size_t n)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)_buf;
|
||||
unsigned char *buf = _buf;
|
||||
unsigned char *keystream;
|
||||
size_t m;
|
||||
|
||||
|
@ -23,6 +23,11 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# include "compat/stdbool.h"
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -33,6 +38,8 @@
|
||||
#include "sudo_debug.h"
|
||||
#include "sudo_digest.h"
|
||||
|
||||
#define SUDO_LIBGCRYPT_VERSION_MIN "1.3.0"
|
||||
|
||||
struct sudo_digest {
|
||||
int gcry_digest_type;
|
||||
unsigned int digest_len;
|
||||
@ -61,9 +68,21 @@ struct sudo_digest *
|
||||
sudo_digest_alloc_v1(int digest_type)
|
||||
{
|
||||
debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL);
|
||||
static bool initialized = false;
|
||||
struct sudo_digest *dig;
|
||||
int gcry_digest_type;
|
||||
|
||||
if (!initialized) {
|
||||
if (!gcry_check_version(SUDO_LIBGCRYPT_VERSION_MIN)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"libgcrypt too old (need %s, have %s)",
|
||||
SUDO_LIBGCRYPT_VERSION_MIN, gcry_check_version(NULL));
|
||||
debug_return_ptr(NULL);
|
||||
}
|
||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
gcry_digest_type = sudo_digest_type_to_gcry(digest_type);
|
||||
if (gcry_digest_type == -1) {
|
||||
errno = EINVAL;
|
||||
|
@ -239,7 +239,7 @@ warning(const char *errstr, const char *fmt, va_list ap)
|
||||
fputs(": ", stderr);
|
||||
fputs(errstr, stderr);
|
||||
}
|
||||
if (isatty(fileno(stderr)))
|
||||
if (sudo_term_is_raw(fileno(stderr)))
|
||||
putc('\r', stderr);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
67
lib/util/fchownat.c
Normal file
67
lib/util/fchownat.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
|
||||
#ifndef HAVE_FCHOWNAT
|
||||
int
|
||||
sudo_fchownat(int dfd, const char *path, uid_t uid, gid_t gid, int flags)
|
||||
{
|
||||
int odfd, ret;
|
||||
|
||||
if (dfd == AT_FDCWD) {
|
||||
if (flags & AT_SYMLINK_NOFOLLOW)
|
||||
return lchown(path, uid, gid);
|
||||
else
|
||||
return chown(path, uid, gid);
|
||||
}
|
||||
|
||||
/* Save cwd */
|
||||
if ((odfd = open(".", O_RDONLY)) == -1)
|
||||
return -1;
|
||||
|
||||
if (fchdir(dfd) == -1) {
|
||||
close(odfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & AT_SYMLINK_NOFOLLOW)
|
||||
ret = lchown(path, uid, gid);
|
||||
else
|
||||
ret = chown(path, uid, gid);
|
||||
|
||||
/* Restore cwd */
|
||||
if (fchdir(odfd) == -1) {
|
||||
/* Should not happen */
|
||||
ret = -1;
|
||||
}
|
||||
close(odfd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_FCHOWNAT */
|
@ -20,6 +20,11 @@
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifndef HAVE_GETENTROPY
|
||||
|
@ -238,7 +238,7 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen)
|
||||
/* Check for YP inclusion/exclusion entries. */
|
||||
if (*cp == '+' || *cp == '-') {
|
||||
/* Only the name is required for YP inclusion/exclusion entries. */
|
||||
grp->gr_passwd = "";
|
||||
grp->gr_passwd = (char *)"";
|
||||
grp->gr_gid = 0;
|
||||
grp->gr_mem = NULL;
|
||||
yp = 1;
|
||||
|
@ -96,7 +96,7 @@ int optreset; /* reset getopt */
|
||||
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
|
||||
#define INORDER (int)1
|
||||
|
||||
#define EMSG ""
|
||||
#define EMSG (char *)""
|
||||
|
||||
#ifdef GNU_COMPATIBLE
|
||||
#define NO_PREFIX (-1)
|
||||
@ -202,7 +202,7 @@ parse_long_options(char * const *nargv, const char *options,
|
||||
{
|
||||
char *current_argv, *has_equal;
|
||||
#ifdef GNU_COMPATIBLE
|
||||
char *current_dash;
|
||||
const char *current_dash;
|
||||
#endif
|
||||
size_t current_argv_len;
|
||||
int i, match, exact_match, second_partial_match;
|
||||
|
174
lib/util/json.c
174
lib/util/json.c
@ -44,13 +44,13 @@
|
||||
* Returns true on success, false if out of memory.
|
||||
*/
|
||||
static bool
|
||||
json_expand_buf(struct json_container *json)
|
||||
json_expand_buf(struct json_container *jsonc)
|
||||
{
|
||||
char *newbuf;
|
||||
debug_decl(json_expand_buf, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((newbuf = reallocarray(json->buf, 2, json->bufsize)) == NULL) {
|
||||
if (json->memfatal) {
|
||||
if ((newbuf = reallocarray(jsonc->buf, 2, jsonc->bufsize)) == NULL) {
|
||||
if (jsonc->memfatal) {
|
||||
sudo_fatalx(U_("%s: %s"),
|
||||
__func__, U_("unable to allocate memory"));
|
||||
}
|
||||
@ -58,8 +58,8 @@ json_expand_buf(struct json_container *json)
|
||||
"%s: %s", __func__, "unable to allocate memory");
|
||||
debug_return_bool(false);
|
||||
}
|
||||
json->buf = newbuf;
|
||||
json->bufsize *= 2;
|
||||
jsonc->buf = newbuf;
|
||||
jsonc->bufsize *= 2;
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
@ -69,24 +69,24 @@ json_expand_buf(struct json_container *json)
|
||||
* Append "indent" number of blank characters.
|
||||
*/
|
||||
static bool
|
||||
json_new_line(struct json_container *json)
|
||||
json_new_line(struct json_container *jsonc)
|
||||
{
|
||||
int indent = json->indent_level;
|
||||
int indent = jsonc->indent_level;
|
||||
debug_decl(json_new_line, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* No non-essential white space in minimal mode. */
|
||||
if (json->minimal)
|
||||
if (jsonc->minimal)
|
||||
debug_return_bool(true);
|
||||
|
||||
while (json->buflen + 1 + indent >= json->bufsize) {
|
||||
if (!json_expand_buf(json))
|
||||
while (jsonc->buflen + 1 + indent >= jsonc->bufsize) {
|
||||
if (!json_expand_buf(jsonc))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
json->buf[json->buflen++] = '\n';
|
||||
jsonc->buf[jsonc->buflen++] = '\n';
|
||||
while (indent--) {
|
||||
json->buf[json->buflen++] = ' ';
|
||||
jsonc->buf[jsonc->buflen++] = ' ';
|
||||
}
|
||||
json->buf[json->buflen] = '\0';
|
||||
jsonc->buf[jsonc->buflen] = '\0';
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
@ -96,20 +96,20 @@ json_new_line(struct json_container *json)
|
||||
* Does not perform any quoting.
|
||||
*/
|
||||
static bool
|
||||
json_append_buf(struct json_container *json, const char *str)
|
||||
json_append_buf(struct json_container *jsonc, const char *str)
|
||||
{
|
||||
size_t len;
|
||||
debug_decl(json_append_buf, SUDO_DEBUG_UTIL);
|
||||
|
||||
len = strlen(str);
|
||||
while (json->buflen + len >= json->bufsize) {
|
||||
if (!json_expand_buf(json))
|
||||
while (jsonc->buflen + len >= jsonc->bufsize) {
|
||||
if (!json_expand_buf(jsonc))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
memcpy(json->buf + json->buflen, str, len);
|
||||
json->buflen += len;
|
||||
json->buf[json->buflen] = '\0';
|
||||
memcpy(jsonc->buf + jsonc->buflen, str, len);
|
||||
jsonc->buflen += len;
|
||||
jsonc->buf[jsonc->buflen] = '\0';
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
@ -119,12 +119,12 @@ json_append_buf(struct json_container *json, const char *str)
|
||||
* Does not support unicode escapes.
|
||||
*/
|
||||
static bool
|
||||
json_append_string(struct json_container *json, const char *str)
|
||||
json_append_string(struct json_container *jsonc, const char *str)
|
||||
{
|
||||
char ch;
|
||||
debug_decl(json_append_string, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!json_append_buf(json, "\""))
|
||||
if (!json_append_buf(jsonc, "\""))
|
||||
debug_return_bool(false);
|
||||
while ((ch = *str++) != '\0') {
|
||||
char buf[3], *cp = buf;
|
||||
@ -157,29 +157,29 @@ json_append_string(struct json_container *json, const char *str)
|
||||
}
|
||||
*cp++ = ch;
|
||||
*cp++ = '\0';
|
||||
if (!json_append_buf(json, buf))
|
||||
if (!json_append_buf(jsonc, buf))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_append_buf(json, "\""))
|
||||
if (!json_append_buf(jsonc, "\""))
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_init_v1(struct json_container *json, int indent, bool minimal,
|
||||
sudo_json_init_v1(struct json_container *jsonc, int indent, bool minimal,
|
||||
bool memfatal)
|
||||
{
|
||||
debug_decl(sudo_json_init, SUDO_DEBUG_UTIL);
|
||||
|
||||
memset(json, 0, sizeof(*json));
|
||||
json->indent_level = indent;
|
||||
json->indent_increment = indent;
|
||||
json->minimal = minimal;
|
||||
json->memfatal = memfatal;
|
||||
json->buf = malloc(64 * 1024);
|
||||
if (json->buf == NULL) {
|
||||
if (json->memfatal) {
|
||||
memset(jsonc, 0, sizeof(*jsonc));
|
||||
jsonc->indent_level = indent;
|
||||
jsonc->indent_increment = indent;
|
||||
jsonc->minimal = minimal;
|
||||
jsonc->memfatal = memfatal;
|
||||
jsonc->buf = malloc(64 * 1024);
|
||||
if (jsonc->buf == NULL) {
|
||||
if (jsonc->memfatal) {
|
||||
sudo_fatalx(U_("%s: %s"),
|
||||
__func__, U_("unable to allocate memory"));
|
||||
}
|
||||
@ -187,162 +187,162 @@ sudo_json_init_v1(struct json_container *json, int indent, bool minimal,
|
||||
"%s: %s", __func__, "unable to allocate memory");
|
||||
debug_return_bool(false);
|
||||
}
|
||||
*json->buf = '\0';
|
||||
json->bufsize = 64 * 1024;
|
||||
*jsonc->buf = '\0';
|
||||
jsonc->bufsize = 64 * 1024;
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
void
|
||||
sudo_json_free_v1(struct json_container *json)
|
||||
sudo_json_free_v1(struct json_container *jsonc)
|
||||
{
|
||||
debug_decl(sudo_json_free, SUDO_DEBUG_UTIL);
|
||||
|
||||
free(json->buf);
|
||||
memset(json, 0, sizeof(*json));
|
||||
free(jsonc->buf);
|
||||
memset(jsonc, 0, sizeof(*jsonc));
|
||||
|
||||
debug_return;
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_open_object_v1(struct json_container *json, const char *name)
|
||||
sudo_json_open_object_v1(struct json_container *jsonc, const char *name)
|
||||
{
|
||||
debug_decl(sudo_json_open_object, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Add comma if we are continuing an object/array. */
|
||||
if (json->need_comma) {
|
||||
if (!json_append_buf(json, ","))
|
||||
if (jsonc->need_comma) {
|
||||
if (!json_append_buf(jsonc, ","))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_new_line(json))
|
||||
if (!json_new_line(jsonc))
|
||||
debug_return_bool(false);
|
||||
|
||||
if (name != NULL) {
|
||||
json_append_string(json, name);
|
||||
if (!json_append_buf(json, json->minimal ? ":{" : ": {"))
|
||||
json_append_string(jsonc, name);
|
||||
if (!json_append_buf(jsonc, jsonc->minimal ? ":{" : ": {"))
|
||||
debug_return_bool(false);
|
||||
} else {
|
||||
if (!json_append_buf(json, "{"))
|
||||
if (!json_append_buf(jsonc, "{"))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
json->indent_level += json->indent_increment;
|
||||
json->need_comma = false;
|
||||
jsonc->indent_level += jsonc->indent_increment;
|
||||
jsonc->need_comma = false;
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_close_object_v1(struct json_container *json)
|
||||
sudo_json_close_object_v1(struct json_container *jsonc)
|
||||
{
|
||||
debug_decl(sudo_json_close_object, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!json->minimal) {
|
||||
json->indent_level -= json->indent_increment;
|
||||
if (!json_new_line(json))
|
||||
if (!jsonc->minimal) {
|
||||
jsonc->indent_level -= jsonc->indent_increment;
|
||||
if (!json_new_line(jsonc))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_append_buf(json, "}"))
|
||||
if (!json_append_buf(jsonc, "}"))
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_open_array_v1(struct json_container *json, const char *name)
|
||||
sudo_json_open_array_v1(struct json_container *jsonc, const char *name)
|
||||
{
|
||||
debug_decl(sudo_json_open_array, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Add comma if we are continuing an object/array. */
|
||||
if (json->need_comma) {
|
||||
if (!json_append_buf(json, ","))
|
||||
if (jsonc->need_comma) {
|
||||
if (!json_append_buf(jsonc, ","))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_new_line(json))
|
||||
if (!json_new_line(jsonc))
|
||||
debug_return_bool(false);
|
||||
|
||||
if (name != NULL) {
|
||||
json_append_string(json, name);
|
||||
if (!json_append_buf(json, json->minimal ? ":[" : ": ["))
|
||||
json_append_string(jsonc, name);
|
||||
if (!json_append_buf(jsonc, jsonc->minimal ? ":[" : ": ["))
|
||||
debug_return_bool(false);
|
||||
} else {
|
||||
if (!json_append_buf(json, "["))
|
||||
if (!json_append_buf(jsonc, "["))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
json->indent_level += json->indent_increment;
|
||||
json->need_comma = false;
|
||||
jsonc->indent_level += jsonc->indent_increment;
|
||||
jsonc->need_comma = false;
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_close_array_v1(struct json_container *json)
|
||||
sudo_json_close_array_v1(struct json_container *jsonc)
|
||||
{
|
||||
debug_decl(sudo_json_close_array, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!json->minimal) {
|
||||
json->indent_level -= json->indent_increment;
|
||||
if (!json_new_line(json))
|
||||
if (!jsonc->minimal) {
|
||||
jsonc->indent_level -= jsonc->indent_increment;
|
||||
if (!json_new_line(jsonc))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_append_buf(json, "]"))
|
||||
if (!json_append_buf(jsonc, "]"))
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
sudo_json_add_value_int(struct json_container *json, const char *name,
|
||||
sudo_json_add_value_int(struct json_container *jsonc, const char *name,
|
||||
struct json_value *value, bool as_object)
|
||||
{
|
||||
char numbuf[(((sizeof(long long) * 8) + 2) / 3) + 2];
|
||||
debug_decl(sudo_json_add_value, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Add comma if we are continuing an object/array. */
|
||||
if (json->need_comma) {
|
||||
if (!json_append_buf(json, ","))
|
||||
if (jsonc->need_comma) {
|
||||
if (!json_append_buf(jsonc, ","))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
if (!json_new_line(json))
|
||||
if (!json_new_line(jsonc))
|
||||
debug_return_bool(false);
|
||||
json->need_comma = true;
|
||||
jsonc->need_comma = true;
|
||||
|
||||
if (as_object) {
|
||||
if (!json_append_buf(json, json->minimal ? "{" : "{ "))
|
||||
if (!json_append_buf(jsonc, jsonc->minimal ? "{" : "{ "))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
/* name */
|
||||
if (name != NULL) {
|
||||
if (!json_append_string(json, name))
|
||||
if (!json_append_string(jsonc, name))
|
||||
debug_return_bool(false);
|
||||
if (!json_append_buf(json, json->minimal ? ":" : ": "))
|
||||
if (!json_append_buf(jsonc, jsonc->minimal ? ":" : ": "))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
/* value */
|
||||
switch (value->type) {
|
||||
case JSON_STRING:
|
||||
if (!json_append_string(json, value->u.string))
|
||||
if (!json_append_string(jsonc, value->u.string))
|
||||
debug_return_bool(false);
|
||||
break;
|
||||
case JSON_ID:
|
||||
snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)value->u.id);
|
||||
if (!json_append_buf(json, numbuf))
|
||||
if (!json_append_buf(jsonc, numbuf))
|
||||
debug_return_bool(false);
|
||||
break;
|
||||
case JSON_NUMBER:
|
||||
snprintf(numbuf, sizeof(numbuf), "%lld", value->u.number);
|
||||
if (!json_append_buf(json, numbuf))
|
||||
if (!json_append_buf(jsonc, numbuf))
|
||||
debug_return_bool(false);
|
||||
break;
|
||||
case JSON_NULL:
|
||||
if (!json_append_buf(json, "null"))
|
||||
if (!json_append_buf(jsonc, "null"))
|
||||
debug_return_bool(false);
|
||||
break;
|
||||
case JSON_BOOL:
|
||||
if (!json_append_buf(json, value->u.boolean ? "true" : "false"))
|
||||
if (!json_append_buf(jsonc, value->u.boolean ? "true" : "false"))
|
||||
debug_return_bool(false);
|
||||
break;
|
||||
case JSON_ARRAY:
|
||||
@ -354,7 +354,7 @@ sudo_json_add_value_int(struct json_container *json, const char *name,
|
||||
}
|
||||
|
||||
if (as_object) {
|
||||
if (!json_append_buf(json, json->minimal ? "}" : " }"))
|
||||
if (!json_append_buf(jsonc, jsonc->minimal ? "}" : " }"))
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
@ -362,27 +362,27 @@ sudo_json_add_value_int(struct json_container *json, const char *name,
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_add_value_v1(struct json_container *json, const char *name,
|
||||
sudo_json_add_value_v1(struct json_container *jsonc, const char *name,
|
||||
struct json_value *value)
|
||||
{
|
||||
return sudo_json_add_value_int(json, name, value, false);
|
||||
return sudo_json_add_value_int(jsonc, name, value, false);
|
||||
}
|
||||
|
||||
bool
|
||||
sudo_json_add_value_as_object_v1(struct json_container *json, const char *name,
|
||||
sudo_json_add_value_as_object_v1(struct json_container *jsonc, const char *name,
|
||||
struct json_value *value)
|
||||
{
|
||||
return sudo_json_add_value_int(json, name, value, true);
|
||||
return sudo_json_add_value_int(jsonc, name, value, true);
|
||||
}
|
||||
|
||||
char *
|
||||
sudo_json_get_buf_v1(struct json_container *json)
|
||||
sudo_json_get_buf_v1(struct json_container *jsonc)
|
||||
{
|
||||
return json->buf;
|
||||
return jsonc->buf;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
sudo_json_get_len_v1(struct json_container *json)
|
||||
sudo_json_get_len_v1(struct json_container *jsonc)
|
||||
{
|
||||
return json->buflen;
|
||||
return jsonc->buflen;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *
|
||||
{
|
||||
int len, saved_len = lbuf->len;
|
||||
bool ret = false;
|
||||
char *cp, *s;
|
||||
const char *cp, *s;
|
||||
va_list ap;
|
||||
debug_decl(sudo_lbuf_append_quoted, SUDO_DEBUG_UTIL);
|
||||
|
||||
@ -155,7 +155,7 @@ sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...)
|
||||
int len, saved_len = lbuf->len;
|
||||
bool ret = false;
|
||||
va_list ap;
|
||||
char *s;
|
||||
const char *s;
|
||||
debug_decl(sudo_lbuf_append, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (sudo_lbuf_error(lbuf))
|
||||
|
@ -39,7 +39,7 @@
|
||||
* For converting between syslog numbers and strings.
|
||||
*/
|
||||
struct strmap {
|
||||
char *name;
|
||||
const char *name;
|
||||
int num;
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
* For converting between syslog numbers and strings.
|
||||
*/
|
||||
struct strmap {
|
||||
char *name;
|
||||
const char *name;
|
||||
int num;
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -76,16 +76,17 @@ is_dir(int dfd, const char *name, int namelen, bool quiet)
|
||||
}
|
||||
|
||||
/*
|
||||
* Create any parent directories needed by path (but not path itself).
|
||||
* Create any parent directories needed by path (but not path itself)
|
||||
* and return an open fd for the parent directory or -1 on error.
|
||||
*/
|
||||
bool
|
||||
sudo_mkdir_parents_v1(const char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet)
|
||||
int
|
||||
sudo_open_parent_dir_v1(const char *path, uid_t uid, gid_t gid, mode_t mode,
|
||||
bool quiet)
|
||||
{
|
||||
const char *cp, *ep, *pathend;
|
||||
char name[PATH_MAX];
|
||||
bool ret = false;
|
||||
int parentfd;
|
||||
debug_decl(sudo_mkdir_parents, SUDO_DEBUG_UTIL);
|
||||
debug_decl(sudo_open_parent_dir, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Starting parent dir is either root or cwd. */
|
||||
cp = path;
|
||||
@ -100,25 +101,27 @@ sudo_mkdir_parents_v1(const char *path, uid_t uid, gid_t gid, mode_t mode, bool
|
||||
if (parentfd == -1) {
|
||||
if (!quiet)
|
||||
sudo_warn(U_("unable to open %s"), *path == '/' ? "/" : ".");
|
||||
debug_return_bool(false);
|
||||
debug_return_int(-1);
|
||||
}
|
||||
|
||||
/* Iterate over path components, skipping the last one. */
|
||||
pathend = cp + strlen(cp);
|
||||
for (cp = sudo_strsplit(cp, pathend, "/", &ep); cp != NULL && ep != NULL;
|
||||
for (cp = sudo_strsplit(cp, pathend, "/", &ep); cp != NULL && *ep != '\0';
|
||||
cp = sudo_strsplit(NULL, pathend, "/", &ep)) {
|
||||
int dfd, len;
|
||||
size_t len = (size_t)(ep - cp);
|
||||
int dfd;
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
|
||||
"mkdir %.*s, mode 0%o, uid %d, gid %d", (int)(ep - path),
|
||||
path, (unsigned int)mode, (int)uid, (int)gid);
|
||||
len = snprintf(name, sizeof(name), "%.*s", (int)(ep - cp), cp);
|
||||
if (len >= ssizeof(name)) {
|
||||
"mkdir %.*s, mode 0%o, uid %d, gid %d", (int)(ep - path), path,
|
||||
(unsigned int)mode, (int)uid, (int)gid);
|
||||
if (len >= sizeof(name)) {
|
||||
errno = ENAMETOOLONG;
|
||||
if (!quiet)
|
||||
sudo_warn(U_("unable to open %.*s"), (int)(ep - path), path);
|
||||
goto done;
|
||||
sudo_warn(U_("unable to mkdir %.*s"), (int)(ep - path), path);
|
||||
goto bad;
|
||||
}
|
||||
memcpy(name, cp, len);
|
||||
name[len] = '\0';
|
||||
reopen:
|
||||
dfd = openat(parentfd, name, O_RDONLY|O_NONBLOCK, 0);
|
||||
if (dfd == -1) {
|
||||
@ -127,7 +130,7 @@ reopen:
|
||||
sudo_warn(U_("unable to open %.*s"),
|
||||
(int)(ep - path), path);
|
||||
}
|
||||
goto done;
|
||||
goto bad;
|
||||
}
|
||||
if (mkdirat(parentfd, name, mode) == 0) {
|
||||
dfd = openat(parentfd, name, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0);
|
||||
@ -136,12 +139,12 @@ reopen:
|
||||
sudo_warn(U_("unable to open %.*s"),
|
||||
(int)(ep - path), path);
|
||||
}
|
||||
goto done;
|
||||
goto bad;
|
||||
}
|
||||
/* Make sure the path we created is still a directory. */
|
||||
if (!is_dir(dfd, path, ep - path, quiet)) {
|
||||
close(dfd);
|
||||
goto done;
|
||||
goto bad;
|
||||
}
|
||||
if (uid != (uid_t)-1 && gid != (gid_t)-1) {
|
||||
if (fchown(dfd, uid, gid) != 0) {
|
||||
@ -157,22 +160,40 @@ reopen:
|
||||
sudo_warn(U_("unable to mkdir %.*s"),
|
||||
(int)(ep - path), path);
|
||||
}
|
||||
goto done;
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
/* Already exists, make sure it is a directory. */
|
||||
if (!is_dir(dfd, path, ep - path, quiet)) {
|
||||
close(dfd);
|
||||
goto done;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
close(parentfd);
|
||||
parentfd = dfd;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
done:
|
||||
debug_return_int(parentfd);
|
||||
bad:
|
||||
if (parentfd != -1)
|
||||
close(parentfd);
|
||||
debug_return_bool(ret);
|
||||
debug_return_int(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create any parent directories needed by path (but not path itself).
|
||||
* Not currently used.
|
||||
*/
|
||||
bool
|
||||
sudo_mkdir_parents_v1(const char *path, uid_t uid, gid_t gid, mode_t mode,
|
||||
bool quiet)
|
||||
{
|
||||
int fd;
|
||||
debug_decl(sudo_mkdir_parents, SUDO_DEBUG_UTIL);
|
||||
|
||||
fd = sudo_open_parent_dir(path, uid, gid, mode, quiet);
|
||||
if (fd == -1)
|
||||
debug_return_bool(false);
|
||||
close(fd);
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2001, 2003, 2004, 2008-2011, 2013, 2015, 2017, 2018
|
||||
* Copyright (c) 2001, 2003, 2004, 2008-2011, 2013, 2015, 2017, 2018, 2022
|
||||
* Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -24,7 +24,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined(HAVE_MKSTEMPS) || !defined(HAVE_MKDTEMP)
|
||||
#if (!defined(HAVE_MKDTEMPAT) && !defined(HAVE_MKDTEMPAT_NP)) || \
|
||||
(!defined(HAVE_MKOSTEMPSAT) && !defined(HAVE_MKOSTEMPSAT_NP))
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
@ -32,9 +33,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif /* HAVE_STDLIB_H */
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
@ -55,12 +54,14 @@
|
||||
#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
|
||||
#define MIN_X 6
|
||||
|
||||
#define MKOTEMP_FLAGS (O_APPEND | O_CLOEXEC | O_SYNC)
|
||||
|
||||
static int
|
||||
mktemp_internal(char *path, int slen, int mode)
|
||||
mktemp_internal(int dfd, char *path, int slen, int mode, int flags)
|
||||
{
|
||||
char *start, *cp, *ep;
|
||||
const char tempchars[] = TEMPCHARS;
|
||||
unsigned int r, tries;
|
||||
unsigned int tries;
|
||||
size_t len;
|
||||
int fd;
|
||||
|
||||
@ -71,31 +72,43 @@ mktemp_internal(char *path, int slen, int mode)
|
||||
}
|
||||
ep = path + len - slen;
|
||||
|
||||
tries = 1;
|
||||
for (start = ep; start > path && start[-1] == 'X'; start--) {
|
||||
if (tries < INT_MAX / NUM_CHARS)
|
||||
tries *= NUM_CHARS;
|
||||
}
|
||||
tries *= 2;
|
||||
for (start = ep; start > path && start[-1] == 'X'; start--)
|
||||
;
|
||||
if (ep - start < MIN_X) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ~MKOTEMP_FLAGS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
flags |= O_CREAT | O_EXCL | O_RDWR;
|
||||
|
||||
tries = INT_MAX;
|
||||
do {
|
||||
for (cp = start; cp != ep; cp++) {
|
||||
r = arc4random_uniform(NUM_CHARS);
|
||||
*cp = tempchars[r];
|
||||
}
|
||||
cp = start;
|
||||
do {
|
||||
unsigned short rbuf[16];
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Avoid lots of arc4random() calls by using
|
||||
* a buffer sized for up to 16 Xs at a time.
|
||||
*/
|
||||
arc4random_buf(rbuf, sizeof(rbuf));
|
||||
for (i = 0; i < nitems(rbuf) && cp != ep; i++)
|
||||
*cp++ = tempchars[rbuf[i] % NUM_CHARS];
|
||||
} while (cp != ep);
|
||||
|
||||
switch (mode) {
|
||||
case MKTEMP_FILE:
|
||||
fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
|
||||
fd = openat(dfd, path, flags, S_IRUSR|S_IWUSR);
|
||||
if (fd != -1 || errno != EEXIST)
|
||||
return fd;
|
||||
break;
|
||||
case MKTEMP_DIR:
|
||||
if (mkdir(path, S_IRWXU) == 0)
|
||||
if (mkdirat(dfd, path, S_IRWXU) == 0)
|
||||
return 0;
|
||||
if (errno != EEXIST)
|
||||
return -1;
|
||||
@ -107,17 +120,53 @@ mktemp_internal(char *path, int slen, int mode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sudo_mkstemps(char *path, int slen)
|
||||
{
|
||||
return mktemp_internal(path, slen, MKTEMP_FILE);
|
||||
}
|
||||
|
||||
char *
|
||||
sudo_mkdtemp(char *path)
|
||||
{
|
||||
if (mktemp_internal(path, 0, MKTEMP_DIR) == -1)
|
||||
if (mktemp_internal(AT_FDCWD, path, 0, MKTEMP_DIR, 0) == -1)
|
||||
return NULL;
|
||||
return path;
|
||||
}
|
||||
#endif /* !HAVE_MKSTEMPS || !HAVE_MKDTEMP */
|
||||
|
||||
char *
|
||||
sudo_mkdtempat(int dfd, char *path)
|
||||
{
|
||||
if (mktemp_internal(dfd, path, 0, MKTEMP_DIR, 0) == -1)
|
||||
return NULL;
|
||||
return path;
|
||||
}
|
||||
|
||||
int
|
||||
sudo_mkostempsat(int dfd, char *path, int slen, int flags)
|
||||
{
|
||||
return mktemp_internal(dfd, path, slen, MKTEMP_FILE, flags);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
int
|
||||
sudo_mkostemps(char *path, int slen, int flags)
|
||||
{
|
||||
return mktemp_internal(AT_FDCWD, path, slen, MKTEMP_FILE, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sudo_mkstemp(char *path)
|
||||
{
|
||||
return mktemp_internal(AT_FDCWD, path, 0, MKTEMP_FILE, 0);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
int
|
||||
sudo_mkostemp(char *path, int flags)
|
||||
{
|
||||
return mktemp_internal(AT_FDCWD, path, 0, MKTEMP_FILE, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sudo_mkstemps(char *path, int slen)
|
||||
{
|
||||
return mktemp_internal(AT_FDCWD, path, slen, MKTEMP_FILE, 0);
|
||||
}
|
||||
#endif /* !HAVE_MKDTEMPAT || !HAVE_MKOSTEMPSAT */
|
||||
|
158
lib/util/mmap_alloc.c
Normal file
158
lib/util/mmap_alloc.c
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void *)-1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
/*
|
||||
* Allocate "size" bytes via mmap().
|
||||
* Space is allocated to store the size for later unmapping.
|
||||
*/
|
||||
void *
|
||||
sudo_mmap_alloc_v1(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
unsigned long *ulp;
|
||||
#ifndef MAP_ANON
|
||||
int fd;
|
||||
|
||||
/* SunOS-style mmap allocation using /dev/zero. */
|
||||
if ((fd = open("/dev/zero", O_RDWR)) == -1)
|
||||
return NULL;
|
||||
size += sizeof(unsigned long);
|
||||
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
close(fd);
|
||||
#else
|
||||
size += sizeof(unsigned long);
|
||||
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||
#endif
|
||||
if (ptr == MAP_FAILED) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Store size before the actual data. */
|
||||
ulp = (unsigned long *)ptr;
|
||||
ulp[0] = size;
|
||||
return (void *)&ulp[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate "nmemb" elements of "size" bytes via mmap().
|
||||
* If overflow would occur, errno is set to ENOMEM and
|
||||
* NULL is returned.
|
||||
*/
|
||||
void *
|
||||
sudo_mmap_allocarray_v1(size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return sudo_mmap_alloc_v1(nmemb * size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of "str" via mmap() and return it.
|
||||
*/
|
||||
char *
|
||||
sudo_mmap_strdup_v1(const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char *newstr;
|
||||
|
||||
if (len == SIZE_MAX) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
newstr = sudo_mmap_alloc_v1(len + 1);
|
||||
memcpy(newstr, str, len);
|
||||
newstr[len] = '\0';
|
||||
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the page permissions for the allocation represented by "ptr" to
|
||||
* read-only. Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
sudo_mmap_protect_v1(void *ptr)
|
||||
{
|
||||
if (ptr != NULL) {
|
||||
unsigned long *ulp = ptr;
|
||||
const unsigned long size = ulp[-1];
|
||||
return mprotect((void *)&ulp[-1], size, PROT_READ);
|
||||
}
|
||||
|
||||
/* Can't protect NULL. */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free "ptr" allocated by sudo_mmap_alloc().
|
||||
* The allocated size is stored (as unsigned long) in ptr[-1].
|
||||
*/
|
||||
void
|
||||
sudo_mmap_free_v1(void *ptr)
|
||||
{
|
||||
if (ptr != NULL) {
|
||||
unsigned long *ulp = (unsigned long *)ptr - 1;
|
||||
const unsigned long size = ulp[0];
|
||||
int saved_errno = errno;
|
||||
|
||||
(void)munmap((void *)ulp, size);
|
||||
errno = saved_errno;
|
||||
}
|
||||
}
|
103
lib/util/multiarch.c
Normal file
103
lib/util/multiarch.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
# if defined(__linux__)
|
||||
/*
|
||||
* On Linux systems that use multi-arch, the actual DSO may be in a
|
||||
* machine-specific subdirectory. If the specified path contains
|
||||
* /lib/ or /libexec/, insert a multi-arch directory after it.
|
||||
* If sb is non-NULL, stat(2) will be called on the new path, filling in sb.
|
||||
* Returns a dynamically allocated string on success and NULL on failure.
|
||||
*/
|
||||
char *
|
||||
sudo_stat_multiarch_v1(const char *path, struct stat *sb)
|
||||
{
|
||||
# if defined(__ILP32__)
|
||||
const char *libdirs[] = { "/libx32/", "/lib/", "/libexec/", NULL };
|
||||
# elif defined(__LP64__)
|
||||
const char *libdirs[] = { "/lib64/", "/lib/", "/libexec/", NULL };
|
||||
# else
|
||||
const char *libdirs[] = { "/lib32/", "/lib/", "/libexec/", NULL };
|
||||
# endif
|
||||
const char **lp, *lib, *slash;
|
||||
struct utsname unamebuf;
|
||||
char *newpath = NULL;
|
||||
int len;
|
||||
|
||||
if (uname(&unamebuf) == -1)
|
||||
return NULL;
|
||||
|
||||
for (lp = libdirs; *lp != NULL; lp++) {
|
||||
/* Replace lib64, lib32, libx32 with lib in new path. */
|
||||
const char *newlib = lp == libdirs ? "/lib/" : *lp;
|
||||
|
||||
/* Search for lib dir in path, find the trailing slash. */
|
||||
lib = strstr(path, *lp);
|
||||
if (lib == NULL)
|
||||
continue;
|
||||
slash = lib + strlen(*lp) - 1;
|
||||
|
||||
/* Make sure there isn't already a machine-linux-gnu dir. */
|
||||
len = strcspn(slash + 1, "/-");
|
||||
if (strncmp(slash + 1 + len, "-linux-gnu/", 11) == 0) {
|
||||
/* Multiarch already present. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add machine-linux-gnu dir after /lib/ or /libexec/. */
|
||||
len = asprintf(&newpath, "%.*s%s%s-linux-gnu%s",
|
||||
(int)(lib - path), path, newlib, unamebuf.machine, slash);
|
||||
if (len == -1) {
|
||||
newpath = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If sb was set, use stat(2) to make sure newpath exists. */
|
||||
if (sb == NULL || stat(newpath, sb) == 0)
|
||||
break;
|
||||
free(newpath);
|
||||
newpath = NULL;
|
||||
}
|
||||
|
||||
return newpath;
|
||||
}
|
||||
#else
|
||||
char *
|
||||
sudo_stat_multiarch_v1(const char *path, struct stat *sb)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __linux__ */
|
@ -23,6 +23,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_FNMATCH
|
||||
# include <fnmatch.h>
|
||||
#else
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include "sudo_plugin.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
|
||||
static int
|
||||
fuzz_conversation(int num_msgs, const struct sudo_conv_message msgs[],
|
||||
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_fatal.h"
|
||||
|
@ -15,6 +15,7 @@
|
||||
# include "compat/glob.h"
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_util.h"
|
||||
@ -183,7 +184,8 @@ main(int argc, char **argv)
|
||||
return errors;
|
||||
}
|
||||
|
||||
int test_glob(struct gl_entry *entry)
|
||||
static int
|
||||
test_glob(struct gl_entry *entry)
|
||||
{
|
||||
glob_t gl;
|
||||
char **ap;
|
||||
|
@ -50,7 +50,7 @@ sudo_dso_public int main(int argc, char *argv[]);
|
||||
* reasonable expansion of the template and matches the fd. Returns true
|
||||
* if all the X's were replaced with non-X's
|
||||
*/
|
||||
int
|
||||
static int
|
||||
check(int fd, char const *kind, char const *path, char const *prefix,
|
||||
size_t plen, char const *suffix, size_t slen, int tlen)
|
||||
{
|
||||
@ -86,7 +86,7 @@ check(int fd, char const *kind, char const *path, char const *prefix,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
try_mkdtemp(char *p, char const *prefix, int len)
|
||||
{
|
||||
size_t plen = strlen(prefix);
|
||||
@ -105,7 +105,7 @@ try_mkdtemp(char *p, char const *prefix, int len)
|
||||
sudo_fatalx("mkdtemp: exceeded MAX_TRIES");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
try_mkstemps(char *p, char const *prefix, int len, char const *suffix)
|
||||
{
|
||||
size_t plen = strlen(prefix);
|
||||
|
178
lib/util/regress/multiarch/multiarch_test.c
Normal file
178
lib/util/regress/multiarch/multiarch_test.c
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SUDO_ERROR_WRAP 0
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_fatal.h"
|
||||
#include "sudo_util.h"
|
||||
|
||||
sudo_dso_public int main(int argc, char *argv[]);
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/utsname.h>
|
||||
|
||||
# if defined(__ILP32__)
|
||||
# define ARCH_LIB "libx32"
|
||||
# elif defined(__LP64__)
|
||||
# define ARCH_LIB "lib64"
|
||||
# else
|
||||
# define ARCH_LIB "lib32"
|
||||
# endif
|
||||
|
||||
struct multiarch_test {
|
||||
const char *inpath;
|
||||
char *outpath;
|
||||
};
|
||||
|
||||
static struct multiarch_test *
|
||||
make_test_data(void)
|
||||
{
|
||||
struct multiarch_test *test_data;
|
||||
struct utsname unamebuf;
|
||||
int i;
|
||||
|
||||
if (uname(&unamebuf) == -1)
|
||||
return NULL;
|
||||
|
||||
test_data = calloc(7, sizeof(*test_data));
|
||||
if (test_data == NULL)
|
||||
return NULL;
|
||||
|
||||
test_data[0].inpath = "/usr/" ARCH_LIB "/libfoo.so";
|
||||
i = asprintf(&test_data[0].outpath, "/usr/lib/%s-linux-gnu/libfoo.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[0].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[1].inpath = "/usr/lib/something.so";
|
||||
i = asprintf(&test_data[1].outpath, "/usr/lib/%s-linux-gnu/something.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[1].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[2].inpath = "/usr/libexec/libbar.so";
|
||||
i = asprintf(&test_data[2].outpath, "/usr/libexec/%s-linux-gnu/libbar.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[2].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[3].inpath = "/usr/local/lib/sudo/libsudo_util.so";
|
||||
i = asprintf(&test_data[3].outpath, "/usr/local/lib/%s-linux-gnu/sudo/libsudo_util.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[3].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
test_data[4].inpath = "/opt/sudo/lib/sudoers.so";
|
||||
i = asprintf(&test_data[4].outpath, "/opt/sudo/lib/%s-linux-gnu/sudoers.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[4].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
i = asprintf(&test_data[5].outpath, "/usr/lib/%s-linux-gnu/something.so",
|
||||
unamebuf.machine);
|
||||
if (i == -1) {
|
||||
test_data[5].outpath = NULL;
|
||||
goto bad;
|
||||
}
|
||||
test_data[5].inpath = test_data[5].outpath;
|
||||
test_data[5].outpath = NULL;
|
||||
|
||||
return test_data;
|
||||
bad:
|
||||
for (i = 0; test_data[i].outpath != NULL; i++)
|
||||
free(test_data[i].outpath);
|
||||
free(test_data);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch, errors = 0;
|
||||
#ifdef __linux__
|
||||
int ntests = 0;
|
||||
struct multiarch_test *test_data;
|
||||
#endif
|
||||
|
||||
initprogname(argc > 0 ? argv[0] : "multiarch_test");
|
||||
|
||||
while ((ch = getopt(argc, argv, "v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'v':
|
||||
/* ignore */
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [-v]\n", getprogname());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef __linux__
|
||||
test_data = make_test_data();
|
||||
if (test_data == NULL) {
|
||||
sudo_warnx("%s", "failed to generate test data");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (ch = 0; test_data[ch].inpath != NULL; ch++) {
|
||||
char *outpath = sudo_stat_multiarch(test_data[ch].inpath, NULL);
|
||||
ntests++;
|
||||
if (outpath == NULL) {
|
||||
if (test_data[ch].outpath != NULL) {
|
||||
sudo_warnx("%s: sudo_stat_multiarch failed",
|
||||
test_data[ch].inpath);
|
||||
errors++;
|
||||
}
|
||||
} else if (strcmp(outpath, test_data[ch].outpath) != 0) {
|
||||
sudo_warnx("%s: expected %s got %s", test_data[ch].inpath,
|
||||
test_data[ch].outpath, outpath);
|
||||
errors++;
|
||||
free(outpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (ntests != 0) {
|
||||
printf("%s: %d tests run, %d errors, %d%% success rate\n",
|
||||
getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
return errors;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user